Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglImageTests.cpp
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::string;
63 using std::vector;
64 using std::set;
65 using std::ostringstream;
66
67 using de::MovePtr;
68 using de::UniquePtr;
69 using glu::ApiType;
70 using glu::ContextType;
71 using glu::Texture;
72 using eglu::AttribMap;
73 using eglu::NativeWindow;
74 using eglu::NativePixmap;
75 using eglu::UniqueImage;
76 using eglu::UniqueSurface;
77 using eglu::ScopedCurrentContext;
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), (string("Unsupported extension: ") + (EXTNAME)).c_str())
92
93 template <typename RetVal>
94 RetVal checkCallError (EglTestContext& eglTestCtx, const char* call, RetVal returnValue, EGLint expectError)
95 {
96         tcu::TestContext&       testCtx         = eglTestCtx.getTestContext();
97         TestLog&                        log                     = testCtx.getLog();
98         EGLint                          error;
99
100         log << TestLog::Message << call << TestLog::EndMessage;
101
102         error = eglTestCtx.getLibrary().getError();
103
104         if (error != expectError)
105         {
106                 log << TestLog::Message << "  Fail: Error code mismatch! Expected " << eglu::getErrorStr(expectError) << ", got " << eglu::getErrorStr(error) << TestLog::EndMessage;
107                 log << TestLog::Message << "  " << returnValue << " was returned" << TestLog::EndMessage;
108
109                 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
110                         testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid error code");
111         }
112
113         return returnValue;
114 }
115
116 template <typename RetVal>
117 void checkCallReturn (EglTestContext& eglTestCtx, const char* call, RetVal returnValue, RetVal expectReturnValue, EGLint expectError)
118 {
119         tcu::TestContext&       testCtx         = eglTestCtx.getTestContext();
120         TestLog&                        log                     = testCtx.getLog();
121         EGLint                          error;
122
123         log << TestLog::Message << call << TestLog::EndMessage;
124
125         error = eglTestCtx.getLibrary().getError();
126
127         if (returnValue != expectReturnValue)
128         {
129                 log << TestLog::Message << "  Fail: Return value mismatch! Expected " << expectReturnValue << ", got " << returnValue << TestLog::EndMessage;
130
131                 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
132                         testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid return value");
133         }
134
135         if (error != expectError)
136         {
137                 log << TestLog::Message << "  Fail: Error code mismatch! Expected " << eglu::getErrorStr(expectError) << ", got " << eglu::getErrorStr(error) << TestLog::EndMessage;
138
139                 if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
140                         testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid error code");
141         }
142 }
143
144 // \note These macros expect "EglTestContext m_eglTestCtx" to be defined.
145 #define CHECK_EXT_CALL_RET(CALL, EXPECT_RETURN_VALUE, EXPECT_ERROR)     checkCallReturn(m_eglTestCtx, #CALL, CALL, (EXPECT_RETURN_VALUE), (EXPECT_ERROR))
146 #define CHECK_EXT_CALL_ERR(CALL, EXPECT_ERROR)                                          checkCallError(m_eglTestCtx, #CALL, CALL, (EXPECT_ERROR))
147
148 class ImageTestCase : public TestCase, public glu::CallLogWrapper
149 {
150 public:
151                                 ImageTestCase           (EglTestContext& eglTestCtx, ApiType api, const string& name, const string& desc)
152                                         : TestCase                              (eglTestCtx, name.c_str(), desc.c_str())
153                                         , glu::CallLogWrapper   (m_gl, m_testCtx.getLog())
154                                         , m_api                                 (api)
155                                         , m_display                             (EGL_NO_DISPLAY)
156         {
157         }
158
159         void            init                            (void)
160         {
161                 DE_ASSERT(m_display == EGL_NO_DISPLAY);
162                 m_display = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
163
164                 const char* extensions[] = { "GL_OES_EGL_image" };
165                 m_eglTestCtx.initGLFunctions(&m_gl, m_api, DE_LENGTH_OF_ARRAY(extensions), &extensions[0]);
166         }
167
168         void            deinit                          (void)
169         {
170                 m_eglTestCtx.getLibrary().terminate(m_display);
171                 m_display = EGL_NO_DISPLAY;
172         }
173
174         bool            isGLRedSupported        (void)
175         {
176                 return m_api.getMajorVersion() >= 3 || glu::hasExtension(m_gl, m_api, "GL_EXT_texture_rg");
177         }
178
179 protected:
180         glw::Functions  m_gl;
181         ApiType                 m_api;
182         EGLDisplay              m_display;
183 };
184
185 class InvalidCreateImage : public ImageTestCase
186 {
187 public:
188         typedef EGLImage    (Library::*createImage)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLAttrib *) const ;
189         typedef EGLImageKHR (Library::*createImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint *) const ;
190
191         InvalidCreateImage (EglTestContext& eglTestCtx)
192                 : ImageTestCase(eglTestCtx, ApiType::es(2, 0), "invalid_create_image", "eglCreateImageKHR() with invalid arguments")
193         {
194         }
195
196         template <typename createImageFuncType, typename imageType>
197         void checkCreate        (createImageFuncType createImageFunc,
198                                                  string createImageName,
199                                                  const char* msg,
200                                                  EGLDisplay dpy,
201                                                  const char* dpyStr,
202                                                  EGLContext context,
203                                                  const char* ctxStr,
204                                                  EGLenum source,
205                                                  const char* srcStr,
206                                                  EGLint expectError,
207                                                  imageType noImageVal);
208
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, SOURCE, #SOURCE, ERR, EGL_NO_IMAGE)
224                 CHECK_CREATE("Testing bad display (-1)...", (EGLDisplay)-1, EGL_NO_CONTEXT, EGL_NONE, EGL_BAD_DISPLAY);
225                 CHECK_CREATE("Testing bad context (-1)...", m_display, (EGLContext)-1, EGL_NONE, EGL_BAD_CONTEXT);
226                 CHECK_CREATE("Testing bad source (-1)...", m_display, EGL_NO_CONTEXT, (EGLenum)-1, EGL_BAD_PARAMETER);
227 #undef CHECK_CREATE
228                 }
229
230                 if (eglu::hasExtension(egl, m_display, "EGL_KHR_image") &&
231                         eglu::hasExtension(egl, m_display, "EGL_KHR_image_base"))
232                 {
233 #define CHECK_CREATE_KHR(MSG, DPY, CONTEXT, SOURCE, ERR) \
234                         checkCreate<createImageKHR, EGLImageKHR>(&Library::createImageKHR, "eglCreateImageKHR", MSG, DPY, #DPY, CONTEXT, #CONTEXT, SOURCE, #SOURCE, ERR, EGL_NO_IMAGE_KHR)
235                 CHECK_CREATE_KHR("Testing bad display (-1)...", (EGLDisplay)-1, EGL_NO_CONTEXT, EGL_NONE, EGL_BAD_DISPLAY);
236                 CHECK_CREATE_KHR("Testing bad context (-1)...", m_display, (EGLContext)-1, EGL_NONE, EGL_BAD_CONTEXT);
237                 CHECK_CREATE_KHR("Testing bad source (-1)...", m_display, EGL_NO_CONTEXT, (EGLenum)-1, EGL_BAD_PARAMETER);
238 #undef CHECK_CREATE_KHR
239                 }
240
241                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
242                 return STOP;
243         }
244
245 };
246
247 template <typename createImageFuncType, typename imageType>
248 void InvalidCreateImage::checkCreate (createImageFuncType createImageFunc,
249                                                                           string createImageName,
250                                                                           const char* msg,
251                                                                           EGLDisplay dpy,
252                                                                           const char* dpyStr,
253                                                                           EGLContext context,
254                                                                           const char* ctxStr,
255                                                                           EGLenum source,
256                                                                           const char* srcStr,
257                                                                           EGLint expectError,
258                                                                           imageType noImageVal)
259 {
260         m_testCtx.getLog() << TestLog::Message << msg << TestLog::EndMessage;
261         {
262                 const Library&          egl             = m_eglTestCtx.getLibrary();
263                 const imageType     image       = (egl.*createImageFunc)(dpy, context, source, 0, DE_NULL);
264                 ostringstream           call;
265
266                 call << createImageName << "(" << dpyStr << ", " << ctxStr << ", " << srcStr << ", 0, DE_NULL)";
267                 checkCallReturn(m_eglTestCtx, call.str().c_str(), image, noImageVal, expectError);
268         }
269 }
270
271 EGLConfig chooseConfig (const Library& egl, EGLDisplay display, ApiType apiType)
272 {
273         AttribMap                               attribs;
274         vector<EGLConfig>               configs;
275         // Prefer configs in order: pbuffer, window, pixmap
276         static const EGLenum    s_surfaceTypes[] = { EGL_PBUFFER_BIT, EGL_WINDOW_BIT, EGL_PIXMAP_BIT };
277
278         attribs[EGL_RENDERABLE_TYPE] = eglu::apiRenderableType(apiType);
279
280         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_surfaceTypes); ++ndx)
281         {
282                 attribs[EGL_SURFACE_TYPE] = s_surfaceTypes[ndx];
283                 configs = eglu::chooseConfigs(egl, display, attribs);
284
285                 if (!configs.empty())
286                         return configs.front();
287         }
288
289         TCU_THROW(NotSupportedError, "No compatible EGL configs found");
290         return (EGLConfig)0;
291 }
292
293 class Context
294 {
295 public:
296                                                                 Context                 (EglTestContext& eglTestCtx, EGLDisplay display, ContextType ctxType, int width, int height)
297                                                                         : m_eglTestCtx  (eglTestCtx)
298                                                                         , m_display             (display)
299                                                                         , m_config              (chooseConfig(eglTestCtx.getLibrary(), display, ctxType.getAPI()))
300                                                                         , m_context             (m_eglTestCtx.getLibrary(), m_display, eglu::createGLContext(eglTestCtx.getLibrary(), m_display, m_config, ctxType))
301                                                                         , m_surface             (createSurface(eglTestCtx, m_display, m_config, width, height))
302                                                                         , m_current             (eglTestCtx.getLibrary(), m_display, m_surface->get(), m_surface->get(), *m_context)
303         {
304                 m_eglTestCtx.initGLFunctions(&m_gl, ctxType.getAPI());
305         }
306
307         EGLConfig                                       getConfig               (void) const { return m_config; }
308         EGLDisplay                                      getEglDisplay   (void) const { return m_display; }
309         EGLContext                                      getEglContext   (void) const { return *m_context; }
310         const glw::Functions&           gl                              (void) const { return m_gl; }
311
312 private:
313         EglTestContext&                         m_eglTestCtx;
314         EGLDisplay                                      m_display;
315         EGLConfig                                       m_config;
316         eglu::UniqueContext                     m_context;
317         UniquePtr<ManagedSurface>       m_surface;
318         ScopedCurrentContext            m_current;
319         glw::Functions                          m_gl;
320
321                                                                 Context                 (const Context&);
322         Context&                                        operator=               (const Context&);
323 };
324
325 class CreateImageGLES2 : public ImageTestCase
326 {
327 public:
328         static const char* getTargetName (EGLint target)
329         {
330                 switch (target)
331                 {
332                         case EGL_GL_TEXTURE_2D_KHR:                                             return "tex2d";
333                         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:    return "cubemap_pos_x";
334                         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:    return "cubemap_neg_x";
335                         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:    return "cubemap_pos_y";
336                         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:    return "cubemap_neg_y";
337                         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:    return "cubemap_pos_z";
338                         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:    return "cubemap_neg_z";
339                         case EGL_GL_RENDERBUFFER_KHR:                                   return "renderbuffer";
340                         case EGL_NATIVE_BUFFER_ANDROID:                                 return "android_native";
341                         default:                DE_ASSERT(DE_FALSE);                    return "";
342                 }
343         }
344
345         static const char* getStorageName (GLenum storage)
346         {
347                 switch (storage)
348                 {
349                         case GL_RED:                            return "red";
350                         case GL_RG:                                     return "rg";
351                         case GL_LUMINANCE:                      return "luminance";
352                         case GL_LUMINANCE_ALPHA:        return "luminance_alpha";
353                         case GL_RGB:                            return "rgb";
354                         case GL_RGBA:                           return "rgba";
355                         case GL_RGBA16F:                        return "rgba16f";
356                         case GL_DEPTH_COMPONENT16:      return "depth_component_16";
357                         case GL_DEPTH_COMPONENT24:      return "depth_component_24";
358                         case GL_DEPTH_COMPONENT32F:     return "depth_component_32f";
359                         case GL_DEPTH24_STENCIL8:       return "depth24_stencil8";
360                         case GL_DEPTH32F_STENCIL8:      return "depth32f_stencil8";
361                         case GL_RGB10_A2:                       return "rgb10_a2";
362                         case GL_RGBA4:                          return "rgba4";
363                         case GL_RGB5_A1:                        return "rgb5_a1";
364                         case GL_RGB565:                         return "rgb565";
365                         case GL_RGB8:                           return "rgb8";
366                         case GL_RGBA8:                          return "rgba8";
367                         case GL_STENCIL_INDEX8:         return "stencil_index8";
368                         default:
369                                 DE_ASSERT(DE_FALSE);
370                                 return "";
371                 }
372         }
373
374         MovePtr<ImageSource> getImageSource (EGLint target, GLenum internalFormat, GLenum format, GLenum type, bool useTexLevel0)
375         {
376                 switch (target)
377                 {
378                         case EGL_GL_TEXTURE_2D_KHR:
379                         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
380                         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
381                         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
382                         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
383                         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
384                         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
385                                 DE_ASSERT(format != 0u && type != 0u);
386                                 return createTextureImageSource(target, internalFormat, format, type, useTexLevel0);
387
388                         case EGL_GL_RENDERBUFFER_KHR:
389                                 DE_ASSERT(format == 0u && type == 0u);
390                                 return createRenderbufferImageSource(internalFormat);
391
392                         case EGL_NATIVE_BUFFER_ANDROID:
393                                 DE_ASSERT(format == 0u && type == 0u);
394                                 return createAndroidNativeImageSource(internalFormat, 1u, false);
395
396                         default:
397                                 DE_FATAL("Impossible");
398                                 return MovePtr<ImageSource>();
399                 }
400         }
401
402         CreateImageGLES2 (EglTestContext& eglTestCtx, EGLint target, GLenum internalFormat, GLenum format, GLenum type, bool useTexLevel0 = false)
403                 : ImageTestCase         (eglTestCtx, ApiType::es(2, 0), string("create_image_gles2_") + getTargetName(target) + "_" + getStorageName(internalFormat) + (useTexLevel0 ? "_level0_only" : ""), "Create EGLImage from GLES2 object")
404                 , m_source                      (getImageSource(target, internalFormat, format, type, useTexLevel0))
405                 , m_internalFormat      (internalFormat)
406         {
407         }
408
409         IterateResult iterate (void)
410         {
411                 const Library&                  egl                             = m_eglTestCtx.getLibrary();
412                 const EGLDisplay                dpy                             = m_display;
413
414                 if (eglu::getVersion(egl, dpy) < eglu::Version(1, 5))
415                         CHECK_EXTENSION(dpy, m_source->getRequiredExtension());
416
417                 // Initialize result.
418                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
419
420                 // Create GLES2 context
421                 TestLog&                                log                             = m_testCtx.getLog();
422                 const ContextType               contextType             (ApiType::es(2, 0));
423                 Context                                 context                 (m_eglTestCtx, dpy, contextType, 64, 64);
424                 const EGLContext                eglContext              = context.getEglContext();
425
426                 if ((m_internalFormat == GL_RED || m_internalFormat == GL_RG) && !isGLRedSupported())
427                         TCU_THROW(NotSupportedError, "Unsupported extension: GL_EXT_texture_rg");
428
429                 log << TestLog::Message << "Using EGL config " << eglu::getConfigID(egl, dpy, context.getConfig()) << TestLog::EndMessage;
430
431                 UniquePtr<ClientBuffer> clientBuffer    (m_source->createBuffer(egl, context.gl()));
432                 const EGLImageKHR               image                   = m_source->createImage(egl, dpy, eglContext, clientBuffer->get());
433
434                 if (image == EGL_NO_IMAGE_KHR)
435                 {
436                         log << TestLog::Message << "  Fail: Got EGL_NO_IMAGE_KHR!" << TestLog::EndMessage;
437
438                         if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
439                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got EGL_NO_IMAGE_KHR");
440                 }
441
442                 // Destroy image
443                 CHECK_EXT_CALL_RET(egl.destroyImageKHR(context.getEglDisplay(), image), (EGLBoolean)EGL_TRUE, EGL_SUCCESS);
444
445                 return STOP;
446         }
447
448 private:
449         const UniquePtr<ImageSource>    m_source;
450         const GLenum                                    m_internalFormat;
451 };
452
453 class ImageTargetGLES2 : public ImageTestCase
454 {
455 public:
456         static const char* getTargetName (GLenum target)
457         {
458                 switch (target)
459                 {
460                         case GL_TEXTURE_2D:             return "tex2d";
461                         case GL_RENDERBUFFER:   return "renderbuffer";
462                         default:
463                                 DE_ASSERT(DE_FALSE);
464                                 return "";
465                 }
466         }
467
468         ImageTargetGLES2 (EglTestContext& eglTestCtx, GLenum target)
469                 : ImageTestCase (eglTestCtx, ApiType::es(2, 0), string("image_target_gles2_") + getTargetName(target), "Use EGLImage as GLES2 object")
470                 , m_target              (target)
471         {
472         }
473
474         IterateResult iterate (void)
475         {
476                 const Library&  egl     = m_eglTestCtx.getLibrary();
477                 TestLog&                log     = m_testCtx.getLog();
478
479                 // \todo [2011-07-21 pyry] Try all possible EGLImage sources
480                 CHECK_EXTENSION(m_display, "EGL_KHR_gl_texture_2D_image");
481
482                 // Initialize result.
483                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
484
485                 // Create GLES2 context
486
487                 Context context(m_eglTestCtx, m_display, ContextType(ApiType::es(2, 0)), 64, 64);
488                 log << TestLog::Message << "Using EGL config " << eglu::getConfigID(m_eglTestCtx.getLibrary(), context.getEglDisplay(), context.getConfig()) << TestLog::EndMessage;
489
490                 // Check for OES_EGL_image
491                 {
492                         const char* glExt = (const char*)glGetString(GL_EXTENSIONS);
493
494                         if (string(glExt).find("GL_OES_EGL_image") == string::npos)
495                                 throw tcu::NotSupportedError("Extension not supported", "GL_OES_EGL_image", __FILE__, __LINE__);
496
497                         TCU_CHECK(m_gl.eglImageTargetTexture2DOES);
498                         TCU_CHECK(m_gl.eglImageTargetRenderbufferStorageOES);
499                 }
500
501                 // Create GL_TEXTURE_2D and EGLImage from it.
502                 log << TestLog::Message << "Creating EGLImage using GL_TEXTURE_2D with GL_RGBA storage" << TestLog::EndMessage;
503
504                 deUint32 srcTex = 1;
505                 GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, srcTex));
506                 GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL));
507                 GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
508
509                 // Create EGL image
510                 EGLint          attribs[]       = { EGL_GL_TEXTURE_LEVEL_KHR, 0, EGL_NONE };
511                 EGLImageKHR     image           = CHECK_EXT_CALL_ERR(egl.createImageKHR(context.getEglDisplay(), context.getEglContext(), EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)(deUintptr)srcTex, attribs), EGL_SUCCESS);
512                 if (image == EGL_NO_IMAGE_KHR)
513                 {
514                         log << TestLog::Message << "  Fail: Got EGL_NO_IMAGE_KHR!" << TestLog::EndMessage;
515
516                         if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
517                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got EGL_NO_IMAGE_KHR");
518                 }
519
520                 // Create texture or renderbuffer
521                 if (m_target == GL_TEXTURE_2D)
522                 {
523                         log << TestLog::Message << "Creating GL_TEXTURE_2D from EGLimage" << TestLog::EndMessage;
524
525                         deUint32 dstTex = 2;
526                         GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, dstTex));
527                         GLU_CHECK_CALL(glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image));
528                         GLU_CHECK_CALL(glDeleteTextures(1, &dstTex));
529                 }
530                 else
531                 {
532                         DE_ASSERT(m_target == GL_RENDERBUFFER);
533
534                         log << TestLog::Message << "Creating GL_RENDERBUFFER from EGLimage" << TestLog::EndMessage;
535
536                         deUint32 dstRbo = 2;
537                         GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, dstRbo));
538                         GLU_CHECK_CALL(glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)image));
539                         GLU_CHECK_CALL(glDeleteRenderbuffers(1, &dstRbo));
540                 }
541
542                 // Destroy image
543                 CHECK_EXT_CALL_RET(egl.destroyImageKHR(context.getEglDisplay(), image), (EGLBoolean)EGL_TRUE, EGL_SUCCESS);
544
545                 // Destroy source texture object
546                 GLU_CHECK_CALL(glDeleteTextures(1, &srcTex));
547
548                 return STOP;
549         }
550
551 private:
552         GLenum  m_target;
553 };
554
555 class ApiTests : public TestCaseGroup
556 {
557 public:
558         ApiTests (EglTestContext& eglTestCtx, const string& name, const string& desc) : TestCaseGroup(eglTestCtx, name.c_str(), desc.c_str()) {}
559
560         void init (void)
561         {
562                 addChild(new Image::InvalidCreateImage(m_eglTestCtx));
563
564                 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_2D_KHR, GL_RED, GL_RED, GL_UNSIGNED_BYTE, false));
565                 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_2D_KHR, GL_RG, GL_RG, GL_UNSIGNED_BYTE, false));
566
567                 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_2D_KHR, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE));
568                 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_2D_KHR, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE));
569
570                 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_2D_KHR, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE));
571                 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE));
572                 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_2D_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, true));
573
574                 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE));
575                 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE));
576                 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, true));
577
578                 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE));
579                 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE));
580                 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE));
581                 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE));
582                 addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE));
583
584                 static const GLenum rboStorages[] =
585                 {
586                         GL_DEPTH_COMPONENT16,
587                         GL_RGBA4,
588                         GL_RGB5_A1,
589                         GL_RGB565,
590                         GL_STENCIL_INDEX8
591                 };
592                 for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(rboStorages); storageNdx++)
593                         addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_GL_RENDERBUFFER_KHR, rboStorages[storageNdx], (GLenum)0, (GLenum)0));
594
595                 static const GLenum androidFormats[] =
596                 {
597                         GL_RGB565,
598                         GL_RGB8,
599                         GL_RGBA8,
600                         GL_RGBA4,
601                         GL_RGB5_A1,
602                         GL_DEPTH_COMPONENT16,
603                         GL_DEPTH_COMPONENT24,
604                         GL_DEPTH24_STENCIL8,
605                         GL_DEPTH_COMPONENT32F,
606                         GL_DEPTH32F_STENCIL8,
607                         GL_RGB10_A2,
608                         GL_RGBA16F,
609                         GL_STENCIL_INDEX8
610                 };
611
612                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(androidFormats); ++formatNdx)
613                         addChild(new Image::CreateImageGLES2(m_eglTestCtx, EGL_NATIVE_BUFFER_ANDROID, androidFormats[formatNdx], (GLenum)0, (GLenum)0));
614
615                 addChild(new Image::ImageTargetGLES2(m_eglTestCtx, GL_TEXTURE_2D));
616                 addChild(new Image::ImageTargetGLES2(m_eglTestCtx, GL_RENDERBUFFER));
617         }
618 };
619
620 } // Image
621
622 ImageTests::ImageTests (EglTestContext& eglTestCtx)
623         : TestCaseGroup(eglTestCtx, "image", "EGLImage Tests")
624 {
625 }
626
627 ImageTests::~ImageTests (void)
628 {
629 }
630
631 void ImageTests::init (void)
632 {
633         addChild(new Image::ApiTests(m_eglTestCtx, "api", "EGLImage API tests"));
634         addChild(Image::createSimpleCreationTests(m_eglTestCtx, "create", "EGLImage creation tests"));
635         addChild(Image::createModifyTests(m_eglTestCtx, "modify", "EGLImage modifying tests"));
636         addChild(Image::createMultiContextRenderTests(m_eglTestCtx, "render_multiple_contexts", "EGLImage render tests on multiple contexts"));
637 }
638
639 } // egl
640 } // deqp