1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program EGL Module
3 * ---------------------------------------
4 *
5 * Copyright 2014 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief EGL image tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "teglImageTests.hpp"
25
26 #include "teglImageUtil.hpp"
27 #include "teglAndroidUtil.hpp"
28 #include "teglImageFormatTests.hpp"
29
30 #include "egluNativeDisplay.hpp"
31 #include "egluNativeWindow.hpp"
32 #include "egluNativePixmap.hpp"
33 #include "egluStrUtil.hpp"
34 #include "egluUnique.hpp"
35 #include "egluUtil.hpp"
36 #include "egluGLUtil.hpp"
37
38 #include "eglwLibrary.hpp"
39 #include "eglwEnums.hpp"
40
41 #include "gluDefs.hpp"
42 #include "gluCallLogWrapper.hpp"
43 #include "gluObjectWrapper.hpp"
44 #include "gluStrUtil.hpp"
45
46 #include "glwDefs.hpp"
47 #include "glwEnums.hpp"
48
49 #include "tcuTestLog.hpp"
50 #include "tcuCommandLine.hpp"
51
52 #include "deUniquePtr.hpp"
53
54 #include <algorithm>
55 #include <sstream>
56 #include <string>
57 #include <vector>
58 #include <set>
59
60 using tcu::TestLog;
61
62 using std::ostringstream;
63 using std::set;
64 using std::string;
65 using std::vector;
66
67 using de::MovePtr;
68 using de::UniquePtr;
69 using eglu::AttribMap;
70 using eglu::NativePixmap;
71 using eglu::NativeWindow;
72 using eglu::ScopedCurrentContext;
73 using eglu::UniqueImage;
74 using eglu::UniqueSurface;
75 using glu::ApiType;
76 using glu::ContextType;
77 using glu::Texture;
78
79 using namespace glw;
80 using namespace eglw;
81
82 namespace deqp
83 {
84 namespace egl
85 {
86
87 namespace Image
88 {
89
90 #define CHECK_EXTENSION(DPY, EXTNAME) \
91 TCU_CHECK_AND_THROW(NotSupportedError, eglu::hasExtension(m_eglTestCtx.getLibrary(), DPY, EXTNAME), \
92 (string("Unsupported extension: ") + (EXTNAME)).c_str())
93
94 template <typename RetVal>
checkCallError(EglTestContext & eglTestCtx,const char * call,RetVal returnValue,EGLint expectError)95 RetVal checkCallError(EglTestContext &eglTestCtx, const char *call, RetVal returnValue, EGLint expectError)
96 {
97 tcu::TestContext &testCtx = eglTestCtx.getTestContext();
98 TestLog &log = testCtx.getLog();
99 EGLint error;
100
101 log << TestLog::Message << call << TestLog::EndMessage;
102
103 error = eglTestCtx.getLibrary().getError();
104
105 if (error != expectError)
106 {
107 log << TestLog::Message << " Fail: Error code mismatch! Expected " << eglu::getErrorStr(expectError)
108 << ", got " << eglu::getErrorStr(error) << TestLog::EndMessage;
109 log << TestLog::Message << " " << returnValue << " was returned" << TestLog::EndMessage;
110
111 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
112 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid error code");
113 }
114
115 return returnValue;
116 }
117
118 template <typename RetVal>
checkCallReturn(EglTestContext & eglTestCtx,const char * call,RetVal returnValue,RetVal expectReturnValue,EGLint expectError)119 void checkCallReturn(EglTestContext &eglTestCtx, const char *call, RetVal returnValue, RetVal expectReturnValue,
120 EGLint expectError)
121 {
122 tcu::TestContext &testCtx = eglTestCtx.getTestContext();
123 TestLog &log = testCtx.getLog();
124 EGLint error;
125
126 log << TestLog::Message << call << TestLog::EndMessage;
127
128 error = eglTestCtx.getLibrary().getError();
129
130 if (returnValue != expectReturnValue)
131 {
132 log << TestLog::Message << " Fail: Return value mismatch! Expected " << expectReturnValue << ", got "
133 << returnValue << TestLog::EndMessage;
134
135 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
136 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid return value");
137 }
138
139 if (error != expectError)
140 {
141 log << TestLog::Message << " Fail: Error code mismatch! Expected " << eglu::getErrorStr(expectError)
142 << ", got " << eglu::getErrorStr(error) << TestLog::EndMessage;
143
144 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
145 testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid error code");
146 }
147 }
148
149 // \note These macros expect "EglTestContext m_eglTestCtx" to be defined.
150 #define CHECK_EXT_CALL_RET(CALL, EXPECT_RETURN_VALUE, EXPECT_ERROR) \
151 checkCallReturn(m_eglTestCtx, #CALL, CALL, (EXPECT_RETURN_VALUE), (EXPECT_ERROR))
152 #define CHECK_EXT_CALL_ERR(CALL, EXPECT_ERROR) checkCallError(m_eglTestCtx, #CALL, CALL, (EXPECT_ERROR))
153
154 class ImageTestCase : public TestCase, public glu::CallLogWrapper
155 {
156 public:
ImageTestCase(EglTestContext & eglTestCtx,ApiType api,const string & name,const string & desc)157 ImageTestCase(EglTestContext &eglTestCtx, ApiType api, const string &name, const string &desc)
158 : TestCase(eglTestCtx, name.c_str(), desc.c_str())
159 , glu::CallLogWrapper(m_gl, m_testCtx.getLog())
160 , m_api(api)
161 , m_display(EGL_NO_DISPLAY)
162 {
163 }
164
init(void)165 void init(void)
166 {
167 DE_ASSERT(m_display == EGL_NO_DISPLAY);
168 m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
169
170 const char *extensions[] = {"GL_OES_EGL_image"};
171 m_eglTestCtx.initGLFunctions(&m_gl, m_api, DE_LENGTH_OF_ARRAY(extensions), &extensions[0]);
172 }
173
deinit(void)174 void deinit(void)
175 {
176 m_eglTestCtx.getLibrary().terminate(m_display);
177 m_display = EGL_NO_DISPLAY;
178 }
179
isGLRedSupported(void)180 bool isGLRedSupported(void)
181 {
182 return m_api.getMajorVersion() >= 3 || glu::hasExtension(m_gl, m_api, "GL_EXT_texture_rg");
183 }
184
185 protected:
186 glw::Functions m_gl;
187 ApiType m_api;
188 EGLDisplay m_display;
189 };
190
191 class InvalidCreateImage : public ImageTestCase
192 {
193 public:
194 typedef EGLImage (Library::*createImage)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLAttrib *) const;
195 typedef EGLImageKHR (Library::*createImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer,
196 const EGLint *) const;
197
InvalidCreateImage(EglTestContext & eglTestCtx)198 InvalidCreateImage(EglTestContext &eglTestCtx)
199 : ImageTestCase(eglTestCtx, ApiType::es(2, 0), "invalid_create_image",
200 "eglCreateImageKHR() with invalid arguments")
201 {
202 }
203
204 template <typename createImageFuncType, typename imageType>
205 void checkCreate(createImageFuncType createImageFunc, string createImageName, const char *msg, EGLDisplay dpy,
206 const char *dpyStr, EGLContext context, const char *ctxStr, EGLenum source, const char *srcStr,
207 EGLint expectError, imageType noImageVal);
208
iterate(void)209 IterateResult iterate(void)
210 {
211 const Library &egl = m_eglTestCtx.getLibrary();
212
213 if (eglu::getVersion(egl, m_display) < eglu::Version(1, 5) &&
214 !eglu::hasExtension(egl, m_display, "EGL_KHR_image") &&
215 !eglu::hasExtension(egl, m_display, "EGL_KHR_image_base"))
216 {
217 TCU_THROW(NotSupportedError, "EGLimages not supported");
218 }
219
220 if (eglu::getVersion(egl, m_display) >= eglu::Version(1, 5))
221 {
222 #define CHECK_CREATE(MSG, DPY, CONTEXT, SOURCE, ERR) \
223 checkCreate<createImage, EGLImage>(&Library::createImage, "eglCreateImage", MSG, DPY, #DPY, CONTEXT, #CONTEXT, \
224 SOURCE, #SOURCE, ERR, EGL_NO_IMAGE)
225 CHECK_CREATE("Testing bad display (-1)...", (EGLDisplay)-1, EGL_NO_CONTEXT, EGL_NONE, EGL_BAD_DISPLAY);
226 CHECK_CREATE("Testing bad context (-1)...", m_display, (EGLContext)-1, EGL_NONE, EGL_BAD_CONTEXT);
227 CHECK_CREATE("Testing bad source (-1)...", m_display, EGL_NO_CONTEXT, (EGLenum)-1, EGL_BAD_PARAMETER);
228 #undef CHECK_CREATE
229 }
230
231 if (eglu::hasExtension(egl, m_display, "EGL_KHR_image") &&
232 eglu::hasExtension(egl, m_display, "EGL_KHR_image_base"))
233 {
234 #define CHECK_CREATE_KHR(MSG, DPY, CONTEXT, SOURCE, ERR) \
235 checkCreate<createImageKHR, EGLImageKHR>(&Library::createImageKHR, "eglCreateImageKHR", MSG, DPY, #DPY, CONTEXT, \
236 #CONTEXT, SOURCE, #SOURCE, ERR, EGL_NO_IMAGE_KHR)
237 CHECK_CREATE_KHR("Testing bad display (-1)...", (EGLDisplay)-1, EGL_NO_CONTEXT, EGL_NONE, EGL_BAD_DISPLAY);
238 CHECK_CREATE_KHR("Testing bad context (-1)...", m_display, (EGLContext)-1, EGL_NONE, EGL_BAD_CONTEXT);
239 CHECK_CREATE_KHR("Testing bad source (-1)...", m_display, EGL_NO_CONTEXT, (EGLenum)-1, EGL_BAD_PARAMETER);
240 #undef CHECK_CREATE_KHR
241 }
242
243 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
244 return STOP;
245 }
246 };
247
248 template <typename createImageFuncType, typename imageType>
checkCreate(createImageFuncType createImageFunc,string createImageName,const char * msg,EGLDisplay dpy,const char * dpyStr,EGLContext context,const char * ctxStr,EGLenum source,const char * srcStr,EGLint expectError,imageType noImageVal)249 void InvalidCreateImage::checkCreate(createImageFuncType createImageFunc, string createImageName, const char *msg,
250 EGLDisplay dpy, const char *dpyStr, EGLContext context, const char *ctxStr,
251 EGLenum source, const char *srcStr, EGLint expectError, imageType noImageVal)
252 {
253 m_testCtx.getLog() << TestLog::Message << msg << TestLog::EndMessage;
254 {
255 const Library &egl = m_eglTestCtx.getLibrary();
256 const imageType image = (egl.*createImageFunc)(dpy, context, source, 0, DE_NULL);
257 ostringstream call;
258
259 call << createImageName << "(" << dpyStr << ", " << ctxStr << ", " << srcStr << ", 0, DE_NULL)";
260 checkCallReturn(m_eglTestCtx, call.str().c_str(), image, noImageVal, expectError);
261 }
262 }
263
chooseConfig(const Library & egl,EGLDisplay display,ApiType apiType)264 EGLConfig chooseConfig(const Library &egl, EGLDisplay display, ApiType apiType)
265 {
266 AttribMap attribs;
267 vector<EGLConfig> configs;
268 // Prefer configs in order: pbuffer, window, pixmap
269 static const EGLenum s_surfaceTypes[] = {EGL_PBUFFER_BIT, EGL_WINDOW_BIT, EGL_PIXMAP_BIT};
270
271 attribs[EGL_RENDERABLE_TYPE] = eglu::apiRenderableType(apiType);
272
273 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_surfaceTypes); ++ndx)
274 {
275 attribs[EGL_SURFACE_TYPE] = s_surfaceTypes[ndx];
276 configs = eglu::chooseConfigs(egl, display, attribs);
277
278 if (!configs.empty())
279 return configs.front();
280 }
281
282 TCU_THROW(NotSupportedError, "No compatible EGL configs found");
283 return (EGLConfig)0;
284 }
285
286 class Context
287 {
288 public:
Context(EglTestContext & eglTestCtx,EGLDisplay display,ContextType ctxType,int width,int height)289 Context(EglTestContext &eglTestCtx, EGLDisplay display, ContextType ctxType, int width, int height)
290 : m_eglTestCtx(eglTestCtx)
291 , m_display(display)
292 , m_config(chooseConfig(eglTestCtx.getLibrary(), display, ctxType.getAPI()))
293 , m_context(m_eglTestCtx.getLibrary(), m_display,
294 eglu::createGLContext(eglTestCtx.getLibrary(), m_display, m_config, ctxType))
295 , m_surface(createSurface(eglTestCtx, m_display, m_config, width, height))
296 , m_current(eglTestCtx.getLibrary(), m_display, m_surface->get(), m_surface->get(), *m_context)
297 {
298 m_eglTestCtx.initGLFunctions(&m_gl, ctxType.getAPI());
299 }
300
getConfig(void) const301 EGLConfig getConfig(void) const
302 {
303 return m_config;
304 }
getEglDisplay(void) const305 EGLDisplay getEglDisplay(void) const
306 {
307 return m_display;
308 }
getEglContext(void) const309 EGLContext getEglContext(void) const
310 {
311 return *m_context;
312 }
gl(void) const313 const glw::Functions &gl(void) const
314 {
315 return m_gl;
316 }
317
318 private:
319 EglTestContext &m_eglTestCtx;
320 EGLDisplay m_display;
321 EGLConfig m_config;
322 eglu::UniqueContext m_context;
323 UniquePtr<ManagedSurface> m_surface;
324 ScopedCurrentContext m_current;
325 glw::Functions m_gl;
326
327 Context(const Context &);
328 Context &operator=(const Context &);
329 };
330
331 class CreateImageGLES2 : public ImageTestCase
332 {
333 public:
getTargetName(EGLint target)334 static const char *getTargetName(EGLint target)
335 {
336 switch (target)
337 {
338 case EGL_GL_TEXTURE_2D_KHR:
339 return "tex2d";
340 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
341 return "cubemap_pos_x";
342 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
343 return "cubemap_neg_x";
344 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
345 return "cubemap_pos_y";
346 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
347 return "cubemap_neg_y";
348 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
349 return "cubemap_pos_z";
350 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
351 return "cubemap_neg_z";
352 case EGL_GL_RENDERBUFFER_KHR:
353 return "renderbuffer";
354 case EGL_NATIVE_BUFFER_ANDROID:
355 return "android_native";
356 default:
357 DE_ASSERT(false);
358 return "";
359 }
360 }
361
getStorageName(GLenum storage)362 static const char *getStorageName(GLenum storage)
363 {
364 switch (storage)
365 {
366 case GL_RED:
367 return "red";
368 case GL_RG:
369 return "rg";
370 case GL_LUMINANCE:
371 return "luminance";
372 case GL_LUMINANCE_ALPHA:
373 return "luminance_alpha";
374 case GL_RGB:
375 return "rgb";
376 case GL_RGBA:
377 return "rgba";
378 case GL_RGBA16F:
379 return "rgba16f";
380 case GL_DEPTH_COMPONENT16:
381 return "depth_component_16";
382 case GL_DEPTH_COMPONENT24:
383 return "depth_component_24";
384 case GL_DEPTH_COMPONENT32F:
385 return "depth_component_32f";
386 case GL_DEPTH24_STENCIL8:
387 return "depth24_stencil8";
388 case GL_DEPTH32F_STENCIL8:
389 return "depth32f_stencil8";
390 case GL_RGB10_A2:
391 return "rgb10_a2";
392 case GL_RGBA4:
393 return "rgba4";
394 case GL_RGB5_A1:
395 return "rgb5_a1";
396 case GL_RGB565:
397 return "rgb565";
398 case GL_RGB8:
399 return "rgb8";
400 case GL_RGBA8:
401 return "rgba8";
402 case GL_STENCIL_INDEX8:
403 return "stencil_index8";
404 default:
405 DE_ASSERT(false);
406 return "";
407 }
408 }
409
getImageSource(EGLint target,GLenum internalFormat,GLenum format,GLenum type,bool useTexLevel0)410 MovePtr<ImageSource> getImageSource(EGLint target, GLenum internalFormat, GLenum format, GLenum type,
411 bool useTexLevel0)
412 {
413 switch (target)
414 {
415 case EGL_GL_TEXTURE_2D_KHR:
416 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
417 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
418 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
419 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
420 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
421 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
422 DE_ASSERT(format != 0u && type != 0u);
423 return createTextureImageSource(target, internalFormat, format, type, useTexLevel0);
424
425 case EGL_GL_RENDERBUFFER_KHR:
426 DE_ASSERT(format == 0u && type == 0u);
427 return createRenderbufferImageSource(internalFormat);
428
429 case EGL_NATIVE_BUFFER_ANDROID:
430 DE_ASSERT(format == 0u && type == 0u);
431 return createAndroidNativeImageSource(internalFormat, 1u, false);
432
433 default:
434 DE_FATAL("Impossible");
435 return MovePtr<ImageSource>();
436 }
437 }
438
CreateImageGLES2(EglTestContext & eglTestCtx,EGLint target,GLenum internalFormat,GLenum format,GLenum type,bool useTexLevel0=false)439 CreateImageGLES2(EglTestContext &eglTestCtx, EGLint target, GLenum internalFormat, GLenum format, GLenum type,
440 bool useTexLevel0 = false)
441 : ImageTestCase(eglTestCtx, ApiType::es(2, 0),
442 string("create_image_gles2_") + getTargetName(target) + "_" + getStorageName(internalFormat) +
443 (useTexLevel0 ? "_level0_only" : ""),
444 "Create EGLImage from GLES2 object")
445 , m_source(getImageSource(target, internalFormat, format, type, useTexLevel0))
446 , m_internalFormat(internalFormat)
447 {
448 }
449
iterate(void)450 IterateResult iterate(void)
451 {
452 const Library &egl = m_eglTestCtx.getLibrary();
453 const EGLDisplay dpy = m_display;
454
455 if (eglu::getVersion(egl, dpy) < eglu::Version(1, 5))
456 CHECK_EXTENSION(dpy, m_source->getRequiredExtension());
457
458 // Initialize result.
459 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
460
461 // Create GLES2 context
462 TestLog &log = m_testCtx.getLog();
463 const ContextType contextType(ApiType::es(2, 0));
464 Context context(m_eglTestCtx, dpy, contextType, 64, 64);
465 const EGLContext eglContext = context.getEglContext();
466
467 if ((m_internalFormat == GL_RED || m_internalFormat == GL_RG) && !isGLRedSupported())
468 TCU_THROW(NotSupportedError, "Unsupported extension: GL_EXT_texture_rg");
469
470 log << TestLog::Message << "Using EGL config " << eglu::getConfigID(egl, dpy, context.getConfig())
471 << TestLog::EndMessage;
472
473 UniquePtr<ClientBuffer> clientBuffer(m_source->createBuffer(egl, context.gl()));
474 const EGLImageKHR image = m_source->createImage(egl, dpy, eglContext, clientBuffer->get());
475
476 if (image == EGL_NO_IMAGE_KHR)
477 {
478 log << TestLog::Message << " Fail: Got EGL_NO_IMAGE_KHR!" << TestLog::EndMessage;
479
480 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
481 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got EGL_NO_IMAGE_KHR");
482 }
483
484 // Destroy image
485 CHECK_EXT_CALL_RET(egl.destroyImageKHR(context.getEglDisplay(), image), (EGLBoolean)EGL_TRUE, EGL_SUCCESS);
486
487 return STOP;
488 }
489
490 private:
491 const UniquePtr<ImageSource> m_source;
492 const GLenum m_internalFormat;
493 };
494
495 class ImageTargetGLES2 : public ImageTestCase
496 {
497 public:
getTargetName(GLenum target)498 static const char *getTargetName(GLenum target)
499 {
500 switch (target)
501 {
502 case GL_TEXTURE_2D:
503 return "tex2d";
504 case GL_RENDERBUFFER:
505 return "renderbuffer";
506 default:
507 DE_ASSERT(false);
508 return "";
509 }
510 }
511
ImageTargetGLES2(EglTestContext & eglTestCtx,GLenum target)512 ImageTargetGLES2(EglTestContext &eglTestCtx, GLenum target)
513 : ImageTestCase(eglTestCtx, ApiType::es(2, 0), string("image_target_gles2_") + getTargetName(target),
514 "Use EGLImage as GLES2 object")
515 , m_target(target)
516 {
517 }
518
iterate(void)519 IterateResult iterate(void)
520 {
521 const Library &egl = m_eglTestCtx.getLibrary();
522 TestLog &log = m_testCtx.getLog();
523
524 // \todo [2011-07-21 pyry] Try all possible EGLImage sources
525 CHECK_EXTENSION(m_display, "EGL_KHR_gl_texture_2D_image");
526
527 // Initialize result.
528 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
529
530 // Create GLES2 context
531
532 Context context(m_eglTestCtx, m_display, ContextType(ApiType::es(2, 0)), 64, 64);
533 log << TestLog::Message << "Using EGL config "
534 << eglu::getConfigID(m_eglTestCtx.getLibrary(), context.getEglDisplay(), context.getConfig())
535 << TestLog::EndMessage;
536
537 // Check for OES_EGL_image
538 {
539 const char *glExt = (const char *)glGetString(GL_EXTENSIONS);
540
541 if (string(glExt).find("GL_OES_EGL_image") == string::npos)
542 throw tcu::NotSupportedError("Extension not supported", "GL_OES_EGL_image", __FILE__, __LINE__);
543
544 TCU_CHECK(m_gl.eglImageTargetTexture2DOES);
545 TCU_CHECK(m_gl.eglImageTargetRenderbufferStorageOES);
546 }
547
548 // Create GL_TEXTURE_2D and EGLImage from it.
549 log << TestLog::Message << "Creating EGLImage using GL_TEXTURE_2D with GL_RGBA storage" << TestLog::EndMessage;
550
551 uint32_t srcTex = 1;
552 GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, srcTex));
553 GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL));
554 GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
555
556 // Create EGL image
557 EGLint attribs[] = {EGL_GL_TEXTURE_LEVEL_KHR, 0, EGL_NONE};
558 EGLImageKHR image =
559 CHECK_EXT_CALL_ERR(egl.createImageKHR(context.getEglDisplay(), context.getEglContext(),
560 EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)(uintptr_t)srcTex, attribs),
561 EGL_SUCCESS);
562 if (image == EGL_NO_IMAGE_KHR)
563 {
564 log << TestLog::Message << " Fail: Got EGL_NO_IMAGE_KHR!" << TestLog::EndMessage;
565
566 if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
567 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got EGL_NO_IMAGE_KHR");
568 }
569
570 // Create texture or renderbuffer
571 if (m_target == GL_TEXTURE_2D)
572 {
573 log << TestLog::Message << "Creating GL_TEXTURE_2D from EGLimage" << TestLog::EndMessage;
574
575 uint32_t dstTex = 2;
576 GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, dstTex));
577 GLU_CHECK_CALL(glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image));
578 GLU_CHECK_CALL(glDeleteTextures(1, &dstTex));
579 }
580 else
581 {
582 DE_ASSERT(m_target == GL_RENDERBUFFER);
583
584 log << TestLog::Message << "Creating GL_RENDERBUFFER from EGLimage" << TestLog::EndMessage;
585
586 uint32_t dstRbo = 2;
587 GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, dstRbo));
588 GLU_CHECK_CALL(glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)image));
589 GLU_CHECK_CALL(glDeleteRenderbuffers(1, &dstRbo));
590 }
591
592 // Destroy image
593 CHECK_EXT_CALL_RET(egl.destroyImageKHR(context.getEglDisplay(), image), (EGLBoolean)EGL_TRUE, EGL_SUCCESS);
594
595 // Destroy source texture object
596 GLU_CHECK_CALL(glDeleteTextures(1, &srcTex));
597
598 return STOP;
599 }
600
601 private:
602 GLenum m_target;
603 };
604
605 class ApiTests : public TestCaseGroup
606 {
607 public:
ApiTests(EglTestContext & eglTestCtx,const string & name,const string & desc)608 ApiTests(EglTestContext &eglTestCtx, const string &name, const string &desc)
609 : TestCaseGroup(eglTestCtx, name.c_str(), desc.c_str())
610 {
611 }
612
init(void)613 void init(void)
614 {
615 addChild(new Image::InvalidCreateImage(m_eglTestCtx));
616
617 addChild(
618 new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_2D_KHR, GL_RED, GL_RED, GL_UNSIGNED_BYTE, false));
619 addChild(
620 new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_2D_KHR, GL_RG, GL_RG, GL_UNSIGNED_BYTE, false));
621
622 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_2D_KHR, GL_LUMINANCE, GL_LUMINANCE,
623 GL_UNSIGNED_BYTE));
624 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_2D_KHR, GL_LUMINANCE_ALPHA,
625 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE));
626
627 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_2D_KHR, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE));
628 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE));
629 addChild(
630 new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, true));
631
632 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR, GL_RGB, GL_RGB,
633 GL_UNSIGNED_BYTE));
634 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR, GL_RGBA, GL_RGBA,
635 GL_UNSIGNED_BYTE));
636 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR, GL_RGBA, GL_RGBA,
637 GL_UNSIGNED_BYTE, true));
638
639 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR, GL_RGBA, GL_RGBA,
640 GL_UNSIGNED_BYTE));
641 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR, GL_RGBA, GL_RGBA,
642 GL_UNSIGNED_BYTE));
643 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR, GL_RGBA, GL_RGBA,
644 GL_UNSIGNED_BYTE));
645 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR, GL_RGBA, GL_RGBA,
646 GL_UNSIGNED_BYTE));
647 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR, GL_RGBA, GL_RGBA,
648 GL_UNSIGNED_BYTE));
649
650 static const GLenum rboStorages[] = {GL_DEPTH_COMPONENT16, GL_RGBA4, GL_RGB5_A1, GL_RGB565, GL_STENCIL_INDEX8};
651 for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(rboStorages); storageNdx++)
652 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_RENDERBUFFER_KHR, rboStorages[storageNdx],
653 (GLenum)0, (GLenum)0));
654
655 static const GLenum androidFormats[] = {GL_RGB565,
656 GL_RGB8,
657 GL_RGBA8,
658 GL_RGBA4,
659 GL_RGB5_A1,
660 GL_DEPTH_COMPONENT16,
661 GL_DEPTH_COMPONENT24,
662 GL_DEPTH24_STENCIL8,
663 GL_DEPTH_COMPONENT32F,
664 GL_DEPTH32F_STENCIL8,
665 GL_RGB10_A2,
666 GL_RGBA16F,
667 GL_STENCIL_INDEX8};
668
669 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(androidFormats); ++formatNdx)
670 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_NATIVE_BUFFER_ANDROID, androidFormats[formatNdx],
671 (GLenum)0, (GLenum)0));
672
673 addChild(new Image::ImageTargetGLES2(m_eglTestCtx, GL_TEXTURE_2D));
674 addChild(new Image::ImageTargetGLES2(m_eglTestCtx, GL_RENDERBUFFER));
675 }
676 };
677
678 } // namespace Image
679
ImageTests(EglTestContext & eglTestCtx)680 ImageTests::ImageTests(EglTestContext &eglTestCtx) : TestCaseGroup(eglTestCtx, "image", "EGLImage Tests")
681 {
682 }
683
~ImageTests(void)684 ImageTests::~ImageTests(void)
685 {
686 }
687
init(void)688 void ImageTests::init(void)
689 {
690 addChild(new Image::ApiTests(m_eglTestCtx, "api", "EGLImage API tests"));
691 addChild(Image::createSimpleCreationTests(m_eglTestCtx, "create", "EGLImage creation tests"));
692 addChild(Image::createModifyTests(m_eglTestCtx, "modify", "EGLImage modifying tests"));
693 addChild(Image::createMultiContextRenderTests(m_eglTestCtx, "render_multiple_contexts",
694 "EGLImage render tests on multiple contexts"));
695 }
696
697 } // namespace egl
698 } // namespace deqp
699