Merge vk-gl-cts/vulkan-cts-1.3.4 into vk-gl-cts/vulkan-cts-1.3.5
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglImageUtil.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 Common utilities for EGL images.
22  *//*--------------------------------------------------------------------*/
23
24
25 #include "teglImageUtil.hpp"
26
27 #include "tcuTexture.hpp"
28 #include "tcuTextureUtil.hpp"
29
30 #include "egluGLUtil.hpp"
31 #include "egluNativeWindow.hpp"
32 #include "egluNativePixmap.hpp"
33
34 #include "eglwLibrary.hpp"
35 #include "eglwEnums.hpp"
36
37 #include "glwEnums.hpp"
38
39 #include "gluObjectWrapper.hpp"
40 #include "gluTextureUtil.hpp"
41
42 namespace deqp
43 {
44 namespace egl
45 {
46 namespace Image
47 {
48
49 using std::string;
50 using std::vector;
51
52 using de::UniquePtr;
53 using de::MovePtr;
54
55 using tcu::TextureFormat;
56 using tcu::Texture2D;
57 using tcu::Vec4;
58
59 using glu::Framebuffer;
60 using glu::Texture;
61
62 using eglu::AttribMap;
63 using eglu::UniqueSurface;
64 using eglu::NativeDisplay;
65 using eglu::NativeWindow;
66 using eglu::NativePixmap;
67 using eglu::NativeDisplayFactory;
68 using eglu::NativeWindowFactory;
69 using eglu::NativePixmapFactory;
70 using eglu::WindowParams;
71
72 using namespace glw;
73 using namespace eglw;
74
75 enum {
76         IMAGE_WIDTH             = 64,
77         IMAGE_HEIGHT    = 64,
78 };
79
80
81 template <typename T>
82 struct NativeSurface : public ManagedSurface
83 {
84 public:
85         explicit                NativeSurface   (MovePtr<UniqueSurface> surface,
86                                                                          MovePtr<T>                             native)
87                                                 : ManagedSurface        (surface)
88                                                 , m_native                      (native) {}
89
90 private:
91         UniquePtr<T>    m_native;
92 };
93
94 typedef NativeSurface<NativeWindow> NativeWindowSurface;
95 typedef NativeSurface<NativePixmap> NativePixmapSurface;
96
97 MovePtr<ManagedSurface> createSurface (EglTestContext& eglTestCtx, EGLDisplay dpy, EGLConfig config, int width, int height)
98 {
99         const Library&                          egl                             = eglTestCtx.getLibrary();
100         EGLint                                          surfaceTypeBits = eglu::getConfigAttribInt(egl, dpy, config, EGL_SURFACE_TYPE);
101         const NativeDisplayFactory&     displayFactory  = eglTestCtx.getNativeDisplayFactory();
102         NativeDisplay&                          nativeDisplay   = eglTestCtx.getNativeDisplay();
103
104         if (surfaceTypeBits & EGL_PBUFFER_BIT)
105         {
106                 static const EGLint attribs[]   = { EGL_WIDTH, width, EGL_HEIGHT, height, EGL_NONE };
107                 const EGLSurface        surface         = egl.createPbufferSurface(dpy, config, attribs);
108
109                 EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()");
110
111                 return de::newMovePtr<ManagedSurface>(MovePtr<UniqueSurface>(new UniqueSurface(egl, dpy, surface)));
112         }
113         else if (surfaceTypeBits & EGL_WINDOW_BIT)
114         {
115                 const NativeWindowFactory&      windowFactory   = selectNativeWindowFactory(displayFactory, eglTestCtx.getTestContext().getCommandLine());
116
117                 MovePtr<NativeWindow>           window  (windowFactory.createWindow(&nativeDisplay, dpy, config, DE_NULL, WindowParams(width, height, WindowParams::VISIBILITY_DONT_CARE)));
118                 const EGLSurface                        surface = eglu::createWindowSurface(nativeDisplay, *window, dpy, config, DE_NULL);
119
120                 return MovePtr<ManagedSurface>(new NativeWindowSurface(MovePtr<UniqueSurface>(new UniqueSurface(egl, dpy, surface)), window));
121         }
122         else if (surfaceTypeBits & EGL_PIXMAP_BIT)
123         {
124                 const NativePixmapFactory&      pixmapFactory   = selectNativePixmapFactory(displayFactory, eglTestCtx.getTestContext().getCommandLine());
125
126                 MovePtr<NativePixmap>   pixmap  (pixmapFactory.createPixmap(&nativeDisplay, dpy, config, DE_NULL, width, height));
127                 const EGLSurface                surface = eglu::createPixmapSurface(eglTestCtx.getNativeDisplay(), *pixmap, dpy, config, DE_NULL);
128
129                 return MovePtr<ManagedSurface>(new NativePixmapSurface(MovePtr<UniqueSurface>(new UniqueSurface(egl, dpy, surface)), pixmap));
130         }
131         else
132                 TCU_FAIL("No valid surface types supported in config");
133 }
134
135 class GLClientBuffer : public ClientBuffer
136 {
137         EGLClientBuffer get             (void) const { return reinterpret_cast<EGLClientBuffer>(static_cast<deUintptr>(getName())); }
138
139 protected:
140         virtual GLuint  getName (void) const = 0;
141 };
142
143 class TextureClientBuffer : public GLClientBuffer
144 {
145 public:
146                                                 TextureClientBuffer     (const glw::Functions& gl) : m_texture (gl) {}
147         GLuint                          getName                         (void) const { return *m_texture; }
148
149 private:
150         glu::Texture            m_texture;
151 };
152
153 class GLImageSource : public ImageSource
154 {
155 public:
156         EGLImageKHR                     createImage                     (const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
157
158 protected:
159         virtual AttribMap       getCreateAttribs        (void) const = 0;
160         virtual EGLenum         getSource                       (void) const = 0;
161 };
162
163 EGLImageKHR GLImageSource::createImage (const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const
164 {
165         AttribMap                               attribMap       = getCreateAttribs();
166
167         attribMap[EGL_IMAGE_PRESERVED_KHR] = EGL_TRUE;
168
169         {
170                 const vector<EGLint>    attribs = eglu::attribMapToList(attribMap);
171                 const EGLImageKHR               image   = egl.createImageKHR(dpy, ctx, getSource(),
172                                                                                                                          clientBuffer, &attribs.front());
173                 EGLU_CHECK_MSG(egl, "eglCreateImageKHR()");
174                 return image;
175         }
176 }
177
178 class TextureImageSource : public GLImageSource
179 {
180 public:
181                                                         TextureImageSource      (GLenum internalFormat, GLenum format, GLenum type, bool useTexLevel0) : m_internalFormat(internalFormat), m_format(format), m_type(type), m_useTexLevel0(useTexLevel0) {}
182         MovePtr<ClientBuffer>   createBuffer            (const eglw::Library& egl, const glw::Functions& gl, Texture2D* reference) const;
183         GLenum                                  getEffectiveFormat      (void) const;
184         GLenum                                  getInternalFormat       (void) const { return m_internalFormat; }
185
186 protected:
187         AttribMap                               getCreateAttribs        (void) const;
188         virtual void                    initTexture                     (const glw::Functions& gl) const = 0;
189         virtual GLenum                  getGLTarget                     (void) const = 0;
190
191         const GLenum                    m_internalFormat;
192         const GLenum                    m_format;
193         const GLenum                    m_type;
194         const bool                              m_useTexLevel0;
195 };
196
197 bool isSizedFormat (GLenum format)
198 {
199         try
200         {
201                 glu::mapGLInternalFormat(format);
202                 return true;
203         }
204         catch (const tcu::InternalError&)
205         {
206                 return false;
207         }
208 }
209
210 GLenum getEffectiveFormat (GLenum format, GLenum type)
211 {
212         return glu::getInternalFormat(glu::mapGLTransferFormat(format, type));
213 }
214
215 GLenum TextureImageSource::getEffectiveFormat (void) const
216 {
217         if (isSizedFormat(m_internalFormat))
218                 return m_internalFormat;
219         else
220                 return deqp::egl::Image::getEffectiveFormat(m_format, m_type);
221 }
222
223 AttribMap TextureImageSource::getCreateAttribs (void) const
224 {
225         AttribMap ret;
226
227         ret[EGL_GL_TEXTURE_LEVEL_KHR] = 0;
228
229         return ret;
230 }
231
232 MovePtr<ClientBuffer> TextureImageSource::createBuffer (const eglw::Library& egl, const glw::Functions& gl, Texture2D* ref) const
233 {
234         DE_UNREF(egl);
235
236         MovePtr<TextureClientBuffer>    clientBuffer    (new TextureClientBuffer(gl));
237         const GLuint                                    texture                 = clientBuffer->getName();
238         const GLenum                                    target                  = getGLTarget();
239
240         GLU_CHECK_GLW_CALL(gl, bindTexture(target, texture));
241         initTexture(gl);
242
243         if (!m_useTexLevel0)
244         {
245                 // Set minification filter to linear. This makes the texture complete.
246                 GLU_CHECK_GLW_CALL(gl, texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
247         }
248
249         if (ref != DE_NULL)
250         {
251                 GLenum          imgTarget       = eglu::getImageGLTarget(getSource());
252
253                 *ref = Texture2D(glu::mapGLTransferFormat(m_format, m_type), IMAGE_WIDTH, IMAGE_HEIGHT);
254                 ref->allocLevel(0);
255                 tcu::fillWithComponentGradients(ref->getLevel(0),
256                                                                                 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),
257                                                                                 tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
258
259                 GLU_CHECK_GLW_CALL(gl, texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
260                 GLU_CHECK_GLW_CALL(gl, texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
261                 GLU_CHECK_GLW_CALL(gl, texParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
262                 GLU_CHECK_GLW_CALL(gl, texParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
263
264                 GLU_CHECK_GLW_CALL(gl, texImage2D(imgTarget, 0, m_internalFormat, IMAGE_WIDTH, IMAGE_HEIGHT,
265                                                                                   0, m_format, m_type, ref->getLevel(0).getDataPtr()));
266         }
267         GLU_CHECK_GLW_CALL(gl, bindTexture(target, 0));
268         return MovePtr<ClientBuffer>(clientBuffer);
269 }
270
271 class Texture2DImageSource : public TextureImageSource
272 {
273 public:
274                                         Texture2DImageSource    (GLenum internalFormat, GLenum format, GLenum type, bool useTexLevel0) : TextureImageSource(internalFormat, format, type, useTexLevel0) {}
275         EGLenum                 getSource                               (void) const { return EGL_GL_TEXTURE_2D_KHR; }
276         string                  getRequiredExtension    (void) const { return "EGL_KHR_gl_texture_2D_image"; }
277         GLenum                  getGLTarget                             (void) const { return GL_TEXTURE_2D; }
278
279 protected:
280         void                    initTexture                             (const glw::Functions& gl) const;
281 };
282
283 void Texture2DImageSource::initTexture (const glw::Functions& gl) const
284 {
285         // Specify mipmap level 0
286         GLU_CHECK_CALL_ERROR(gl.texImage2D(GL_TEXTURE_2D, 0, m_internalFormat, IMAGE_WIDTH, IMAGE_HEIGHT, 0, m_format, m_type, DE_NULL),
287                                                  gl.getError());
288 }
289
290 class TextureCubeMapImageSource : public TextureImageSource
291 {
292 public:
293                                         TextureCubeMapImageSource       (EGLenum source, GLenum internalFormat, GLenum format, GLenum type, bool useTexLevel0) : TextureImageSource(internalFormat, format, type, useTexLevel0), m_source(source) {}
294         EGLenum                 getSource                                       (void) const { return m_source; }
295         string                  getRequiredExtension            (void) const { return "EGL_KHR_gl_texture_cubemap_image"; }
296         GLenum                  getGLTarget                                     (void) const { return GL_TEXTURE_CUBE_MAP; }
297
298 protected:
299         void                    initTexture                                     (const glw::Functions& gl) const;
300
301         EGLenum                 m_source;
302 };
303
304 void TextureCubeMapImageSource::initTexture (const glw::Functions& gl) const
305 {
306         // Specify mipmap level 0 for all faces
307         static const GLenum faces[] =
308         {
309                 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
310                 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
311                 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
312                 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
313                 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
314                 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
315         };
316
317         for (int faceNdx = 0; faceNdx < DE_LENGTH_OF_ARRAY(faces); faceNdx++)
318                 GLU_CHECK_GLW_CALL(gl, texImage2D(faces[faceNdx], 0, m_internalFormat, IMAGE_WIDTH, IMAGE_HEIGHT, 0, m_format, m_type, DE_NULL));
319 }
320
321 class RenderbufferClientBuffer : public GLClientBuffer
322 {
323 public:
324                                                 RenderbufferClientBuffer        (const glw::Functions& gl) : m_rbo (gl) {}
325         GLuint                          getName                                         (void) const { return *m_rbo; }
326
327 private:
328         glu::Renderbuffer       m_rbo;
329 };
330
331 class RenderbufferImageSource : public GLImageSource
332 {
333 public:
334                                                         RenderbufferImageSource (GLenum format) : m_format(format) {}
335
336         string                                  getRequiredExtension    (void) const    { return "EGL_KHR_gl_renderbuffer_image"; }
337         MovePtr<ClientBuffer>   createBuffer                    (const eglw::Library& egl, const glw::Functions& gl, Texture2D* reference) const;
338         GLenum                                  getEffectiveFormat              (void) const { return m_format; }
339
340 protected:
341         EGLenum                                 getSource                               (void) const    { return EGL_GL_RENDERBUFFER_KHR; }
342         AttribMap                               getCreateAttribs                (void) const    { return AttribMap(); }
343
344         GLenum                                  m_format;
345 };
346
347 void initializeStencilRbo(const glw::Functions& gl, GLuint rbo, Texture2D& ref)
348 {
349         static const deUint32 stencilValues[] =
350         {
351                 0xBF688C11u,
352                 0xB43D2922u,
353                 0x055D5FFBu,
354                 0x9300655Eu,
355                 0x63BE0DF2u,
356                 0x0345C13Bu,
357                 0x1C184832u,
358                 0xD107040Fu,
359                 0x9B91569Fu,
360                 0x0F0CFDC7u,
361         };
362
363         const deUint32 numStencilBits   = tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilTextureFormat(ref.getLevel(0).getFormat(), tcu::Sampler::MODE_STENCIL)).x();
364         const deUint32 stencilMask              = deBitMask32(0, numStencilBits);
365
366         GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
367                                                                                                    GL_RENDERBUFFER, rbo));
368         GLU_CHECK_GLW_CALL(gl, clearStencil(0));
369         GLU_CHECK_GLW_CALL(gl, clear(GL_STENCIL_BUFFER_BIT));
370         tcu::clearStencil(ref.getLevel(0), 0);
371
372         // create a pattern
373         GLU_CHECK_GLW_CALL(gl, enable(GL_SCISSOR_TEST));
374         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stencilValues); ++ndx)
375         {
376                 const deUint32          stencil = stencilValues[ndx] & stencilMask;
377                 const tcu::IVec2        size    = tcu::IVec2((int)((float)(DE_LENGTH_OF_ARRAY(stencilValues) - ndx) * ((float)ref.getWidth() / float(DE_LENGTH_OF_ARRAY(stencilValues)))),
378                                                                                                  (int)((float)(DE_LENGTH_OF_ARRAY(stencilValues) - ndx) * ((float)ref.getHeight() / float(DE_LENGTH_OF_ARRAY(stencilValues) + 4)))); // not symmetric
379
380                 if (size.x() == 0 || size.y() == 0)
381                         break;
382
383                 GLU_CHECK_GLW_CALL(gl, scissor(0, 0, size.x(), size.y()));
384                 GLU_CHECK_GLW_CALL(gl, clearStencil(stencil));
385                 GLU_CHECK_GLW_CALL(gl, clear(GL_STENCIL_BUFFER_BIT));
386
387                 tcu::clearStencil(tcu::getSubregion(ref.getLevel(0), 0, 0, size.x(), size.y()), stencil);
388         }
389
390         GLU_CHECK_GLW_CALL(gl, disable(GL_SCISSOR_TEST));
391         GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
392                                                                                                    GL_RENDERBUFFER, 0));
393 }
394
395 void initializeDepthRbo(const glw::Functions& gl, GLuint rbo, Texture2D& ref)
396 {
397         const int NUM_STEPS = 13;
398
399         GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
400                                                                                                    GL_RENDERBUFFER, rbo));
401
402         GLU_CHECK_GLW_CALL(gl, clearDepthf(0.0f));
403         GLU_CHECK_GLW_CALL(gl, clear(GL_DEPTH_BUFFER_BIT));
404         tcu::clearDepth(ref.getLevel(0), 0.0f);
405
406         // create a pattern
407         GLU_CHECK_GLW_CALL(gl, enable(GL_SCISSOR_TEST));
408         for (int ndx = 0; ndx < NUM_STEPS; ++ndx)
409         {
410                 const float                     depth   = (float)ndx / float(NUM_STEPS);
411                 const tcu::IVec2        size    = tcu::IVec2((int)((float)(NUM_STEPS - ndx) * ((float)ref.getWidth() / float(NUM_STEPS))),
412                                                                                                  (int)((float)(NUM_STEPS - ndx) * ((float)ref.getHeight() / float(NUM_STEPS + 4)))); // not symmetric
413
414                 if (size.x() == 0 || size.y() == 0)
415                         break;
416
417                 GLU_CHECK_GLW_CALL(gl, scissor(0, 0, size.x(), size.y()));
418                 GLU_CHECK_GLW_CALL(gl, clearDepthf(depth));
419                 GLU_CHECK_GLW_CALL(gl, clear(GL_DEPTH_BUFFER_BIT));
420
421                 tcu::clearDepth(tcu::getSubregion(ref.getLevel(0), 0, 0, size.x(), size.y()), depth);
422         }
423
424         GLU_CHECK_GLW_CALL(gl, disable(GL_SCISSOR_TEST));
425         GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
426                                                                                                    GL_RENDERBUFFER, 0));
427
428 }
429
430 void initializeColorRbo(const glw::Functions& gl, GLuint rbo, Texture2D& ref)
431 {
432         static const tcu::Vec4 colorValues[] =
433         {
434                 tcu::Vec4(0.9f, 0.5f, 0.65f, 1.0f),
435                 tcu::Vec4(0.5f, 0.7f, 0.65f, 1.0f),
436                 tcu::Vec4(0.2f, 0.5f, 0.65f, 1.0f),
437                 tcu::Vec4(0.3f, 0.1f, 0.5f, 1.0f),
438                 tcu::Vec4(0.8f, 0.2f, 0.3f, 1.0f),
439                 tcu::Vec4(0.9f, 0.4f, 0.8f, 1.0f),
440         };
441
442         GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
443                                                                                                    GL_RENDERBUFFER, rbo));
444         GLU_CHECK_GLW_CALL(gl, clearColor(1.0f, 1.0f, 0.0f, 1.0f));
445         GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
446         tcu::clear(ref.getLevel(0), Vec4(1.0f, 1.0f, 0.0f, 1.0f));
447
448         // create a pattern
449         GLU_CHECK_GLW_CALL(gl, enable(GL_SCISSOR_TEST));
450         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorValues); ++ndx)
451         {
452                 const tcu::IVec2        size    = tcu::IVec2((int)((float)(DE_LENGTH_OF_ARRAY(colorValues) - ndx) * ((float)ref.getWidth() / float(DE_LENGTH_OF_ARRAY(colorValues)))),
453                                                                                                  (int)((float)(DE_LENGTH_OF_ARRAY(colorValues) - ndx) * ((float)ref.getHeight() / float(DE_LENGTH_OF_ARRAY(colorValues) + 4)))); // not symmetric
454
455                 if (size.x() == 0 || size.y() == 0)
456                         break;
457
458                 GLU_CHECK_GLW_CALL(gl, scissor(0, 0, size.x(), size.y()));
459                 GLU_CHECK_GLW_CALL(gl, clearColor(colorValues[ndx].x(), colorValues[ndx].y(), colorValues[ndx].z(), colorValues[ndx].w()));
460                 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT));
461
462                 tcu::clear(tcu::getSubregion(ref.getLevel(0), 0, 0, size.x(), size.y()), colorValues[ndx]);
463         }
464
465         GLU_CHECK_GLW_CALL(gl, disable(GL_SCISSOR_TEST));
466         GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
467                                                                                                    GL_RENDERBUFFER, 0));
468 }
469
470 MovePtr<ClientBuffer> RenderbufferImageSource::createBuffer (const eglw::Library& egl, const glw::Functions& gl, Texture2D* ref) const
471 {
472         DE_UNREF(egl);
473
474         MovePtr<RenderbufferClientBuffer>       buffer  (new RenderbufferClientBuffer(gl));
475         const GLuint                                            rbo             = buffer->getName();
476
477         GLU_CHECK_CALL_ERROR(gl.bindRenderbuffer(GL_RENDERBUFFER, rbo), gl.getError());
478
479         // Specify storage.
480         GLU_CHECK_CALL_ERROR(gl.renderbufferStorage(GL_RENDERBUFFER, m_format, 64, 64), gl.getError());
481
482         if (ref != DE_NULL)
483         {
484                 Framebuffer                     fbo                     (gl);
485                 const TextureFormat     texFormat       = glu::mapGLInternalFormat(m_format);
486
487                 *ref = tcu::Texture2D(texFormat, 64, 64);
488                 ref->allocLevel(0);
489
490                 gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
491                 switch (m_format)
492                 {
493                         case GL_STENCIL_INDEX8:
494                                 initializeStencilRbo(gl, rbo, *ref);
495                                 break;
496                         case GL_DEPTH_COMPONENT16:
497                                 initializeDepthRbo(gl, rbo, *ref);
498                                 break;
499                         case GL_RGBA4:
500                                 initializeColorRbo(gl, rbo, *ref);
501                                 break;
502                         case GL_RGB5_A1:
503                                 initializeColorRbo(gl, rbo, *ref);
504                                 break;
505                         case GL_RGB565:
506                                 initializeColorRbo(gl, rbo, *ref);
507                                 break;
508                         default:
509                                 DE_FATAL("Impossible");
510                 }
511
512                 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
513         }
514
515         return MovePtr<ClientBuffer>(buffer);
516 }
517
518 class UnsupportedImageSource : public ImageSource
519 {
520 public:
521                                                         UnsupportedImageSource  (const string& message, GLenum format, bool isYUV) : m_message(message), m_format(format), m_isY8Cb8Cr8_420(isYUV) {}
522         string                                  getRequiredExtension    (void) const { fail(); return ""; }
523         MovePtr<ClientBuffer>   createBuffer                    (const eglw::Library& egl, const glw::Functions&, tcu::Texture2D*) const { DE_UNREF(egl); fail(); return de::MovePtr<ClientBuffer>(); }
524         EGLImageKHR                             createImage                             (const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const;
525         GLenum                                  getEffectiveFormat              (void) const { return m_format; }
526         bool                                    isYUVFormatImage                (void) const {return m_isY8Cb8Cr8_420;};
527 private:
528         const string                    m_message;
529         GLenum                                  m_format;
530         bool                                    m_isY8Cb8Cr8_420;
531         void                                    fail                                    (void) const { TCU_THROW(NotSupportedError, m_message.c_str()); }
532 };
533
534 EGLImageKHR     UnsupportedImageSource::createImage (const Library&, EGLDisplay, EGLContext, EGLClientBuffer) const
535 {
536         fail();
537         return EGL_NO_IMAGE_KHR;
538 }
539
540 MovePtr<ImageSource> createTextureImageSource (EGLenum source, GLenum internalFormat, GLenum format, GLenum type, bool useTexLevel0)
541 {
542         if (source == EGL_GL_TEXTURE_2D_KHR)
543                 return MovePtr<ImageSource>(new Texture2DImageSource(internalFormat, format, type, useTexLevel0));
544         else
545                 return MovePtr<ImageSource>(new TextureCubeMapImageSource(source, internalFormat, format, type, useTexLevel0));
546 }
547
548 MovePtr<ImageSource> createRenderbufferImageSource (GLenum format)
549 {
550         return MovePtr<ImageSource>(new RenderbufferImageSource(format));
551 }
552
553 MovePtr<ImageSource> createUnsupportedImageSource (const string& message, GLenum format, bool isYUV)
554 {
555         return MovePtr<ImageSource>(new UnsupportedImageSource(message, format, isYUV));
556 }
557
558 } // Image
559 } // egl
560 } // deqp