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