Home | History | Annotate | Download | only in egl
      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 #include "teglImageFormatTests.hpp"
     24 
     25 #include "tcuTestLog.hpp"
     26 #include "tcuSurface.hpp"
     27 #include "tcuTexture.hpp"
     28 #include "tcuTextureUtil.hpp"
     29 #include "tcuImageCompare.hpp"
     30 #include "tcuCommandLine.hpp"
     31 
     32 #include "egluNativeDisplay.hpp"
     33 #include "egluNativeWindow.hpp"
     34 #include "egluNativePixmap.hpp"
     35 #include "egluConfigFilter.hpp"
     36 #include "egluUtil.hpp"
     37 
     38 #include "gluTexture.hpp"
     39 #include "gluPixelTransfer.hpp"
     40 #include "gluTextureUtil.hpp"
     41 
     42 #include <GLES2/gl2.h>
     43 #include <GLES2/gl2ext.h>
     44 #include <EGL/eglext.h>
     45 
     46 #include <vector>
     47 #include <string>
     48 #include <set>
     49 
     50 using std::vector;
     51 using std::set;
     52 using std::string;
     53 
     54 namespace deqp
     55 {
     56 namespace egl
     57 {
     58 
     59 namespace
     60 {
     61 
     62 // \todo [2013-04-09 pyry] Use glu::Program
     63 class Program
     64 {
     65 public:
     66 	Program (const char* vertexSource, const char* fragmentSource)
     67 		: m_program			(0)
     68 		, m_vertexShader	(0)
     69 		, m_fragmentShader	(0)
     70 		, m_isOk			(false)
     71 	{
     72 		m_program			= glCreateProgram();
     73 		m_vertexShader		= glCreateShader(GL_VERTEX_SHADER);
     74 		m_fragmentShader	= glCreateShader(GL_FRAGMENT_SHADER);
     75 
     76 		try
     77 		{
     78 			bool	vertexCompileOk		= false;
     79 			bool	fragmentCompileOk	= false;
     80 			bool	linkOk				= false;
     81 
     82 			for (int ndx = 0; ndx < 2; ndx++)
     83 			{
     84 				const char*		source			= ndx ? fragmentSource		: vertexSource;
     85 				const deUint32	shader			= ndx ? m_fragmentShader	: m_vertexShader;
     86 				int				compileStatus	= 0;
     87 				bool&			compileOk		= ndx ? fragmentCompileOk	: vertexCompileOk;
     88 
     89 				glShaderSource(shader, 1, &source, DE_NULL);
     90 				glCompileShader(shader);
     91 				glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
     92 
     93 				compileOk = (compileStatus == GL_TRUE);
     94 			}
     95 
     96 			if (vertexCompileOk && fragmentCompileOk)
     97 			{
     98 				int linkStatus = 0;
     99 
    100 				glAttachShader(m_program, m_vertexShader);
    101 				glAttachShader(m_program, m_fragmentShader);
    102 				glLinkProgram(m_program);
    103 				glGetProgramiv(m_program, GL_LINK_STATUS, &linkStatus);
    104 
    105 				linkOk = (linkStatus == GL_TRUE);
    106 			}
    107 
    108 			m_isOk = linkOk;
    109 		}
    110 		catch (...)
    111 		{
    112 			glDeleteShader(m_vertexShader);
    113 			glDeleteShader(m_fragmentShader);
    114 			glDeleteProgram(m_program);
    115 			throw;
    116 		}
    117 	}
    118 
    119 	~Program (void)
    120 	{
    121 		glDeleteShader(m_vertexShader);
    122 		glDeleteShader(m_fragmentShader);
    123 		glDeleteProgram(m_program);
    124 	}
    125 
    126 	bool			isOk			(void) const { return m_isOk;	}
    127 	deUint32		getProgram		(void) const {return m_program;	}
    128 
    129 private:
    130 	deUint32		m_program;
    131 	deUint32		m_vertexShader;
    132 	deUint32		m_fragmentShader;
    133 	bool			m_isOk;
    134 };
    135 
    136 } // anonymous
    137 
    138 namespace Image
    139 {
    140 
    141 class EglExt
    142 {
    143 public:
    144 	EglExt (void)
    145 	{
    146 		eglCreateImageKHR						= (PFNEGLCREATEIMAGEKHRPROC)						eglGetProcAddress("eglCreateImageKHR");
    147 		eglDestroyImageKHR						= (PFNEGLDESTROYIMAGEKHRPROC)						eglGetProcAddress("eglDestroyImageKHR");
    148 
    149 		glEGLImageTargetTexture2DOES			= (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)				eglGetProcAddress("glEGLImageTargetTexture2DOES");
    150 		glEGLImageTargetRenderbufferStorageOES	= (PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC)	eglGetProcAddress("glEGLImageTargetRenderbufferStorageOES");
    151 	}
    152 
    153 	PFNEGLCREATEIMAGEKHRPROC						eglCreateImageKHR;
    154 	PFNEGLDESTROYIMAGEKHRPROC						eglDestroyImageKHR;
    155 
    156 	PFNGLEGLIMAGETARGETTEXTURE2DOESPROC				glEGLImageTargetTexture2DOES;
    157 	PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC	glEGLImageTargetRenderbufferStorageOES;
    158 
    159 private:
    160 };
    161 
    162 struct TestSpec
    163 {
    164 	std::string name;
    165 	std::string desc;
    166 
    167 	enum ApiContext
    168 	{
    169 		API_GLES2 = 0,
    170 		//API_VG
    171 		//API_GLES1
    172 
    173 		API_LAST
    174 	};
    175 
    176 	struct Operation
    177 	{
    178 		enum Type
    179 		{
    180 				TYPE_CREATE = 0,
    181 				TYPE_RENDER,
    182 				TYPE_MODIFY,
    183 
    184 				TYPE_LAST
    185 		};
    186 
    187 		ApiContext	requiredApi;
    188 		int			apiIndex;
    189 		Type		type;
    190 		int			operationIndex;
    191 	};
    192 
    193 	vector<ApiContext>	contexts;
    194 	vector<Operation>	operations;
    195 
    196 };
    197 
    198 class ImageApi
    199 {
    200 public:
    201 							ImageApi				(int contextId, tcu::TestLog& log, tcu::egl::Display& display, tcu::egl::Surface* surface);
    202 	virtual 				~ImageApi				(void) {}
    203 
    204 	virtual EGLImageKHR		create					(int operationNdx, tcu::Texture2D& ref) = 0;
    205 	virtual bool			render					(int operationNdx, EGLImageKHR img, const tcu::Texture2D& reference) = 0;
    206 	virtual void			modify					(int operationNdx, EGLImageKHR img, tcu::Texture2D& reference) = 0;
    207 
    208 	virtual void			checkRequiredExtensions	(set<string>& extensions, TestSpec::Operation::Type type, int operationNdx) = 0;
    209 
    210 protected:
    211 	int						m_contextId;
    212 	tcu::TestLog&			m_log;
    213 	tcu::egl::Display&		m_display;
    214 	tcu::egl::Surface*		m_surface;
    215 };
    216 
    217 ImageApi::ImageApi (int contextId, tcu::TestLog& log, tcu::egl::Display& display, tcu::egl::Surface* surface)
    218 	: m_contextId		(contextId)
    219 	, m_log				(log)
    220 	, m_display			(display)
    221 	, m_surface			(surface)
    222 {
    223 }
    224 
    225 class GLES2ImageApi : public ImageApi
    226 {
    227 public:
    228 	enum Create
    229 	{
    230 		CREATE_TEXTURE2D_RGB8 = 0,
    231 		CREATE_TEXTURE2D_RGB565,
    232 		CREATE_TEXTURE2D_RGBA8,
    233 		CREATE_TEXTURE2D_RGBA5_A1,
    234 		CREATE_TEXTURE2D_RGBA4,
    235 
    236 		CREATE_CUBE_MAP_POSITIVE_X_RGBA8,
    237 		CREATE_CUBE_MAP_NEGATIVE_X_RGBA8,
    238 		CREATE_CUBE_MAP_POSITIVE_Y_RGBA8,
    239 		CREATE_CUBE_MAP_NEGATIVE_Y_RGBA8,
    240 		CREATE_CUBE_MAP_POSITIVE_Z_RGBA8,
    241 		CREATE_CUBE_MAP_NEGATIVE_Z_RGBA8,
    242 
    243 		CREATE_CUBE_MAP_POSITIVE_X_RGB8,
    244 		CREATE_CUBE_MAP_NEGATIVE_X_RGB8,
    245 		CREATE_CUBE_MAP_POSITIVE_Y_RGB8,
    246 		CREATE_CUBE_MAP_NEGATIVE_Y_RGB8,
    247 		CREATE_CUBE_MAP_POSITIVE_Z_RGB8,
    248 		CREATE_CUBE_MAP_NEGATIVE_Z_RGB8,
    249 
    250 		CREATE_RENDER_BUFFER_DEPTH16,
    251 		CREATE_RENDER_BUFFER_RGBA4,
    252 		CREATE_RENDER_BUFFER_RGB5_A1,
    253 		CREATE_RENDER_BUFFER_RGB565,
    254 		CREATE_RENDER_BUFFER_STENCIL,
    255 
    256 		CREATE_LAST
    257 	};
    258 
    259 	enum Render
    260 	{
    261 		RENDER_TEXTURE2D = 0,
    262 
    263 		// \note Not supported
    264 		RENDER_CUBE_MAP_POSITIVE_X,
    265 		RENDER_CUBE_MAP_NEGATIVE_X,
    266 		RENDER_CUBE_MAP_POSITIVE_Y,
    267 		RENDER_CUBE_MAP_NEGATIVE_Y,
    268 		RENDER_CUBE_MAP_POSITIVE_Z,
    269 		RENDER_CUBE_MAP_NEGATIVE_Z,
    270 
    271 		RENDER_READ_PIXELS_RENDERBUFFER,
    272 		RENDER_DEPTHBUFFER,
    273 
    274 		RENDER_TRY_ALL,
    275 
    276 		RENDER_LAST
    277 	};
    278 
    279 	enum Modify
    280 	{
    281 		MODIFY_TEXSUBIMAGE_RGBA8,
    282 		MODIFY_TEXSUBIMAGE_RGBA5_A1,
    283 		MODIFY_TEXSUBIMAGE_RGBA4,
    284 		MODIFY_TEXSUBIMAGE_RGB8,
    285 		MODIFY_TEXSUBIMAGE_RGB565,
    286 		MODIFY_RENDERBUFFER_CLEAR_COLOR,
    287 		MODIFY_RENDERBUFFER_CLEAR_DEPTH,
    288 		MODIFY_RENDERBUFFER_CLEAR_STENCIL,
    289 
    290 		MODIFY_LAST
    291 	};
    292 
    293 					GLES2ImageApi					(int contextId, tcu::TestLog& log, tcu::egl::Display& display, tcu::egl::Surface* surface, EGLConfig config);
    294 					~GLES2ImageApi					(void);
    295 
    296 	EGLImageKHR		create							(int operationNdx, tcu::Texture2D& ref);
    297 	EGLImageKHR		createTexture2D					(tcu::Texture2D& ref, GLenum target, GLenum format, GLenum type);
    298 	EGLImageKHR		createRenderBuffer				(tcu::Texture2D& ref, GLenum type);
    299 
    300 	bool			render							(int operationNdx, EGLImageKHR img, const tcu::Texture2D& reference);
    301 	bool			renderTexture2D					(EGLImageKHR img, const tcu::Texture2D& reference);
    302 	bool			renderDepth						(EGLImageKHR img, const tcu::Texture2D& reference);
    303 	bool			renderReadPixelsRenderBuffer	(EGLImageKHR img, const tcu::Texture2D& reference);
    304 	bool			renderTryAll					(EGLImageKHR img, const tcu::Texture2D& reference);
    305 
    306 	// \note Not supported
    307 	bool			renderCubeMap					(EGLImageKHR img, const tcu::Surface& reference, GLenum face);
    308 
    309 	void			modify							(int operationNdx, EGLImageKHR img, tcu::Texture2D& reference);
    310 	void			modifyTexSubImage				(EGLImageKHR img, tcu::Texture2D& reference, GLenum format, GLenum type);
    311 	void			modifyRenderbufferClearColor	(EGLImageKHR img, tcu::Texture2D& reference);
    312 	void			modifyRenderbufferClearDepth	(EGLImageKHR img, tcu::Texture2D& reference);
    313 	void			modifyRenderbufferClearStencil	(EGLImageKHR img, tcu::Texture2D& reference);
    314 
    315 	void			checkRequiredExtensions			(set<string>& extensions, TestSpec::Operation::Type type, int operationNdx);
    316 
    317 private:
    318 	tcu::egl::Context*	m_context;
    319 	EglExt				m_eglExt;
    320 };
    321 
    322 GLES2ImageApi::GLES2ImageApi (int contextId, tcu::TestLog& log, tcu::egl::Display& display, tcu::egl::Surface* surface, EGLConfig config)
    323 	: ImageApi	(contextId, log, display, surface)
    324 	, m_context	(DE_NULL)
    325 {
    326 	EGLint attriblist[] =
    327 	{
    328 		EGL_CONTEXT_CLIENT_VERSION, 2,
    329 		EGL_NONE
    330 	};
    331 
    332 	EGLint configId = -1;
    333 	TCU_CHECK_EGL_CALL(eglGetConfigAttrib(m_display.getEGLDisplay(), config, EGL_CONFIG_ID, &configId));
    334 	m_log << tcu::TestLog::Message << "Creating gles2 context with config id: " << configId << " context: " << m_contextId << tcu::TestLog::EndMessage;
    335 	m_context = new tcu::egl::Context(m_display, config, attriblist, EGL_OPENGL_ES_API);
    336 	TCU_CHECK_EGL_MSG("Failed to create GLES2 context");
    337 
    338 	m_context->makeCurrent(*m_surface, *m_surface);
    339 	TCU_CHECK_EGL_MSG("Failed to make context current");
    340 }
    341 
    342 GLES2ImageApi::~GLES2ImageApi (void)
    343 {
    344 	delete m_context;
    345 }
    346 
    347 EGLImageKHR GLES2ImageApi::create (int operationNdx, tcu::Texture2D& ref)
    348 {
    349 	m_context->makeCurrent(*m_surface, *m_surface);
    350 	EGLImageKHR	img = EGL_NO_IMAGE_KHR;
    351 	switch (operationNdx)
    352 	{
    353 		case CREATE_TEXTURE2D_RGB8:				img = createTexture2D(ref, GL_TEXTURE_2D, GL_RGB,	GL_UNSIGNED_BYTE);			break;
    354 		case CREATE_TEXTURE2D_RGB565:			img = createTexture2D(ref, GL_TEXTURE_2D, GL_RGB,	GL_UNSIGNED_SHORT_5_6_5);	break;
    355 		case CREATE_TEXTURE2D_RGBA8:			img = createTexture2D(ref, GL_TEXTURE_2D, GL_RGBA,	GL_UNSIGNED_BYTE);			break;
    356 		case CREATE_TEXTURE2D_RGBA4:			img = createTexture2D(ref, GL_TEXTURE_2D, GL_RGBA,	GL_UNSIGNED_SHORT_4_4_4_4);	break;
    357 		case CREATE_TEXTURE2D_RGBA5_A1:			img = createTexture2D(ref, GL_TEXTURE_2D, GL_RGBA,	GL_UNSIGNED_SHORT_5_5_5_1);	break;
    358 
    359 		case CREATE_CUBE_MAP_POSITIVE_X_RGBA8:	img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_RGBA, GL_UNSIGNED_BYTE); break;
    360 		case CREATE_CUBE_MAP_NEGATIVE_X_RGBA8:	img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_RGBA, GL_UNSIGNED_BYTE); break;
    361 		case CREATE_CUBE_MAP_POSITIVE_Y_RGBA8:	img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_RGBA, GL_UNSIGNED_BYTE); break;
    362 		case CREATE_CUBE_MAP_NEGATIVE_Y_RGBA8:	img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_RGBA, GL_UNSIGNED_BYTE); break;
    363 		case CREATE_CUBE_MAP_POSITIVE_Z_RGBA8:	img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_RGBA, GL_UNSIGNED_BYTE); break;
    364 		case CREATE_CUBE_MAP_NEGATIVE_Z_RGBA8:	img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_RGBA, GL_UNSIGNED_BYTE); break;
    365 
    366 		case CREATE_CUBE_MAP_POSITIVE_X_RGB8:	img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_RGB, GL_UNSIGNED_BYTE); break;
    367 		case CREATE_CUBE_MAP_NEGATIVE_X_RGB8:	img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_RGB, GL_UNSIGNED_BYTE); break;
    368 		case CREATE_CUBE_MAP_POSITIVE_Y_RGB8:	img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_RGB, GL_UNSIGNED_BYTE); break;
    369 		case CREATE_CUBE_MAP_NEGATIVE_Y_RGB8:	img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_RGB, GL_UNSIGNED_BYTE); break;
    370 		case CREATE_CUBE_MAP_POSITIVE_Z_RGB8:	img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_RGB, GL_UNSIGNED_BYTE); break;
    371 		case CREATE_CUBE_MAP_NEGATIVE_Z_RGB8:	img = createTexture2D(ref, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, GL_RGB, GL_UNSIGNED_BYTE); break;
    372 
    373 		case CREATE_RENDER_BUFFER_DEPTH16:		img = createRenderBuffer(ref, GL_DEPTH_COMPONENT16);	break;
    374 		case CREATE_RENDER_BUFFER_RGBA4:		img = createRenderBuffer(ref, GL_RGBA4);				break;
    375 		case CREATE_RENDER_BUFFER_RGB5_A1:		img = createRenderBuffer(ref, GL_RGB5_A1);				break;
    376 		case CREATE_RENDER_BUFFER_RGB565:		img = createRenderBuffer(ref, GL_RGB565);				break;
    377 		case CREATE_RENDER_BUFFER_STENCIL:		img = createRenderBuffer(ref, GL_STENCIL_INDEX8);		break;
    378 
    379 		default:
    380 			DE_ASSERT(false);
    381 			break;
    382 	}
    383 
    384 	return img;
    385 }
    386 
    387 namespace
    388 {
    389 
    390 const char* glTargetToString (GLenum target)
    391 {
    392 	switch (target)
    393 	{
    394 		case GL_TEXTURE_2D: return "GL_TEXTURE_2D";
    395 		break;
    396 		case GL_TEXTURE_CUBE_MAP_POSITIVE_X: return "GL_TEXTURE_CUBE_MAP_POSITIVE_X";
    397 		break;
    398 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: return "GL_TEXTURE_CUBE_MAP_NEGATIVE_X";
    399 		break;
    400 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: return "GL_TEXTURE_CUBE_MAP_POSITIVE_Y";
    401 		break;
    402 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y";
    403 		break;
    404 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: return "GL_TEXTURE_CUBE_MAP_POSITIVE_Z";
    405 		break;
    406 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z";
    407 		break;
    408 		default:
    409 			DE_ASSERT(false);
    410 		break;
    411 	};
    412 	return "";
    413 }
    414 
    415 const char* glFormatToString (GLenum format)
    416 {
    417 	switch (format)
    418 	{
    419 		case GL_RGB:
    420 			return "GL_RGB";
    421 
    422 		case GL_RGBA:
    423 			return "GL_RGBA";
    424 
    425 		default:
    426 			DE_ASSERT(false);
    427 			return "";
    428 	}
    429 }
    430 
    431 const char* glTypeToString (GLenum type)
    432 {
    433 	switch (type)
    434 	{
    435 		case GL_UNSIGNED_BYTE:
    436 			return "GL_UNSIGNED_BYTE";
    437 
    438 		case GL_UNSIGNED_SHORT_5_6_5:
    439 			return "GL_UNSIGNED_SHORT_5_6_5";
    440 
    441 		case GL_UNSIGNED_SHORT_4_4_4_4:
    442 			return "GL_UNSIGNED_SHORT_4_4_4_4";
    443 
    444 		case GL_UNSIGNED_SHORT_5_5_5_1:
    445 			return "GL_UNSIGNED_SHORT_5_5_5_1";
    446 
    447 		default:
    448 			DE_ASSERT(false);
    449 			return "";
    450 	}
    451 }
    452 
    453 } // anonymous
    454 
    455 EGLImageKHR	GLES2ImageApi::createTexture2D (tcu::Texture2D& reference, GLenum target, GLenum format, GLenum type)
    456 {
    457 	tcu::Texture2D src(glu::mapGLTransferFormat(format, type), 64, 64);
    458 	src.allocLevel(0);
    459 
    460 	tcu::fillWithComponentGradients(src.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    461 	m_log << tcu::TestLog::Message << "Creating EGLImage from " << glTargetToString(target) << " " << glFormatToString(format) << " " << glTypeToString(type) << " in context: " << m_contextId << tcu::TestLog::EndMessage;
    462 
    463 	deUint32 srcTex = 0;
    464 	glGenTextures(1, &srcTex);
    465 	TCU_CHECK(srcTex != 0);
    466 	if (GL_TEXTURE_2D == target)
    467 	{
    468 		GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, srcTex));
    469 		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
    470 		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
    471 		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
    472 		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
    473 		GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_2D, 0, format, src.getWidth(), src.getHeight(), 0, format, type, src.getLevel(0).getDataPtr()));
    474 	}
    475 	else
    476 	{
    477 		GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, srcTex));
    478 		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
    479 		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
    480 		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
    481 		GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
    482 
    483 		// First fill all faces, required by eglCreateImageKHR
    484 		GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format, src.getWidth(), src.getHeight(), 0, format, type, 0));
    485 		GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, format, src.getWidth(), src.getHeight(), 0, format, type, 0));
    486 		GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, format, src.getWidth(), src.getHeight(), 0, format, type, 0));
    487 		GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, format, src.getWidth(), src.getHeight(), 0, format, type, 0));
    488 		GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, format, src.getWidth(), src.getHeight(), 0, format, type, 0));
    489 		GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, format, src.getWidth(), src.getHeight(), 0, format, type, 0));
    490 		GLU_CHECK_CALL(glTexImage2D(target, 0, format, src.getWidth(), src.getHeight(), 0, format, type, src.getLevel(0).getDataPtr()));
    491 	}
    492 
    493 	EGLint attrib[] = {
    494 		EGL_GL_TEXTURE_LEVEL_KHR, 0,
    495 		EGL_NONE
    496 	};
    497 
    498 	EGLImageKHR img = EGL_NO_IMAGE_KHR;
    499 
    500 	if (GL_TEXTURE_2D == target)
    501 	{
    502 		img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)(deUintptr)srcTex, attrib);
    503 	}
    504 	else
    505 	{
    506 		switch (target)
    507 		{
    508 			case GL_TEXTURE_CUBE_MAP_POSITIVE_X: img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR, (EGLClientBuffer)(deUintptr)srcTex, attrib); break;
    509 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR, (EGLClientBuffer)(deUintptr)srcTex, attrib); break;
    510 			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR, (EGLClientBuffer)(deUintptr)srcTex, attrib); break;
    511 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR, (EGLClientBuffer)(deUintptr)srcTex, attrib); break;
    512 			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR, (EGLClientBuffer)(deUintptr)srcTex, attrib); break;
    513 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR, (EGLClientBuffer)(deUintptr)srcTex, attrib); break;
    514 
    515 			default:
    516 				DE_ASSERT(false);
    517 				break;
    518 		}
    519 	}
    520 
    521 	GLU_CHECK_CALL(glDeleteTextures(1, &srcTex));
    522 	TCU_CHECK_EGL_MSG("Failed to create EGLImage");
    523 	TCU_CHECK_MSG(img != EGL_NO_IMAGE_KHR, "Failed to create EGLImage, got EGL_NO_IMAGE_KHR");
    524 	glBindTexture(GL_TEXTURE_2D, 0);
    525 
    526 	reference = src;
    527 
    528 	return img;
    529 }
    530 
    531 static std::string glRenderbufferTargetToString (GLenum format)
    532 {
    533 	switch (format)
    534 	{
    535 		case GL_RGBA4:
    536 			return "GL_RGBA4";
    537 			break;
    538 
    539 		case GL_RGB5_A1:
    540 			return "GL_RGB5_A1";
    541 			break;
    542 
    543 		case GL_RGB565:
    544 			return "GL_RGB565";
    545 			break;
    546 
    547 		case GL_DEPTH_COMPONENT16:
    548 			return "GL_DEPTH_COMPONENT16";
    549 			break;
    550 
    551 		case GL_STENCIL_INDEX8:
    552 			return "GL_STENCIL_INDEX8";
    553 			break;
    554 
    555 		default:
    556 			DE_ASSERT(false);
    557 			break;
    558 	}
    559 
    560 	DE_ASSERT(false);
    561 	return "";
    562 }
    563 
    564 EGLImageKHR GLES2ImageApi::createRenderBuffer (tcu::Texture2D& ref, GLenum format)
    565 {
    566 	m_log << tcu::TestLog::Message << "Creating EGLImage from GL_RENDERBUFFER " << glRenderbufferTargetToString(format) << " " << " in context: " << m_contextId << tcu::TestLog::EndMessage;
    567 	GLuint renderBuffer = 1;
    568 
    569 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer));
    570 	GLU_CHECK_CALL(glRenderbufferStorage(GL_RENDERBUFFER, format, 64, 64));
    571 
    572 	GLuint frameBuffer = 1;
    573 	GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer));
    574 
    575 	switch (format)
    576 	{
    577 		case GL_STENCIL_INDEX8:
    578 			GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBuffer));
    579 			TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
    580 			GLU_CHECK_CALL(glClearStencil(235));
    581 			GLU_CHECK_CALL(glClear(GL_STENCIL_BUFFER_BIT));
    582 			GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0));
    583 			ref = tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::I, tcu::TextureFormat::UNORM_INT8),  64, 64);
    584 			ref.allocLevel(0);
    585 
    586 			for (int x = 0; x < 64; x++)
    587 			{
    588 				for (int y = 0; y < 64; y++)
    589 				{
    590 					ref.getLevel(0).setPixel(tcu::IVec4(235, 235, 235, 235), x, y);
    591 				}
    592 			}
    593 			break;
    594 
    595 		case GL_DEPTH_COMPONENT16:
    596 			GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffer));
    597 			TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
    598 			GLU_CHECK_CALL(glClearDepthf(0.5f));
    599 			GLU_CHECK_CALL(glClear(GL_DEPTH_BUFFER_BIT));
    600 			GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0));
    601 			ref = tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::I, tcu::TextureFormat::UNORM_INT16),  64, 64);
    602 			ref.allocLevel(0);
    603 
    604 			for (int x = 0; x < 64; x++)
    605 			{
    606 				for (int y = 0; y < 64; y++)
    607 				{
    608 					ref.getLevel(0).setPixel(tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), x, y);
    609 				}
    610 			}
    611 			break;
    612 
    613 		case GL_RGBA4:
    614 			GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBuffer));
    615 			TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
    616 			GLU_CHECK_CALL(glClearColor(0.9f, 0.5f, 0.65f, 1.0f));
    617 			GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
    618 			GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0));
    619 			ref = tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_SHORT_4444),  64, 64);
    620 			ref.allocLevel(0);
    621 
    622 			for (int x = 0; x < 64; x++)
    623 			{
    624 				for (int y = 0; y < 64; y++)
    625 				{
    626 					ref.getLevel(0).setPixel(tcu::Vec4(0.9f, 0.5f, 0.65f, 1.0f), x, y);
    627 				}
    628 			}
    629 			break;
    630 
    631 		case GL_RGB5_A1:
    632 			GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBuffer));
    633 			TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
    634 			GLU_CHECK_CALL(glClearColor(0.5f, 0.7f, 0.65f, 1.0f));
    635 			GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
    636 			GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0));
    637 			ref = tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_SHORT_5551),  64, 64);
    638 			ref.allocLevel(0);
    639 
    640 			for (int x = 0; x < 64; x++)
    641 			{
    642 				for (int y = 0; y < 64; y++)
    643 				{
    644 					ref.getLevel(0).setPixel(tcu::Vec4(0.5f, 0.7f, 0.65f, 1.0f), x, y);
    645 				}
    646 			}
    647 			break;
    648 
    649 		case GL_RGB565:
    650 			GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBuffer));
    651 			TCU_CHECK(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
    652 			GLU_CHECK_CALL(glClearColor(0.2f, 0.5f, 0.65f, 1.0f));
    653 			GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
    654 			GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0));
    655 			ref = tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_SHORT_565),  64, 64);
    656 			ref.allocLevel(0);
    657 
    658 			for (int x = 0; x < 64; x++)
    659 			{
    660 				for (int y = 0; y < 64; y++)
    661 				{
    662 					ref.getLevel(0).setPixel(tcu::Vec4(0.2f, 0.5f, 0.65f, 1.0f), x, y);
    663 				}
    664 			}
    665 			break;
    666 
    667 		default:
    668 			DE_ASSERT(false);
    669 	}
    670 
    671 	GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
    672 	GLU_CHECK_CALL(glDeleteFramebuffers(1, &frameBuffer));
    673 
    674 	EGLint attrib[] = {
    675 		EGL_NONE
    676 	};
    677 
    678 	EGLImageKHR img = m_eglExt.eglCreateImageKHR(m_display.getEGLDisplay(), m_context->getEGLContext(), EGL_GL_RENDERBUFFER_KHR, (EGLClientBuffer)(deUintptr)renderBuffer, attrib);
    679 
    680 	GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderBuffer));
    681 	return img;
    682 }
    683 
    684 bool GLES2ImageApi::render (int operationNdx, EGLImageKHR img, const tcu::Texture2D& reference)
    685 {
    686 	m_context->makeCurrent(*m_surface, *m_surface);
    687 	switch (operationNdx)
    688 	{
    689 		case RENDER_TEXTURE2D:
    690 			return renderTexture2D(img, reference);
    691 
    692 		case RENDER_READ_PIXELS_RENDERBUFFER:
    693 			return renderReadPixelsRenderBuffer(img, reference);
    694 
    695 		case RENDER_DEPTHBUFFER:
    696 			return renderDepth(img, reference);
    697 
    698 		case RENDER_TRY_ALL:
    699 			return renderTryAll(img, reference);
    700 
    701 		default:
    702 			DE_ASSERT(false);
    703 			break;
    704 	};
    705 	return false;
    706 }
    707 
    708 bool GLES2ImageApi::renderTexture2D (EGLImageKHR img, const tcu::Texture2D& reference)
    709 {
    710 	glClearColor(0.0, 0.0, 0.0, 0.0);
    711 	glViewport(0, 0, reference.getWidth(), reference.getHeight());
    712 	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    713 	glDisable(GL_DEPTH_TEST);
    714 
    715 	m_log << tcu::TestLog::Message << "Rendering EGLImage as GL_TEXTURE_2D in context: " << m_contextId << tcu::TestLog::EndMessage;
    716 	TCU_CHECK(img != EGL_NO_IMAGE_KHR);
    717 
    718 	deUint32 srcTex = 0;
    719 	glGenTextures(1, &srcTex);
    720 	TCU_CHECK(srcTex != 0);
    721 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, srcTex));
    722 	m_eglExt.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)img);
    723 	GLenum error = glGetError();
    724 
    725 	if (error == GL_INVALID_OPERATION)
    726 	{
    727 		GLU_CHECK_CALL(glDeleteTextures(1, &srcTex));
    728 		throw tcu::NotSupportedError("Creating texture2D from EGLImage type not supported", "glEGLImageTargetTexture2DOES", __FILE__, __LINE__);
    729 	}
    730 
    731 	TCU_CHECK(error == GL_NONE);
    732 
    733 	TCU_CHECK_EGL_MSG("glEGLImageTargetTexture2DOES() failed");
    734 
    735 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
    736 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
    737 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
    738 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
    739 
    740 	const char* vertexShader =
    741 		"attribute highp vec2 a_coord;\n"
    742 		"varying mediump vec2 v_texCoord;\n"
    743 		"void main(void) {\n"
    744 		"\tv_texCoord = vec2((a_coord.x + 1.0) * 0.5, (a_coord.y + 1.0) * 0.5);\n"
    745 		"\tgl_Position = vec4(a_coord, -0.1, 1.0);\n"
    746 		"}\n";
    747 
    748 	const char* fragmentShader =
    749 		"varying mediump vec2 v_texCoord;\n"
    750 		"uniform sampler2D u_sampler;\n"
    751 		"void main(void) {\n"
    752 		"\tmediump vec4 texColor = texture2D(u_sampler, v_texCoord);\n"
    753 		"\tgl_FragColor = vec4(texColor);\n"
    754 		"}";
    755 
    756 	Program program(vertexShader, fragmentShader);
    757 	TCU_CHECK(program.isOk());
    758 
    759 	GLuint glProgram = program.getProgram();
    760 	GLU_CHECK_CALL(glUseProgram(glProgram));
    761 
    762 	GLuint coordLoc = glGetAttribLocation(glProgram, "a_coord");
    763 	TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
    764 
    765 	GLuint samplerLoc = glGetUniformLocation(glProgram, "u_sampler");
    766 	TCU_CHECK_MSG((int)samplerLoc != (int)-1, "Couldn't find uniform u_sampler");
    767 
    768 	float coords[] =
    769 	{
    770 		-1.0, -1.0,
    771 		1.0, -1.0,
    772 		1.0,  1.0,
    773 
    774 		1.0,  1.0,
    775 		-1.0,  1.0,
    776 		-1.0, -1.0
    777 	};
    778 
    779 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, srcTex));
    780 	GLU_CHECK_CALL(glUniform1i(samplerLoc, 0));
    781 	GLU_CHECK_CALL(glEnableVertexAttribArray(coordLoc));
    782 	GLU_CHECK_CALL(glVertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, coords));
    783 
    784 	GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 6));
    785 	GLU_CHECK_CALL(glDisableVertexAttribArray(coordLoc));
    786 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, 0));
    787 	GLU_CHECK_CALL(glDeleteTextures(1, &srcTex));
    788 
    789 	tcu::Surface screen(reference.getWidth(), reference.getHeight());
    790 	glReadPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr());
    791 	GLU_CHECK_MSG("glReadPixels()");
    792 
    793 	tcu::Surface referenceScreen(reference.getWidth(), reference.getHeight());
    794 
    795 	for (int y = 0; y < referenceScreen.getHeight(); y++)
    796 	{
    797 		for (int x = 0; x < referenceScreen.getWidth(); x++)
    798 		{
    799 			tcu::Vec4 src = reference.getLevel(0).getPixel(x, y);
    800 			referenceScreen.setPixel(x, y, tcu::RGBA(src));
    801 		}
    802 	}
    803 
    804 	float	threshold	= 0.05f;
    805 	bool	match		= tcu::fuzzyCompare(m_log, "ComparisonResult", "Image comparison result", referenceScreen, screen, threshold, tcu::COMPARE_LOG_RESULT);
    806 
    807 	return match;
    808 }
    809 
    810 bool GLES2ImageApi::renderDepth (EGLImageKHR img, const tcu::Texture2D& reference)
    811 {
    812 	m_log << tcu::TestLog::Message << "Rendering with depth buffer" << tcu::TestLog::EndMessage;
    813 
    814 	deUint32 framebuffer;
    815 	glGenFramebuffers(1, &framebuffer);
    816 	TCU_CHECK(framebuffer != (GLuint)-1);
    817 	GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
    818 
    819 	deUint32 renderbufferColor = 0;
    820 	glGenRenderbuffers(1, &renderbufferColor);
    821 	TCU_CHECK(renderbufferColor != (GLuint)-1);
    822 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbufferColor));
    823 	GLU_CHECK_CALL(glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, reference.getWidth(), reference.getHeight()));
    824 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
    825 
    826 	deUint32 renderbufferDepth = 0;
    827 	glGenRenderbuffers(1, &renderbufferDepth);
    828 	TCU_CHECK(renderbufferDepth != (GLuint)-1);
    829 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbufferDepth));
    830 
    831 	m_eglExt.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)img);
    832 
    833 	GLenum error = glGetError();
    834 
    835 	if (error == GL_INVALID_OPERATION)
    836 	{
    837 		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbufferDepth));
    838 		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbufferColor));
    839 		throw tcu::NotSupportedError("Creating renderbuffer from EGLImage type not supported", "glEGLImageTargetRenderbufferStorageOES", __FILE__, __LINE__);
    840 	}
    841 
    842 	TCU_CHECK(error == GL_NONE);
    843 
    844 	TCU_CHECK_EGL_MSG("glEGLImageTargetRenderbufferStorageOES() failed");
    845 
    846 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbufferDepth));
    847 	GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbufferDepth));
    848 
    849 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbufferColor));
    850 	GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbufferColor));
    851 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
    852 
    853 	GLU_CHECK_CALL(glViewport(0, 0, reference.getWidth(), reference.getHeight()));
    854 	if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    855 	{
    856 		GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer));
    857 		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbufferDepth));
    858 		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbufferColor));
    859 		throw tcu::NotSupportedError("EGLImage as depth attachment not supported", "", __FILE__, __LINE__);
    860 	}
    861 
    862 	// Render
    863 	const char* vertexShader =
    864 		"attribute highp vec2 a_coord;\n"
    865 		"uniform highp float u_depth;\n"
    866 		"void main(void) {\n"
    867 		"\tgl_Position = vec4(a_coord, u_depth, 1.0);\n"
    868 		"}\n";
    869 
    870 	const char* fragmentShader =
    871 		"uniform mediump vec4 u_color;\n"
    872 		"void main(void) {\n"
    873 		"\tgl_FragColor = u_color;\n"
    874 		"}";
    875 
    876 	Program program(vertexShader, fragmentShader);
    877 	TCU_CHECK(program.isOk());
    878 
    879 	GLuint glProgram = program.getProgram();
    880 	GLU_CHECK_CALL(glUseProgram(glProgram));
    881 
    882 	GLuint coordLoc = glGetAttribLocation(glProgram, "a_coord");
    883 	TCU_CHECK_MSG((int)coordLoc != -1, "Couldn't find attribute a_coord");
    884 
    885 	GLuint colorLoc = glGetUniformLocation(glProgram, "u_color");
    886 	TCU_CHECK_MSG((int)colorLoc != (int)-1, "Couldn't find uniform u_color");
    887 
    888 	GLuint depthLoc = glGetUniformLocation(glProgram, "u_depth");
    889 	TCU_CHECK_MSG((int)depthLoc != (int)-1, "Couldn't find uniform u_depth");
    890 
    891 	float coords[] =
    892 	{
    893 		-1.0, -1.0,
    894 		1.0, -1.0,
    895 		1.0,  1.0,
    896 
    897 		1.0,  1.0,
    898 		-1.0,  1.0,
    899 		-1.0, -1.0
    900 	};
    901 
    902 	float depthLevels[] = {
    903 		0.1f,
    904 		0.2f,
    905 		0.3f,
    906 		0.4f,
    907 		0.5f,
    908 		0.6f,
    909 		0.7f,
    910 		0.8f,
    911 		0.9f,
    912 		1.0f
    913 	};
    914 
    915 	tcu::Vec4 depthLevelColors[] = {
    916 		tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
    917 		tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
    918 		tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
    919 		tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
    920 		tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f),
    921 
    922 		tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
    923 		tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f),
    924 		tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f),
    925 		tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f),
    926 		tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f)
    927 	};
    928 
    929 	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(depthLevels) == DE_LENGTH_OF_ARRAY(depthLevelColors));
    930 
    931 	GLU_CHECK_CALL(glEnableVertexAttribArray(coordLoc));
    932 	GLU_CHECK_CALL(glVertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, coords));
    933 
    934 	GLU_CHECK_CALL(glEnable(GL_DEPTH_TEST));
    935 	GLU_CHECK_CALL(glDepthFunc(GL_LESS));
    936 
    937 	for (int level = 0; level < DE_LENGTH_OF_ARRAY(depthLevels); level++)
    938 	{
    939 		tcu::Vec4 color = depthLevelColors[level];
    940 		GLU_CHECK_CALL(glUniform4f(colorLoc, color.x(), color.y(), color.z(), color.w()));
    941 		GLU_CHECK_CALL(glUniform1f(depthLoc, depthLevels[level]));
    942 		GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 6));
    943 	}
    944 
    945 	GLU_CHECK_CALL(glDisable(GL_DEPTH_TEST));
    946 	GLU_CHECK_CALL(glDisableVertexAttribArray(coordLoc));
    947 
    948 	tcu::Surface screen(reference.getWidth(), reference.getHeight());
    949 	tcu::Surface referenceScreen(reference.getWidth(), reference.getHeight());
    950 
    951 	glReadPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr());
    952 
    953 	for (int y = 0; y < reference.getHeight(); y++)
    954 	{
    955 		for (int x = 0; x < reference.getWidth(); x++)
    956 		{
    957 			tcu::RGBA result;
    958 			for (int level = 0; level < DE_LENGTH_OF_ARRAY(depthLevels); level++)
    959 			{
    960 				tcu::Vec4 src = reference.getLevel(0).getPixel(x, y);
    961 
    962 				if (src.x() < depthLevels[level])
    963 				{
    964 					result = tcu::RGBA((int)(depthLevelColors[level].x() * 255.0f), (int)(depthLevelColors[level].y() * 255.0f), (int)(depthLevelColors[level].z() * 255.0f), (int)(depthLevelColors[level].w() * 255.0f));
    965 				}
    966 			}
    967 
    968 			referenceScreen.setPixel(x, reference.getHeight(), result);
    969 		}
    970 	}
    971 
    972 	bool isOk = tcu::pixelThresholdCompare(m_log, "Depth buffer rendering result", "Result from rendering with depth buffer", referenceScreen, screen, tcu::RGBA(1,1,1,1), tcu::COMPARE_LOG_RESULT);
    973 
    974 	GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
    975 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
    976 	GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbufferDepth));
    977 	GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbufferColor));
    978 	GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer));
    979 	GLU_CHECK_CALL(glFinish());
    980 
    981 	return isOk;
    982 }
    983 
    984 bool GLES2ImageApi::renderReadPixelsRenderBuffer (EGLImageKHR img, const tcu::Texture2D& reference)
    985 {
    986 	m_log << tcu::TestLog::Message << "Reading with ReadPixels from renderbuffer" << tcu::TestLog::EndMessage;
    987 
    988 	deUint32 framebuffer;
    989 	glGenFramebuffers(1, &framebuffer);
    990 	TCU_CHECK(framebuffer != (GLuint)-1);
    991 	GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
    992 
    993 	deUint32 renderbuffer = 0;
    994 	glGenRenderbuffers(1, &renderbuffer);
    995 	TCU_CHECK(renderbuffer != (GLuint)-1);
    996 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer));
    997 
    998 	m_eglExt.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)img);
    999 
   1000 	GLenum error = glGetError();
   1001 
   1002 	if (error == GL_INVALID_OPERATION)
   1003 	{
   1004 		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer));
   1005 		throw tcu::NotSupportedError("Creating renderbuffer from EGLImage type not supported", "glEGLImageTargetRenderbufferStorageOES", __FILE__, __LINE__);
   1006 	}
   1007 
   1008 	TCU_CHECK(error == GL_NONE);
   1009 
   1010 	TCU_CHECK_EGL_MSG("glEGLImageTargetRenderbufferStorageOES() failed");
   1011 
   1012 	GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer));
   1013 
   1014 	GLU_CHECK_CALL(glViewport(0, 0, reference.getWidth(), reference.getHeight()));
   1015 	if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   1016 	{
   1017 		GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer));
   1018 		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer));
   1019 		throw tcu::NotSupportedError("EGLImage as color attachment not supported", "", __FILE__, __LINE__);
   1020 	}
   1021 
   1022 	tcu::Surface screen(reference.getWidth(), reference.getHeight());
   1023 	tcu::Surface referenceScreen(reference.getWidth(), reference.getHeight());
   1024 
   1025 	glReadPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr());
   1026 
   1027 	for (int y = 0; y < reference.getHeight(); y++)
   1028 	{
   1029 		for (int x = 0; x < reference.getWidth(); x++)
   1030 		{
   1031 			tcu::Vec4 src = reference.getLevel(0).getPixel(x, y);
   1032 			referenceScreen.setPixel(x, y, tcu::RGBA(src));
   1033 		}
   1034 	}
   1035 
   1036 	bool isOk = tcu::pixelThresholdCompare(m_log, "Renderbuffer read", "Result from reading renderbuffer", referenceScreen, screen, tcu::RGBA(1,1,1,1), tcu::COMPARE_LOG_RESULT);
   1037 
   1038 	GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
   1039 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
   1040 	GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer));
   1041 	GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer));
   1042 	GLU_CHECK_CALL(glFinish());
   1043 
   1044 	return isOk;
   1045 }
   1046 
   1047 bool GLES2ImageApi::renderTryAll (EGLImageKHR img, const tcu::Texture2D& reference)
   1048 {
   1049 	bool isOk = true;
   1050 	bool foundSupportedRendering = false;
   1051 
   1052 	try
   1053 	{
   1054 		if (!renderTexture2D(img, reference))
   1055 			isOk = false;
   1056 
   1057 		foundSupportedRendering = true;
   1058 	}
   1059 	catch (const tcu::NotSupportedError& error)
   1060 	{
   1061 		m_log << tcu::TestLog::Message << error.what() << tcu::TestLog::EndMessage;
   1062 	}
   1063 
   1064 	if (!isOk)
   1065 		return false;
   1066 
   1067 	try
   1068 	{
   1069 		if (!renderReadPixelsRenderBuffer(img, reference))
   1070 			isOk = false;
   1071 
   1072 		foundSupportedRendering = true;
   1073 	}
   1074 	catch (const tcu::NotSupportedError& error)
   1075 	{
   1076 		m_log << tcu::TestLog::Message << error.what() << tcu::TestLog::EndMessage;
   1077 	}
   1078 
   1079 	if (!isOk)
   1080 		return false;
   1081 
   1082 	try
   1083 	{
   1084 		if (!renderDepth(img, reference))
   1085 			isOk = false;
   1086 
   1087 		foundSupportedRendering = true;
   1088 	}
   1089 	catch (const tcu::NotSupportedError& error)
   1090 	{
   1091 		m_log << tcu::TestLog::Message << error.what() << tcu::TestLog::EndMessage;
   1092 	}
   1093 
   1094 	if (!foundSupportedRendering)
   1095 		throw tcu::NotSupportedError("Rendering not supported", "", __FILE__, __LINE__);
   1096 
   1097 	return isOk;
   1098 }
   1099 
   1100 bool GLES2ImageApi::renderCubeMap (EGLImageKHR img, const tcu::Surface& reference, GLenum face)
   1101 {
   1102 	// \note This is not supported by EGLImage
   1103 	DE_ASSERT(false);
   1104 
   1105 	glClearColor(0.5, 0.5, 0.5, 1.0);
   1106 	glViewport(0, 0, reference.getWidth(), reference.getHeight());
   1107 	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
   1108 	glDisable(GL_DEPTH_TEST);
   1109 
   1110 	m_log << tcu::TestLog::Message << "Rendering EGLImage as " <<  glTargetToString(face) << " in context: " << m_contextId << tcu::TestLog::EndMessage;
   1111 	DE_ASSERT(img != EGL_NO_IMAGE_KHR);
   1112 
   1113 	deUint32 srcTex = 0;
   1114 	glGenTextures(1, &srcTex);
   1115 	DE_ASSERT(srcTex != 0);
   1116 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, srcTex));
   1117 	GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, reference.getWidth(), reference.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0));
   1118 	GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, reference.getWidth(), reference.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0));
   1119 	GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, reference.getWidth(), reference.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0));
   1120 	GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, reference.getWidth(), reference.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0));
   1121 	GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, reference.getWidth(), reference.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0));
   1122 	GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, reference.getWidth(), reference.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0));
   1123 
   1124 	m_eglExt.glEGLImageTargetTexture2DOES(face, (GLeglImageOES)img);
   1125 	GLenum error = glGetError();
   1126 
   1127 	if (error == GL_INVALID_OPERATION)
   1128 	{
   1129 		GLU_CHECK_CALL(glDeleteTextures(1, &srcTex));
   1130 		throw tcu::NotSupportedError("Creating texture cubemap from EGLImage type not supported", "glEGLImageTargetTexture2DOES", __FILE__, __LINE__);
   1131 	}
   1132 
   1133 	TCU_CHECK(error == GL_NONE);
   1134 
   1135 	TCU_CHECK_EGL_MSG("glEGLImageTargetTexture2DOES() failed");
   1136 
   1137 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
   1138 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
   1139 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
   1140 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
   1141 
   1142 	const char* vertexShader =
   1143 		"attribute highp vec3 a_coord;\n"
   1144 		"attribute highp vec3 a_texCoord;\n"
   1145 		"varying mediump vec3 v_texCoord;\n"
   1146 		"void main(void) {\n"
   1147 		"\tv_texCoord = a_texCoord;\n"
   1148 		"\tgl_Position = vec4(a_coord.xy, -0.1, 1.0);\n"
   1149 		"}\n";
   1150 
   1151 	const char* fragmentShader =
   1152 		"varying mediump vec3 v_texCoord;\n"
   1153 		"uniform samplerCube u_sampler;\n"
   1154 		"void main(void) {\n"
   1155 		"\tmediump vec4 texColor = textureCube(u_sampler, v_texCoord);\n"
   1156 		"\tgl_FragColor = vec4(texColor.rgb, 1.0);\n"
   1157 		"}";
   1158 
   1159 	Program program(vertexShader, fragmentShader);
   1160 	DE_ASSERT(program.isOk());
   1161 
   1162 	GLuint glProgram = program.getProgram();
   1163 	GLU_CHECK_CALL(glUseProgram(glProgram));
   1164 
   1165 	GLint coordLoc = glGetAttribLocation(glProgram, "a_coord");
   1166 	DE_ASSERT(coordLoc != -1);
   1167 
   1168 	GLint texCoordLoc = glGetAttribLocation(glProgram, "a_texCoord");
   1169 	DE_ASSERT(texCoordLoc != -1);
   1170 
   1171 	GLint samplerLoc = glGetUniformLocation(glProgram, "u_sampler");
   1172 	DE_ASSERT(samplerLoc != -1);
   1173 
   1174 	float coords[] =
   1175 	{
   1176 		-1.0, -1.0,
   1177 		1.0, -1.0,
   1178 		1.0,  1.0,
   1179 
   1180 		1.0,  1.0,
   1181 		-1.0,  1.0,
   1182 		-1.0, -1.0,
   1183 	};
   1184 
   1185 	float sampleTexCoords[] =
   1186 	{
   1187 		10.0, -1.0, -1.0,
   1188 		10.0,  1.0, -1.0,
   1189 		10.0,  1.0,  1.0,
   1190 
   1191 		10.0,  1.0,  1.0,
   1192 		10.0, -1.0,  1.0,
   1193 		10.0, -1.0, -1.0,
   1194 	};
   1195 
   1196 	vector<float> texCoords;
   1197 	float	sign	= 0.0f;
   1198 	int		dir		= -1;
   1199 
   1200 	switch (face)
   1201 	{
   1202 		case GL_TEXTURE_CUBE_MAP_POSITIVE_X: sign =  1.0; dir = 0; break;
   1203 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: sign = -1.0; dir = 0; break;
   1204 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: sign =  1.0; dir = 1; break;
   1205 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: sign = -1.0; dir = 1; break;
   1206 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: sign =  1.0; dir = 2; break;
   1207 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: sign = -1.0; dir = 2; break;
   1208 		default:
   1209 				DE_ASSERT(false);
   1210 	}
   1211 
   1212 	for (int i = 0; i < 6; i++)
   1213 	{
   1214 		texCoords.push_back(sign * sampleTexCoords[i*3 + (dir % 3)]);
   1215 		texCoords.push_back(sampleTexCoords[i*3 + ((dir + 1) % 3)]);
   1216 		texCoords.push_back(sampleTexCoords[i*3 + ((dir + 2) % 3)]);
   1217 	}
   1218 
   1219 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, srcTex));
   1220 	GLU_CHECK_CALL(glUniform1i(samplerLoc, 0));
   1221 	GLU_CHECK_CALL(glEnableVertexAttribArray(coordLoc));
   1222 	GLU_CHECK_CALL(glEnableVertexAttribArray(texCoordLoc));
   1223 	GLU_CHECK_CALL(glVertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, coords));
   1224 	GLU_CHECK_CALL(glVertexAttribPointer(texCoordLoc, 3, GL_FLOAT, GL_FALSE, 0, coords));
   1225 
   1226 	GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 6));
   1227 	GLU_CHECK_CALL(glDisableVertexAttribArray(coordLoc));
   1228 	GLU_CHECK_CALL(glDisableVertexAttribArray(texCoordLoc));
   1229 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_CUBE_MAP, 0));
   1230 	GLU_CHECK_CALL(glDeleteTextures(1, &srcTex));
   1231 
   1232 	tcu::Surface screen(reference.getWidth(), reference.getHeight());
   1233 	glReadPixels(0, 0, screen.getWidth(), screen.getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen.getAccess().getDataPtr());
   1234 	GLU_CHECK_MSG("glReadPixels()");
   1235 
   1236 	float	threshold	= 0.05f;
   1237 	bool	match		= tcu::fuzzyCompare(m_log, "ComparisonResult", "Image comparison result", reference, screen, threshold, tcu::COMPARE_LOG_RESULT);
   1238 
   1239 	return match;
   1240 }
   1241 
   1242 void GLES2ImageApi::modify (int operationNdx, EGLImageKHR img, tcu::Texture2D& reference)
   1243 {
   1244 	switch (operationNdx)
   1245 	{
   1246 		case MODIFY_TEXSUBIMAGE_RGBA8:
   1247 			modifyTexSubImage(img, reference, GL_RGBA, GL_UNSIGNED_BYTE);
   1248 			break;
   1249 
   1250 		case MODIFY_TEXSUBIMAGE_RGBA5_A1:
   1251 			modifyTexSubImage(img, reference, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
   1252 			break;
   1253 
   1254 		case MODIFY_TEXSUBIMAGE_RGBA4:
   1255 			modifyTexSubImage(img, reference, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
   1256 			break;
   1257 
   1258 		case MODIFY_TEXSUBIMAGE_RGB8:
   1259 			modifyTexSubImage(img, reference, GL_RGB, GL_UNSIGNED_BYTE);
   1260 			break;
   1261 
   1262 		case MODIFY_TEXSUBIMAGE_RGB565:
   1263 			modifyTexSubImage(img, reference, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
   1264 			break;
   1265 
   1266 		case MODIFY_RENDERBUFFER_CLEAR_COLOR:
   1267 			modifyRenderbufferClearColor(img, reference);
   1268 			break;
   1269 
   1270 		case MODIFY_RENDERBUFFER_CLEAR_DEPTH:
   1271 			modifyRenderbufferClearDepth(img, reference);
   1272 			break;
   1273 
   1274 		case MODIFY_RENDERBUFFER_CLEAR_STENCIL:
   1275 			modifyRenderbufferClearStencil(img, reference);
   1276 			break;
   1277 
   1278 		default:
   1279 			DE_ASSERT(false);
   1280 			break;
   1281 	}
   1282 }
   1283 
   1284 void GLES2ImageApi::modifyTexSubImage (EGLImageKHR img, tcu::Texture2D& reference, GLenum format, GLenum type)
   1285 {
   1286 	m_log << tcu::TestLog::Message << "Modifying EGLImage with glTexSubImage2D" << tcu::TestLog::EndMessage;
   1287 
   1288 	deUint32 srcTex = 0;
   1289 	glGenTextures(1, &srcTex);
   1290 	TCU_CHECK(srcTex != 0);
   1291 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, srcTex));
   1292 
   1293 	m_eglExt.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)img);
   1294 
   1295 	GLenum error = glGetError();
   1296 
   1297 	if (error == GL_INVALID_OPERATION)
   1298 	{
   1299 		GLU_CHECK_CALL(glDeleteTextures(1, &srcTex));
   1300 		throw tcu::NotSupportedError("Creating texture2D from EGLImage type not supported", "glEGLImageTargetTexture2DOES", __FILE__, __LINE__);
   1301 	}
   1302 	TCU_CHECK(error == GL_NONE);
   1303 
   1304 	TCU_CHECK_EGL_MSG("glEGLImageTargetTexture2DOES() failed");
   1305 
   1306 	int xOffset = 8;
   1307 	int yOffset = 16;
   1308 
   1309 	tcu::Texture2D src(glu::mapGLTransferFormat(format, type), 16, 16);
   1310 	src.allocLevel(0);
   1311 	tcu::fillWithComponentGradients(src.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
   1312 
   1313 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, srcTex));
   1314 	GLU_CHECK_CALL(glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, src.getWidth(), src.getHeight(), format, type, src.getLevel(0).getDataPtr()));
   1315 
   1316 	for (int x = 0; x < src.getWidth(); x++)
   1317 	{
   1318 		if (x + xOffset >= reference.getWidth())
   1319 			continue;
   1320 
   1321 		for (int y = 0; y < src.getHeight(); y++)
   1322 		{
   1323 			if (y + yOffset >= reference.getHeight())
   1324 				continue;
   1325 
   1326 			reference.getLevel(0).setPixel(src.getLevel(0).getPixel(x, y), x+xOffset, y+yOffset);
   1327 		}
   1328 	}
   1329 
   1330 	GLU_CHECK_CALL(glDeleteTextures(1, &srcTex));
   1331 	GLU_CHECK_CALL(glFinish());
   1332 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, 0));
   1333 }
   1334 
   1335 void GLES2ImageApi::modifyRenderbufferClearColor (EGLImageKHR img, tcu::Texture2D& reference)
   1336 {
   1337 	m_log << tcu::TestLog::Message << "Modifying EGLImage with glClear to renderbuffer" << tcu::TestLog::EndMessage;
   1338 
   1339 	deUint32 framebuffer;
   1340 	glGenFramebuffers(1, &framebuffer);
   1341 	TCU_CHECK(framebuffer != (GLuint)-1);
   1342 	GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
   1343 
   1344 	deUint32 renderbuffer = 0;
   1345 	glGenRenderbuffers(1, &renderbuffer);
   1346 	TCU_CHECK(renderbuffer != (GLuint)-1);
   1347 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer));
   1348 
   1349 	m_eglExt.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)img);
   1350 
   1351 	GLenum error = glGetError();
   1352 
   1353 	if (error == GL_INVALID_OPERATION)
   1354 	{
   1355 		GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer));
   1356 		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer));
   1357 		throw tcu::NotSupportedError("Creating renderbuffer from EGLImage type not supported", "glEGLImageTargetRenderbufferStorageOES", __FILE__, __LINE__);
   1358 	}
   1359 	TCU_CHECK(error == GL_NONE);
   1360 
   1361 	TCU_CHECK_EGL_MSG("glEGLImageTargetRenderbufferStorageOES() failed");
   1362 
   1363 	float red	= 0.3f;
   1364 	float green	= 0.5f;
   1365 	float blue	= 0.3f;
   1366 	float alpha	= 1.0f;
   1367 
   1368 	GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer));
   1369 
   1370 	GLU_CHECK_CALL(glViewport(0, 0, reference.getWidth(), reference.getHeight()));
   1371 	if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   1372 	{
   1373 		GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer));
   1374 		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer));
   1375 		throw tcu::NotSupportedError("EGLImage type as color attachment not supported", "", __FILE__, __LINE__);
   1376 	}
   1377 
   1378 	GLU_CHECK_CALL(glClearColor(red, green, blue, alpha));
   1379 	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
   1380 
   1381 	for (int x = 0; x < reference.getWidth(); x++)
   1382 	{
   1383 		for (int y = 0; y < reference.getHeight(); y++)
   1384 		{
   1385 			tcu::Vec4 color = tcu::Vec4(red, green, blue, alpha);
   1386 			reference.getLevel(0).setPixel(color, x, y);
   1387 		}
   1388 	}
   1389 
   1390 	GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
   1391 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
   1392 	GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer));
   1393 	GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer));
   1394 	GLU_CHECK_CALL(glFinish());
   1395 }
   1396 
   1397 void GLES2ImageApi::modifyRenderbufferClearDepth (EGLImageKHR img, tcu::Texture2D& reference)
   1398 {
   1399 	m_log << tcu::TestLog::Message << "Modifying EGLImage with glClear to renderbuffer" << tcu::TestLog::EndMessage;
   1400 
   1401 	deUint32 framebuffer;
   1402 	glGenFramebuffers(1, &framebuffer);
   1403 	TCU_CHECK(framebuffer != (GLuint)-1);
   1404 	GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
   1405 
   1406 	deUint32 renderbuffer = 0;
   1407 	glGenRenderbuffers(1, &renderbuffer);
   1408 	TCU_CHECK(renderbuffer != 0);
   1409 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer));
   1410 
   1411 	m_eglExt.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)img);
   1412 
   1413 	GLenum error = glGetError();
   1414 
   1415 	if (error == GL_INVALID_OPERATION)
   1416 	{
   1417 		GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer));
   1418 		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer));
   1419 		throw tcu::NotSupportedError("Creating renderbuffer from EGLImage type not supported", "glEGLImageTargetRenderbufferStorageOES", __FILE__, __LINE__);
   1420 	}
   1421 	TCU_CHECK(error == GL_NONE);
   1422 
   1423 	TCU_CHECK_EGL_MSG("glEGLImageTargetRenderbufferStorageOES() failed");
   1424 
   1425 	float depth = 0.7f;
   1426 
   1427 	GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer));
   1428 
   1429 	GLU_CHECK_CALL(glViewport(0, 0, reference.getWidth(), reference.getHeight()));
   1430 	if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   1431 	{
   1432 		GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer));
   1433 		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer));
   1434 		throw tcu::NotSupportedError("EGLImage type as depth attachment not supported", "", __FILE__, __LINE__);
   1435 	}
   1436 
   1437 	GLU_CHECK_CALL(glClearDepthf(depth));
   1438 	GLU_CHECK_CALL(glClear(GL_DEPTH_BUFFER_BIT));
   1439 
   1440 	for (int x = 0; x < reference.getWidth(); x++)
   1441 	{
   1442 		for (int y = 0; y < reference.getHeight(); y++)
   1443 		{
   1444 			tcu::Vec4 color = tcu::Vec4(depth, depth, depth, depth);
   1445 			reference.getLevel(0).setPixel(color, x, y);
   1446 		}
   1447 	}
   1448 
   1449 	GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
   1450 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
   1451 	GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer));
   1452 	GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer));
   1453 	GLU_CHECK_CALL(glFinish());
   1454 }
   1455 
   1456 void GLES2ImageApi::modifyRenderbufferClearStencil (EGLImageKHR img, tcu::Texture2D& reference)
   1457 {
   1458 	m_log << tcu::TestLog::Message << "Modifying EGLImage with glClear to renderbuffer" << tcu::TestLog::EndMessage;
   1459 
   1460 	deUint32 framebuffer;
   1461 	glGenFramebuffers(1, &framebuffer);
   1462 	TCU_CHECK(framebuffer != (GLuint)-1);
   1463 	GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
   1464 
   1465 	deUint32 renderbuffer = 0;
   1466 	glGenRenderbuffers(1, &renderbuffer);
   1467 	TCU_CHECK(renderbuffer != 0);
   1468 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer));
   1469 
   1470 	m_eglExt.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, (GLeglImageOES)img);
   1471 	GLenum error = glGetError();
   1472 
   1473 	if (error == GL_INVALID_OPERATION)
   1474 	{
   1475 		GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer));
   1476 		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer));
   1477 		throw tcu::NotSupportedError("Creating renderbuffer from EGLImage type not supported", "glEGLImageTargetRenderbufferStorageOES", __FILE__, __LINE__);
   1478 	}
   1479 	TCU_CHECK(error == GL_NONE);
   1480 
   1481 	TCU_CHECK_EGL_MSG("glEGLImageTargetRenderbufferStorageOES() failed");
   1482 
   1483 	int stencilValue = 78;
   1484 
   1485 	GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuffer));
   1486 
   1487 	GLU_CHECK_CALL(glViewport(0, 0, reference.getWidth(), reference.getHeight()));
   1488 	if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
   1489 	{
   1490 		GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer));
   1491 		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer));
   1492 		throw tcu::NotSupportedError("EGLImage type as stencil attachment not supported", "", __FILE__, __LINE__);
   1493 	}
   1494 
   1495 	GLU_CHECK_CALL(glClearStencil(stencilValue));
   1496 	GLU_CHECK_CALL(glClear(GL_STENCIL_BUFFER_BIT));
   1497 
   1498 	for (int x = 0; x < reference.getWidth(); x++)
   1499 	{
   1500 		for (int y = 0; y < reference.getHeight(); y++)
   1501 		{
   1502 			tcu::IVec4 color = tcu::IVec4(stencilValue, stencilValue, stencilValue, stencilValue);
   1503 			reference.getLevel(0).setPixel(color, x, y);
   1504 		}
   1505 	}
   1506 
   1507 	GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
   1508 	GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, 0));
   1509 	GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer));
   1510 	GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer));
   1511 	GLU_CHECK_CALL(glFinish());
   1512 }
   1513 
   1514 
   1515 void GLES2ImageApi::checkRequiredExtensions (set<string>& extensions, TestSpec::Operation::Type type, int operationNdx)
   1516 {
   1517 	switch (type)
   1518 	{
   1519 		case TestSpec::Operation::TYPE_CREATE:
   1520 			switch (operationNdx)
   1521 			{
   1522 				case CREATE_TEXTURE2D_RGB8:
   1523 				case CREATE_TEXTURE2D_RGB565:
   1524 				case CREATE_TEXTURE2D_RGBA8:
   1525 				case CREATE_TEXTURE2D_RGBA5_A1:
   1526 				case CREATE_TEXTURE2D_RGBA4:
   1527 					extensions.insert("EGL_KHR_gl_texture_2D_image");
   1528 					break;
   1529 
   1530 				case CREATE_CUBE_MAP_POSITIVE_X_RGB8:
   1531 				case CREATE_CUBE_MAP_NEGATIVE_X_RGB8:
   1532 				case CREATE_CUBE_MAP_POSITIVE_Y_RGB8:
   1533 				case CREATE_CUBE_MAP_NEGATIVE_Y_RGB8:
   1534 				case CREATE_CUBE_MAP_POSITIVE_Z_RGB8:
   1535 				case CREATE_CUBE_MAP_NEGATIVE_Z_RGB8:
   1536 				case CREATE_CUBE_MAP_POSITIVE_X_RGBA8:
   1537 				case CREATE_CUBE_MAP_NEGATIVE_X_RGBA8:
   1538 				case CREATE_CUBE_MAP_POSITIVE_Y_RGBA8:
   1539 				case CREATE_CUBE_MAP_NEGATIVE_Y_RGBA8:
   1540 				case CREATE_CUBE_MAP_POSITIVE_Z_RGBA8:
   1541 				case CREATE_CUBE_MAP_NEGATIVE_Z_RGBA8:
   1542 					extensions.insert("EGL_KHR_gl_texture_cubemap_image");
   1543 					break;
   1544 
   1545 				case CREATE_RENDER_BUFFER_RGBA4:
   1546 				case CREATE_RENDER_BUFFER_RGB5_A1:
   1547 				case CREATE_RENDER_BUFFER_RGB565:
   1548 				case CREATE_RENDER_BUFFER_DEPTH16:
   1549 				case CREATE_RENDER_BUFFER_STENCIL:
   1550 					extensions.insert("EGL_KHR_gl_renderbuffer_image");
   1551 					break;
   1552 
   1553 				default:
   1554 					DE_ASSERT(false);
   1555 			}
   1556 			break;
   1557 
   1558 		case TestSpec::Operation::TYPE_RENDER:
   1559 			switch (operationNdx)
   1560 			{
   1561 				case RENDER_TEXTURE2D:
   1562 				case RENDER_READ_PIXELS_RENDERBUFFER:
   1563 				case RENDER_DEPTHBUFFER:
   1564 				case RENDER_TRY_ALL:
   1565 					extensions.insert("GL_OES_EGL_image");
   1566 					break;
   1567 
   1568 				default:
   1569 					DE_ASSERT(false);
   1570 					break;
   1571 			}
   1572 			break;
   1573 
   1574 		case TestSpec::Operation::TYPE_MODIFY:
   1575 			switch (operationNdx)
   1576 			{
   1577 				case MODIFY_TEXSUBIMAGE_RGB565:
   1578 				case MODIFY_TEXSUBIMAGE_RGB8:
   1579 				case MODIFY_TEXSUBIMAGE_RGBA8:
   1580 				case MODIFY_TEXSUBIMAGE_RGBA5_A1:
   1581 				case MODIFY_TEXSUBIMAGE_RGBA4:
   1582 				case MODIFY_RENDERBUFFER_CLEAR_COLOR:
   1583 				case MODIFY_RENDERBUFFER_CLEAR_DEPTH:
   1584 				case MODIFY_RENDERBUFFER_CLEAR_STENCIL:
   1585 					extensions.insert("GL_OES_EGL_image");
   1586 					break;
   1587 
   1588 				default:
   1589 					DE_ASSERT(false);
   1590 					break;
   1591 			};
   1592 			break;
   1593 
   1594 		default:
   1595 			DE_ASSERT(false);
   1596 			break;
   1597 	}
   1598 }
   1599 
   1600 class ImageFormatCase : public TestCase
   1601 {
   1602 public:
   1603 						ImageFormatCase		(EglTestContext& eglTestCtx, const TestSpec& spec);
   1604 						~ImageFormatCase	(void);
   1605 
   1606 	void				init				(void);
   1607 	void				deinit				(void);
   1608 	IterateResult		iterate				(void);
   1609 	void				checkExtensions		(void);
   1610 
   1611 private:
   1612 	EGLConfig			getConfig			(void);
   1613 
   1614 	const TestSpec		m_spec;
   1615 	tcu::TestLog&		m_log;
   1616 
   1617 	vector<ImageApi*>	m_apiContexts;
   1618 
   1619 	tcu::egl::Display*	m_display;
   1620 	eglu::NativeWindow*	m_window;
   1621 	tcu::egl::Surface*	m_surface;
   1622 	EGLConfig			m_config;
   1623 	int					m_curIter;
   1624 	EGLImageKHR			m_img;
   1625 	tcu::Texture2D		m_refImg;
   1626 	EglExt				m_eglExt;
   1627 };
   1628 
   1629 EGLConfig ImageFormatCase::getConfig (void)
   1630 {
   1631 	vector<EGLConfig>	configs;
   1632 	eglu::FilterList	filter;
   1633 
   1634 	EGLint attribList[] =
   1635 	{
   1636 		EGL_RENDERABLE_TYPE, 	EGL_OPENGL_ES2_BIT,
   1637 		EGL_SURFACE_TYPE,	 	EGL_WINDOW_BIT,
   1638 		EGL_ALPHA_SIZE,			1,
   1639 		EGL_DEPTH_SIZE,			8,
   1640 		EGL_NONE
   1641 	};
   1642 	m_display->chooseConfig(attribList, configs);
   1643 
   1644 	return configs[0];
   1645 }
   1646 
   1647 ImageFormatCase::ImageFormatCase (EglTestContext& eglTestCtx, const TestSpec& spec)
   1648 	: TestCase			(eglTestCtx, spec.name.c_str(), spec.desc.c_str())
   1649 	, m_spec			(spec)
   1650 	, m_log				(eglTestCtx.getTestContext().getLog())
   1651 	, m_display			(DE_NULL)
   1652 	, m_window			(DE_NULL)
   1653 	, m_surface			(DE_NULL)
   1654 	, m_config			(0)
   1655 	, m_curIter			(0)
   1656 	, m_img				(EGL_NO_IMAGE_KHR)
   1657 	, m_refImg			(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1)
   1658 {
   1659 }
   1660 
   1661 ImageFormatCase::~ImageFormatCase (void)
   1662 {
   1663 	deinit();
   1664 }
   1665 
   1666 void ImageFormatCase::checkExtensions (void)
   1667 {
   1668 	vector<string> extensions;
   1669 	m_display->getExtensions(extensions);
   1670 
   1671 	set<string> extSet(extensions.begin(), extensions.end());
   1672 
   1673 	const char* glExt = (const char*)glGetString(GL_EXTENSIONS);
   1674 
   1675 	for (const char* c = glExt; true; c++)
   1676 	{
   1677 		if (*c == '\0')
   1678 		{
   1679 			extSet.insert(string(glExt));
   1680 			break;
   1681 		}
   1682 
   1683 		if (*c == ' ')
   1684 		{
   1685 			extSet.insert(string(glExt, c));
   1686 			glExt = (c+1);
   1687 		}
   1688 	}
   1689 
   1690 	if (extSet.find("EGL_KHR_image_base") == extSet.end()
   1691 			&& extSet.find("EGL_KHR_image") == extSet.end())
   1692 	{
   1693 		m_log << tcu::TestLog::Message
   1694 			<< "EGL_KHR_image and EGL_KHR_image_base not supported."
   1695 			<< "One should be supported."
   1696 			<< tcu::TestLog::EndMessage;
   1697 		throw tcu::NotSupportedError("Extension not supported", "EGL_KHR_image_base", __FILE__, __LINE__);
   1698 	}
   1699 
   1700 	set<string> requiredExtensions;
   1701 	for (int operationNdx = 0; operationNdx < (int)m_spec.operations.size(); operationNdx++)
   1702 		m_apiContexts[m_spec.operations[m_curIter].apiIndex]->checkRequiredExtensions(requiredExtensions, m_spec.operations[operationNdx].type, m_spec.operations[operationNdx].operationIndex);
   1703 
   1704 	std::set<string>::iterator extIter = requiredExtensions.begin();
   1705 	for (; extIter != requiredExtensions.end(); extIter++)
   1706 	{
   1707 		if (extSet.find(*extIter) == extSet.end())
   1708 			throw tcu::NotSupportedError("Extension not supported", (*extIter).c_str(), __FILE__, __LINE__);
   1709 	}
   1710 }
   1711 
   1712 void ImageFormatCase::init (void)
   1713 {
   1714 	m_display	= &m_eglTestCtx.getDisplay();
   1715 	m_config	= getConfig();
   1716 	m_window	= m_eglTestCtx.createNativeWindow(m_display->getEGLDisplay(), m_config, DE_NULL, 480, 480, eglu::parseWindowVisibility(m_testCtx.getCommandLine()));
   1717 	m_surface	= new tcu::egl::WindowSurface(*m_display, eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_display->getEGLDisplay(), m_config, DE_NULL));
   1718 
   1719 	for (int contextNdx = 0; contextNdx < (int)m_spec.contexts.size(); contextNdx++)
   1720 	{
   1721 		ImageApi* api = DE_NULL;
   1722 		switch (m_spec.contexts[contextNdx])
   1723 		{
   1724 			case TestSpec::API_GLES2:
   1725 			{
   1726 				api = new GLES2ImageApi(contextNdx, m_log, *m_display, m_surface, m_config);
   1727 				break;
   1728 			}
   1729 
   1730 			default:
   1731 				DE_ASSERT(false);
   1732 				break;
   1733 		}
   1734 		m_apiContexts.push_back(api);
   1735 	}
   1736 	checkExtensions();
   1737 }
   1738 
   1739 void ImageFormatCase::deinit (void)
   1740 {
   1741 	for (int contexNdx = 0 ; contexNdx < (int)m_apiContexts.size(); contexNdx++)
   1742 		delete m_apiContexts[contexNdx];
   1743 
   1744 	m_apiContexts.clear();
   1745 	delete m_surface;
   1746 	m_surface = DE_NULL;
   1747 	delete m_window;
   1748 	m_window = DE_NULL;
   1749 }
   1750 
   1751 TestCase::IterateResult ImageFormatCase::iterate (void)
   1752 {
   1753 	bool isOk = true;
   1754 
   1755 	switch (m_spec.operations[m_curIter].type)
   1756 	{
   1757 		case TestSpec::Operation::TYPE_CREATE:
   1758 		{
   1759 			// Delete old image if exists
   1760 			if (m_img != EGL_NO_IMAGE_KHR)
   1761 			{
   1762 				m_log << tcu::TestLog::Message << "Destroying old EGLImage" << tcu::TestLog::EndMessage;
   1763 				TCU_CHECK_EGL_CALL(m_eglExt.eglDestroyImageKHR(m_display->getEGLDisplay(), m_img));
   1764 
   1765 				m_img = EGL_NO_IMAGE_KHR;
   1766 			}
   1767 
   1768 			m_img = m_apiContexts[m_spec.operations[m_curIter].apiIndex]->create(m_spec.operations[m_curIter].operationIndex, m_refImg);
   1769 			break;
   1770 		}
   1771 
   1772 		case TestSpec::Operation::TYPE_RENDER:
   1773 		{
   1774 			DE_ASSERT(m_apiContexts[m_spec.operations[m_curIter].apiIndex]);
   1775 			isOk = m_apiContexts[m_spec.operations[m_curIter].apiIndex]->render(m_spec.operations[m_curIter].operationIndex, m_img, m_refImg);
   1776 			break;
   1777 		}
   1778 
   1779 		case TestSpec::Operation::TYPE_MODIFY:
   1780 		{
   1781 			m_apiContexts[m_spec.operations[m_curIter].apiIndex]->modify(m_spec.operations[m_curIter].operationIndex, m_img, m_refImg);
   1782 			break;
   1783 		}
   1784 
   1785 		default:
   1786 			DE_ASSERT(false);
   1787 			break;
   1788 	}
   1789 
   1790 	if (isOk && ++m_curIter < (int)m_spec.operations.size())
   1791 	{
   1792 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1793 		return CONTINUE;
   1794 	}
   1795 	else if (!isOk)
   1796 	{
   1797 		if (m_img != EGL_NO_IMAGE_KHR)
   1798 		{
   1799 			m_log << tcu::TestLog::Message << "Destroying EGLImage" << tcu::TestLog::EndMessage;
   1800 			TCU_CHECK_EGL_CALL(m_eglExt.eglDestroyImageKHR(m_display->getEGLDisplay(), m_img));
   1801 			m_img = EGL_NO_IMAGE_KHR;
   1802 		}
   1803 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1804 		return STOP;
   1805 	}
   1806 	else
   1807 	{
   1808 		if (m_img != EGL_NO_IMAGE_KHR)
   1809 		{
   1810 			m_log << tcu::TestLog::Message << "Destroying EGLImage" << tcu::TestLog::EndMessage;
   1811 			TCU_CHECK_EGL_CALL(m_eglExt.eglDestroyImageKHR(m_display->getEGLDisplay(), m_img));
   1812 			m_img = EGL_NO_IMAGE_KHR;
   1813 		}
   1814 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1815 		return STOP;
   1816 	}
   1817 }
   1818 
   1819 SimpleCreationTests::SimpleCreationTests (EglTestContext& eglTestCtx)
   1820 	: TestCaseGroup	(eglTestCtx, "create", "EGLImage creation tests")
   1821 {
   1822 }
   1823 
   1824 #define PUSH_VALUES_TO_VECTOR(type, vector, ...)\
   1825 do {\
   1826 	type array[] = __VA_ARGS__;\
   1827 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(array); i++)\
   1828 	{\
   1829 		vector.push_back(array[i]);\
   1830 	}\
   1831 } while(false);
   1832 
   1833 void SimpleCreationTests::init (void)
   1834 {
   1835 	GLES2ImageApi::Create createOperations[] = {
   1836 		GLES2ImageApi::CREATE_TEXTURE2D_RGB8,
   1837 		GLES2ImageApi::CREATE_TEXTURE2D_RGB565,
   1838 		GLES2ImageApi::CREATE_TEXTURE2D_RGBA8,
   1839 		GLES2ImageApi::CREATE_TEXTURE2D_RGBA5_A1,
   1840 		GLES2ImageApi::CREATE_TEXTURE2D_RGBA4,
   1841 
   1842 		GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_X_RGBA8,
   1843 		GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Y_RGBA8,
   1844 		GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Z_RGBA8,
   1845 
   1846 		GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_X_RGBA8,
   1847 		GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Y_RGBA8,
   1848 		GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Z_RGBA8,
   1849 
   1850 		GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_X_RGB8,
   1851 		GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Y_RGB8,
   1852 		GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Z_RGB8,
   1853 
   1854 		GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_X_RGB8,
   1855 		GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Y_RGB8,
   1856 		GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Z_RGB8,
   1857 
   1858 		GLES2ImageApi::CREATE_RENDER_BUFFER_RGBA4,
   1859 		GLES2ImageApi::CREATE_RENDER_BUFFER_RGB5_A1,
   1860 		GLES2ImageApi::CREATE_RENDER_BUFFER_RGB565,
   1861 		GLES2ImageApi::CREATE_RENDER_BUFFER_DEPTH16,
   1862 		GLES2ImageApi::CREATE_RENDER_BUFFER_STENCIL
   1863 	};
   1864 
   1865 	const char* createOperationsStr[] = {
   1866 		"texture_rgb8",
   1867 		"texture_rgb565",
   1868 		"texture_rgba8",
   1869 		"texture_rgba5_a1",
   1870 		"texture_rgba4",
   1871 
   1872 		"cubemap_positive_x_rgba",
   1873 		"cubemap_positive_y_rgba",
   1874 		"cubemap_positive_z_rgba",
   1875 
   1876 		"cubemap_negative_x_rgba",
   1877 		"cubemap_negative_y_rgba",
   1878 		"cubemap_negative_z_rgba",
   1879 
   1880 		"cubemap_positive_x_rgb",
   1881 		"cubemap_positive_y_rgb",
   1882 		"cubemap_positive_z_rgb",
   1883 
   1884 		"cubemap_negative_x_rgb",
   1885 		"cubemap_negative_y_rgb",
   1886 		"cubemap_negative_z_rgb",
   1887 
   1888 		"renderbuffer_rgba4",
   1889 		"renderbuffer_rgb5_a1",
   1890 		"renderbuffer_rgb565",
   1891 		"renderbuffer_depth16",
   1892 		"renderbuffer_stencil"
   1893 	};
   1894 
   1895 	GLES2ImageApi::Render renderOperations[] = {
   1896 			GLES2ImageApi::RENDER_TEXTURE2D,
   1897 			GLES2ImageApi::RENDER_READ_PIXELS_RENDERBUFFER,
   1898 			GLES2ImageApi::RENDER_DEPTHBUFFER
   1899 	};
   1900 	const char* renderOperationsStr[] = {
   1901 			"texture",
   1902 			"read_pixels",
   1903 			"depth_buffer"
   1904 	};
   1905 
   1906 	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(createOperations) == DE_LENGTH_OF_ARRAY(createOperationsStr));
   1907 	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(renderOperations) == DE_LENGTH_OF_ARRAY(renderOperationsStr));
   1908 
   1909 	for (int createNdx = 0; createNdx < DE_LENGTH_OF_ARRAY(createOperations); createNdx++)
   1910 	{
   1911 		for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renderOperations); renderNdx++)
   1912 		{
   1913 			TestSpec spec;
   1914 			spec.name = std::string("gles2_") + createOperationsStr[createNdx] + "_" + renderOperationsStr[renderNdx];
   1915 			spec.desc = spec.name;
   1916 
   1917 			PUSH_VALUES_TO_VECTOR(TestSpec::ApiContext, spec.contexts,
   1918 			{
   1919 				TestSpec::API_GLES2
   1920 			});
   1921 			PUSH_VALUES_TO_VECTOR(TestSpec::Operation, spec.operations,
   1922 			{
   1923 				{ TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_CREATE, createOperations[createNdx] },
   1924 				{ TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_RENDER, renderOperations[renderNdx] },
   1925 			});
   1926 
   1927 			addChild(new ImageFormatCase(m_eglTestCtx, spec));
   1928 		}
   1929 	}
   1930 }
   1931 
   1932 MultiContextRenderTests::MultiContextRenderTests (EglTestContext& eglTestCtx)
   1933 	: TestCaseGroup	(eglTestCtx, "render_multiple_contexts", "EGLImage render tests on multiple contexts")
   1934 {
   1935 }
   1936 
   1937 void MultiContextRenderTests::init (void)
   1938 {
   1939 	GLES2ImageApi::Create createOperations[] = {
   1940 		GLES2ImageApi::CREATE_TEXTURE2D_RGB8,
   1941 		GLES2ImageApi::CREATE_TEXTURE2D_RGB565,
   1942 		GLES2ImageApi::CREATE_TEXTURE2D_RGBA8,
   1943 		GLES2ImageApi::CREATE_TEXTURE2D_RGBA5_A1,
   1944 		GLES2ImageApi::CREATE_TEXTURE2D_RGBA4,
   1945 
   1946 		GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_X_RGBA8,
   1947 		GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Y_RGBA8,
   1948 		GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Z_RGBA8,
   1949 
   1950 		GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_X_RGBA8,
   1951 		GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Y_RGBA8,
   1952 		GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Z_RGBA8,
   1953 
   1954 		GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_X_RGB8,
   1955 		GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Y_RGB8,
   1956 		GLES2ImageApi::CREATE_CUBE_MAP_POSITIVE_Z_RGB8,
   1957 
   1958 		GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_X_RGB8,
   1959 		GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Y_RGB8,
   1960 		GLES2ImageApi::CREATE_CUBE_MAP_NEGATIVE_Z_RGB8,
   1961 
   1962 		GLES2ImageApi::CREATE_RENDER_BUFFER_RGBA4,
   1963 		GLES2ImageApi::CREATE_RENDER_BUFFER_RGB5_A1,
   1964 		GLES2ImageApi::CREATE_RENDER_BUFFER_RGB565,
   1965 		GLES2ImageApi::CREATE_RENDER_BUFFER_DEPTH16,
   1966 		GLES2ImageApi::CREATE_RENDER_BUFFER_STENCIL
   1967 	};
   1968 
   1969 	const char* createOperationsStr[] = {
   1970 		"texture_rgb8",
   1971 		"texture_rgb565",
   1972 		"texture_rgba8",
   1973 		"texture_rgba5_a1",
   1974 		"texture_rgba4",
   1975 
   1976 		"cubemap_positive_x_rgba8",
   1977 		"cubemap_positive_y_rgba8",
   1978 		"cubemap_positive_z_rgba8",
   1979 
   1980 		"cubemap_negative_x_rgba8",
   1981 		"cubemap_negative_y_rgba8",
   1982 		"cubemap_negative_z_rgba8",
   1983 
   1984 		"cubemap_positive_x_rgb8",
   1985 		"cubemap_positive_y_rgb8",
   1986 		"cubemap_positive_z_rgb8",
   1987 
   1988 		"cubemap_negative_x_rgb8",
   1989 		"cubemap_negative_y_rgb8",
   1990 		"cubemap_negative_z_rgb8",
   1991 
   1992 		"renderbuffer_rgba4",
   1993 		"renderbuffer_rgb5_a1",
   1994 		"renderbuffer_rgb565",
   1995 		"renderbuffer_depth16",
   1996 		"renderbuffer_stencil"
   1997 	};
   1998 
   1999 	GLES2ImageApi::Render renderOperations[] = {
   2000 			GLES2ImageApi::RENDER_TEXTURE2D,
   2001 			GLES2ImageApi::RENDER_READ_PIXELS_RENDERBUFFER,
   2002 			GLES2ImageApi::RENDER_DEPTHBUFFER
   2003 	};
   2004 	const char* renderOperationsStr[] = {
   2005 			"texture",
   2006 			"read_pixels",
   2007 			"depth_buffer"
   2008 	};
   2009 
   2010 	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(createOperations) == DE_LENGTH_OF_ARRAY(createOperationsStr));
   2011 	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(renderOperations) == DE_LENGTH_OF_ARRAY(renderOperationsStr));
   2012 
   2013 	for (int createNdx = 0; createNdx < DE_LENGTH_OF_ARRAY(createOperations); createNdx++)
   2014 	{
   2015 		for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renderOperations); renderNdx++)
   2016 		{
   2017 			TestSpec spec;
   2018 			spec.name = std::string("gles2_") + createOperationsStr[createNdx] + "_" + renderOperationsStr[renderNdx];
   2019 			spec.desc = spec.name;
   2020 
   2021 			PUSH_VALUES_TO_VECTOR(TestSpec::ApiContext, spec.contexts,
   2022 			{
   2023 				TestSpec::API_GLES2,
   2024 				TestSpec::API_GLES2
   2025 			});
   2026 			PUSH_VALUES_TO_VECTOR(TestSpec::Operation, spec.operations,
   2027 			{
   2028 				{ TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_CREATE, createOperations[createNdx] },
   2029 				{ TestSpec::API_GLES2, 1, TestSpec::Operation::TYPE_RENDER, renderOperations[renderNdx] },
   2030 				{ TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_RENDER, renderOperations[renderNdx] },
   2031 				{ TestSpec::API_GLES2, 1, TestSpec::Operation::TYPE_CREATE, createOperations[createNdx] },
   2032 				{ TestSpec::API_GLES2, 1, TestSpec::Operation::TYPE_RENDER, renderOperations[renderNdx] },
   2033 				{ TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_RENDER, renderOperations[renderNdx] }
   2034 			});
   2035 			addChild(new ImageFormatCase(m_eglTestCtx, spec));
   2036 		}
   2037 	}
   2038 }
   2039 
   2040 ModifyTests::ModifyTests (EglTestContext& eglTestCtx)
   2041 	: TestCaseGroup	(eglTestCtx, "modify", "EGLImage modifying tests")
   2042 {
   2043 }
   2044 
   2045 void ModifyTests::init (void)
   2046 {
   2047 	GLES2ImageApi::Create createOperations[] = {
   2048 		GLES2ImageApi::CREATE_TEXTURE2D_RGB8,
   2049 		GLES2ImageApi::CREATE_TEXTURE2D_RGB565,
   2050 		GLES2ImageApi::CREATE_TEXTURE2D_RGBA8,
   2051 		GLES2ImageApi::CREATE_TEXTURE2D_RGBA5_A1,
   2052 		GLES2ImageApi::CREATE_TEXTURE2D_RGBA4,
   2053 
   2054 		GLES2ImageApi::CREATE_RENDER_BUFFER_RGBA4,
   2055 		GLES2ImageApi::CREATE_RENDER_BUFFER_RGB5_A1,
   2056 		GLES2ImageApi::CREATE_RENDER_BUFFER_RGB565,
   2057 		GLES2ImageApi::CREATE_RENDER_BUFFER_DEPTH16,
   2058 		GLES2ImageApi::CREATE_RENDER_BUFFER_STENCIL
   2059 	};
   2060 
   2061 	const char* createOperationsStr[] = {
   2062 		"tex_rgb8",
   2063 		"tex_rgb565",
   2064 		"tex_rgba8",
   2065 		"tex_rgba5_a1",
   2066 		"tex_rgba4",
   2067 
   2068 		"renderbuffer_rgba4",
   2069 		"renderbuffer_rgb5_a1",
   2070 		"renderbuffer_rgb565",
   2071 		"renderbuffer_depth16",
   2072 		"renderbuffer_stencil"
   2073 	};
   2074 
   2075 	GLES2ImageApi::Modify modifyOperations[] = {
   2076 		GLES2ImageApi::MODIFY_TEXSUBIMAGE_RGB8,
   2077 		GLES2ImageApi::MODIFY_TEXSUBIMAGE_RGB565,
   2078 		GLES2ImageApi::MODIFY_TEXSUBIMAGE_RGBA8,
   2079 		GLES2ImageApi::MODIFY_TEXSUBIMAGE_RGBA5_A1,
   2080 		GLES2ImageApi::MODIFY_TEXSUBIMAGE_RGBA4,
   2081 
   2082 		GLES2ImageApi::MODIFY_RENDERBUFFER_CLEAR_COLOR,
   2083 		GLES2ImageApi::MODIFY_RENDERBUFFER_CLEAR_DEPTH,
   2084 		GLES2ImageApi::MODIFY_RENDERBUFFER_CLEAR_STENCIL,
   2085 	};
   2086 
   2087 	const char* modifyOperationsStr[] = {
   2088 		"tex_subimage_rgb8",
   2089 		"tex_subimage_rgb565",
   2090 		"tex_subimage_rgba8",
   2091 		"tex_subimage_rgba5_a1",
   2092 		"tex_subimage_rgba4",
   2093 
   2094 		"renderbuffer_clear_color",
   2095 		"renderbuffer_clear_depth",
   2096 		"renderbuffer_clear_stencil",
   2097 	};
   2098 
   2099 	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(modifyOperations) == DE_LENGTH_OF_ARRAY(modifyOperationsStr));
   2100 	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(createOperations) == DE_LENGTH_OF_ARRAY(createOperationsStr));
   2101 
   2102 	for (int createNdx = 0; createNdx < DE_LENGTH_OF_ARRAY(createOperations); createNdx++)
   2103 	{
   2104 		for (int modifyNdx = 0; modifyNdx < DE_LENGTH_OF_ARRAY(modifyOperations); modifyNdx++)
   2105 		{
   2106 			TestSpec spec;
   2107 			spec.name = "gles2_tex_sub_image";
   2108 			spec.desc = spec.name;
   2109 
   2110 			PUSH_VALUES_TO_VECTOR(TestSpec::ApiContext, spec.contexts,
   2111 			{
   2112 				TestSpec::API_GLES2
   2113 			});
   2114 			PUSH_VALUES_TO_VECTOR(TestSpec::Operation, spec.operations,
   2115 			{
   2116 				{ TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_CREATE, createOperations[createNdx] },
   2117 				{ TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_RENDER, GLES2ImageApi::RENDER_TRY_ALL },
   2118 				{ TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_MODIFY, modifyOperations[modifyNdx] },
   2119 				{ TestSpec::API_GLES2, 0, TestSpec::Operation::TYPE_RENDER, GLES2ImageApi::RENDER_TRY_ALL }
   2120 			});
   2121 
   2122 			spec.name = std::string(createOperationsStr[createNdx]) + "_" + modifyOperationsStr[modifyNdx];
   2123 			addChild(new ImageFormatCase(m_eglTestCtx, spec));
   2124 		}
   2125 	}
   2126 }
   2127 
   2128 } // Image
   2129 } // egl
   2130 } // deqp
   2131