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 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 glw::Functions& gl, Texture2D* ref) const 233 { 234 MovePtr<TextureClientBuffer> clientBuffer (new TextureClientBuffer(gl)); 235 const GLuint texture = clientBuffer->getName(); 236 const GLenum target = getGLTarget(); 237 238 GLU_CHECK_GLW_CALL(gl, bindTexture(target, texture)); 239 initTexture(gl); 240 241 if (!m_useTexLevel0) 242 { 243 // Set minification filter to linear. This makes the texture complete. 244 GLU_CHECK_GLW_CALL(gl, texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); 245 } 246 247 if (ref != DE_NULL) 248 { 249 GLenum imgTarget = eglu::getImageGLTarget(getSource()); 250 251 *ref = Texture2D(glu::mapGLTransferFormat(m_format, m_type), IMAGE_WIDTH, IMAGE_HEIGHT); 252 ref->allocLevel(0); 253 tcu::fillWithComponentGradients(ref->getLevel(0), 254 tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), 255 tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); 256 257 GLU_CHECK_GLW_CALL(gl, texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); 258 GLU_CHECK_GLW_CALL(gl, texParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); 259 GLU_CHECK_GLW_CALL(gl, texParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); 260 GLU_CHECK_GLW_CALL(gl, texParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); 261 262 GLU_CHECK_GLW_CALL(gl, texImage2D(imgTarget, 0, m_internalFormat, IMAGE_WIDTH, IMAGE_HEIGHT, 263 0, m_format, m_type, ref->getLevel(0).getDataPtr())); 264 } 265 GLU_CHECK_GLW_CALL(gl, bindTexture(target, 0)); 266 return MovePtr<ClientBuffer>(clientBuffer); 267 } 268 269 class Texture2DImageSource : public TextureImageSource 270 { 271 public: 272 Texture2DImageSource (GLenum internalFormat, GLenum format, GLenum type, bool useTexLevel0) : TextureImageSource(internalFormat, format, type, useTexLevel0) {} 273 EGLenum getSource (void) const { return EGL_GL_TEXTURE_2D_KHR; } 274 string getRequiredExtension (void) const { return "EGL_KHR_gl_texture_2D_image"; } 275 GLenum getGLTarget (void) const { return GL_TEXTURE_2D; } 276 277 protected: 278 void initTexture (const glw::Functions& gl) const; 279 }; 280 281 void Texture2DImageSource::initTexture (const glw::Functions& gl) const 282 { 283 // Specify mipmap level 0 284 GLU_CHECK_CALL_ERROR(gl.texImage2D(GL_TEXTURE_2D, 0, m_internalFormat, IMAGE_WIDTH, IMAGE_HEIGHT, 0, m_format, m_type, DE_NULL), 285 gl.getError()); 286 } 287 288 class TextureCubeMapImageSource : public TextureImageSource 289 { 290 public: 291 TextureCubeMapImageSource (EGLenum source, GLenum internalFormat, GLenum format, GLenum type, bool useTexLevel0) : TextureImageSource(internalFormat, format, type, useTexLevel0), m_source(source) {} 292 EGLenum getSource (void) const { return m_source; } 293 string getRequiredExtension (void) const { return "EGL_KHR_gl_texture_cubemap_image"; } 294 GLenum getGLTarget (void) const { return GL_TEXTURE_CUBE_MAP; } 295 296 protected: 297 void initTexture (const glw::Functions& gl) const; 298 299 EGLenum m_source; 300 }; 301 302 void TextureCubeMapImageSource::initTexture (const glw::Functions& gl) const 303 { 304 // Specify mipmap level 0 for all faces 305 static const GLenum faces[] = 306 { 307 GL_TEXTURE_CUBE_MAP_POSITIVE_X, 308 GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 309 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 310 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 311 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 312 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 313 }; 314 315 for (int faceNdx = 0; faceNdx < DE_LENGTH_OF_ARRAY(faces); faceNdx++) 316 GLU_CHECK_GLW_CALL(gl, texImage2D(faces[faceNdx], 0, m_internalFormat, IMAGE_WIDTH, IMAGE_HEIGHT, 0, m_format, m_type, DE_NULL)); 317 } 318 319 class RenderbufferClientBuffer : public GLClientBuffer 320 { 321 public: 322 RenderbufferClientBuffer (const glw::Functions& gl) : m_rbo (gl) {} 323 GLuint getName (void) const { return *m_rbo; } 324 325 private: 326 glu::Renderbuffer m_rbo; 327 }; 328 329 class RenderbufferImageSource : public GLImageSource 330 { 331 public: 332 RenderbufferImageSource (GLenum format) : m_format(format) {} 333 334 string getRequiredExtension (void) const { return "EGL_KHR_gl_renderbuffer_image"; } 335 MovePtr<ClientBuffer> createBuffer (const glw::Functions& gl, Texture2D* reference) const; 336 GLenum getEffectiveFormat (void) const { return m_format; } 337 338 protected: 339 EGLenum getSource (void) const { return EGL_GL_RENDERBUFFER_KHR; } 340 AttribMap getCreateAttribs (void) const { return AttribMap(); } 341 342 GLenum m_format; 343 }; 344 345 void initializeStencilRbo(const glw::Functions& gl, GLuint rbo, Texture2D& ref) 346 { 347 static const deUint32 stencilValues[] = 348 { 349 0xBF688C11u, 350 0xB43D2922u, 351 0x055D5FFBu, 352 0x9300655Eu, 353 0x63BE0DF2u, 354 0x0345C13Bu, 355 0x1C184832u, 356 0xD107040Fu, 357 0x9B91569Fu, 358 0x0F0CFDC7u, 359 }; 360 361 const deUint32 numStencilBits = tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilTextureFormat(ref.getLevel(0).getFormat(), tcu::Sampler::MODE_STENCIL)).x(); 362 const deUint32 stencilMask = deBitMask32(0, numStencilBits); 363 364 GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, 365 GL_RENDERBUFFER, rbo)); 366 GLU_CHECK_GLW_CALL(gl, clearStencil(0)); 367 GLU_CHECK_GLW_CALL(gl, clear(GL_STENCIL_BUFFER_BIT)); 368 tcu::clearStencil(ref.getLevel(0), 0); 369 370 // create a pattern 371 GLU_CHECK_GLW_CALL(gl, enable(GL_SCISSOR_TEST)); 372 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stencilValues); ++ndx) 373 { 374 const deUint32 stencil = stencilValues[ndx] & stencilMask; 375 const tcu::IVec2 size = tcu::IVec2((int)((float)(DE_LENGTH_OF_ARRAY(stencilValues) - ndx) * ((float)ref.getWidth() / float(DE_LENGTH_OF_ARRAY(stencilValues)))), 376 (int)((float)(DE_LENGTH_OF_ARRAY(stencilValues) - ndx) * ((float)ref.getHeight() / float(DE_LENGTH_OF_ARRAY(stencilValues) + 4)))); // not symmetric 377 378 if (size.x() == 0 || size.y() == 0) 379 break; 380 381 GLU_CHECK_GLW_CALL(gl, scissor(0, 0, size.x(), size.y())); 382 GLU_CHECK_GLW_CALL(gl, clearStencil(stencil)); 383 GLU_CHECK_GLW_CALL(gl, clear(GL_STENCIL_BUFFER_BIT)); 384 385 tcu::clearStencil(tcu::getSubregion(ref.getLevel(0), 0, 0, size.x(), size.y()), stencil); 386 } 387 388 GLU_CHECK_GLW_CALL(gl, disable(GL_SCISSOR_TEST)); 389 GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, 390 GL_RENDERBUFFER, 0)); 391 } 392 393 void initializeDepthRbo(const glw::Functions& gl, GLuint rbo, Texture2D& ref) 394 { 395 const int NUM_STEPS = 13; 396 397 GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 398 GL_RENDERBUFFER, rbo)); 399 400 GLU_CHECK_GLW_CALL(gl, clearDepthf(0.0f)); 401 GLU_CHECK_GLW_CALL(gl, clear(GL_DEPTH_BUFFER_BIT)); 402 tcu::clearDepth(ref.getLevel(0), 0.0f); 403 404 // create a pattern 405 GLU_CHECK_GLW_CALL(gl, enable(GL_SCISSOR_TEST)); 406 for (int ndx = 0; ndx < NUM_STEPS; ++ndx) 407 { 408 const float depth = (float)ndx / float(NUM_STEPS); 409 const tcu::IVec2 size = tcu::IVec2((int)((float)(NUM_STEPS - ndx) * ((float)ref.getWidth() / float(NUM_STEPS))), 410 (int)((float)(NUM_STEPS - ndx) * ((float)ref.getHeight() / float(NUM_STEPS + 4)))); // not symmetric 411 412 if (size.x() == 0 || size.y() == 0) 413 break; 414 415 GLU_CHECK_GLW_CALL(gl, scissor(0, 0, size.x(), size.y())); 416 GLU_CHECK_GLW_CALL(gl, clearDepthf(depth)); 417 GLU_CHECK_GLW_CALL(gl, clear(GL_DEPTH_BUFFER_BIT)); 418 419 tcu::clearDepth(tcu::getSubregion(ref.getLevel(0), 0, 0, size.x(), size.y()), depth); 420 } 421 422 GLU_CHECK_GLW_CALL(gl, disable(GL_SCISSOR_TEST)); 423 GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, 424 GL_RENDERBUFFER, 0)); 425 426 } 427 428 void initializeColorRbo(const glw::Functions& gl, GLuint rbo, Texture2D& ref) 429 { 430 static const tcu::Vec4 colorValues[] = 431 { 432 tcu::Vec4(0.9f, 0.5f, 0.65f, 1.0f), 433 tcu::Vec4(0.5f, 0.7f, 0.65f, 1.0f), 434 tcu::Vec4(0.2f, 0.5f, 0.65f, 1.0f), 435 tcu::Vec4(0.3f, 0.1f, 0.5f, 1.0f), 436 tcu::Vec4(0.8f, 0.2f, 0.3f, 1.0f), 437 tcu::Vec4(0.9f, 0.4f, 0.8f, 1.0f), 438 }; 439 440 GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 441 GL_RENDERBUFFER, rbo)); 442 GLU_CHECK_GLW_CALL(gl, clearColor(1.0f, 1.0f, 0.0f, 1.0f)); 443 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT)); 444 tcu::clear(ref.getLevel(0), Vec4(1.0f, 1.0f, 0.0f, 1.0f)); 445 446 // create a pattern 447 GLU_CHECK_GLW_CALL(gl, enable(GL_SCISSOR_TEST)); 448 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorValues); ++ndx) 449 { 450 const tcu::IVec2 size = tcu::IVec2((int)((float)(DE_LENGTH_OF_ARRAY(colorValues) - ndx) * ((float)ref.getWidth() / float(DE_LENGTH_OF_ARRAY(colorValues)))), 451 (int)((float)(DE_LENGTH_OF_ARRAY(colorValues) - ndx) * ((float)ref.getHeight() / float(DE_LENGTH_OF_ARRAY(colorValues) + 4)))); // not symmetric 452 453 if (size.x() == 0 || size.y() == 0) 454 break; 455 456 GLU_CHECK_GLW_CALL(gl, scissor(0, 0, size.x(), size.y())); 457 GLU_CHECK_GLW_CALL(gl, clearColor(colorValues[ndx].x(), colorValues[ndx].y(), colorValues[ndx].z(), colorValues[ndx].w())); 458 GLU_CHECK_GLW_CALL(gl, clear(GL_COLOR_BUFFER_BIT)); 459 460 tcu::clear(tcu::getSubregion(ref.getLevel(0), 0, 0, size.x(), size.y()), colorValues[ndx]); 461 } 462 463 GLU_CHECK_GLW_CALL(gl, disable(GL_SCISSOR_TEST)); 464 GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 465 GL_RENDERBUFFER, 0)); 466 } 467 468 MovePtr<ClientBuffer> RenderbufferImageSource::createBuffer (const glw::Functions& gl, Texture2D* ref) const 469 { 470 MovePtr<RenderbufferClientBuffer> buffer (new RenderbufferClientBuffer(gl)); 471 const GLuint rbo = buffer->getName(); 472 473 GLU_CHECK_CALL_ERROR(gl.bindRenderbuffer(GL_RENDERBUFFER, rbo), gl.getError()); 474 475 // Specify storage. 476 GLU_CHECK_CALL_ERROR(gl.renderbufferStorage(GL_RENDERBUFFER, m_format, 64, 64), gl.getError()); 477 478 if (ref != DE_NULL) 479 { 480 Framebuffer fbo (gl); 481 const TextureFormat texFormat = glu::mapGLInternalFormat(m_format); 482 483 *ref = tcu::Texture2D(texFormat, 64, 64); 484 ref->allocLevel(0); 485 486 gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo); 487 switch (m_format) 488 { 489 case GL_STENCIL_INDEX8: 490 initializeStencilRbo(gl, rbo, *ref); 491 break; 492 case GL_DEPTH_COMPONENT16: 493 initializeDepthRbo(gl, rbo, *ref); 494 break; 495 case GL_RGBA4: 496 initializeColorRbo(gl, rbo, *ref); 497 break; 498 case GL_RGB5_A1: 499 initializeColorRbo(gl, rbo, *ref); 500 break; 501 case GL_RGB565: 502 initializeColorRbo(gl, rbo, *ref); 503 break; 504 default: 505 DE_FATAL("Impossible"); 506 } 507 508 gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 509 } 510 511 return MovePtr<ClientBuffer>(buffer); 512 } 513 514 class UnsupportedImageSource : public ImageSource 515 { 516 public: 517 UnsupportedImageSource (const string& message, GLenum format) : m_message(message), m_format(format) {} 518 string getRequiredExtension (void) const { fail(); return ""; } 519 MovePtr<ClientBuffer> createBuffer (const glw::Functions&, tcu::Texture2D*) const { fail(); return de::MovePtr<ClientBuffer>(); } 520 EGLImageKHR createImage (const Library& egl, EGLDisplay dpy, EGLContext ctx, EGLClientBuffer clientBuffer) const; 521 GLenum getEffectiveFormat (void) const { return m_format; } 522 523 private: 524 const string m_message; 525 GLenum m_format; 526 527 void fail (void) const { TCU_THROW(NotSupportedError, m_message.c_str()); } 528 }; 529 530 EGLImageKHR UnsupportedImageSource::createImage (const Library&, EGLDisplay, EGLContext, EGLClientBuffer) const 531 { 532 fail(); 533 return EGL_NO_IMAGE_KHR; 534 } 535 536 MovePtr<ImageSource> createTextureImageSource (EGLenum source, GLenum internalFormat, GLenum format, GLenum type, bool useTexLevel0) 537 { 538 if (source == EGL_GL_TEXTURE_2D_KHR) 539 return MovePtr<ImageSource>(new Texture2DImageSource(internalFormat, format, type, useTexLevel0)); 540 else 541 return MovePtr<ImageSource>(new TextureCubeMapImageSource(source, internalFormat, format, type, useTexLevel0)); 542 } 543 544 MovePtr<ImageSource> createRenderbufferImageSource (GLenum format) 545 { 546 return MovePtr<ImageSource>(new RenderbufferImageSource(format)); 547 } 548 549 MovePtr<ImageSource> createUnsupportedImageSource (const string& message, GLenum format) 550 { 551 return MovePtr<ImageSource>(new UnsupportedImageSource(message, format)); 552 } 553 554 } // Image 555 } // egl 556 } // deqp 557