xref: /aosp_15_r20/external/deqp/modules/egl/teglImageTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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