• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
Program(const char * vertexSource,const char * fragmentSource)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 
~Program(void)119 	~Program (void)
120 	{
121 		glDeleteShader(m_vertexShader);
122 		glDeleteShader(m_fragmentShader);
123 		glDeleteProgram(m_program);
124 	}
125 
isOk(void) const126 	bool			isOk			(void) const { return m_isOk;	}
getProgram(void) const127 	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:
EglExt(void)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);
~ImageApi(void)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 
ImageApi(int contextId,tcu::TestLog & log,tcu::egl::Display & display,tcu::egl::Surface * surface)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 
GLES2ImageApi(int contextId,tcu::TestLog & log,tcu::egl::Display & display,tcu::egl::Surface * surface,EGLConfig config)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 
~GLES2ImageApi(void)342 GLES2ImageApi::~GLES2ImageApi (void)
343 {
344 	delete m_context;
345 }
346 
create(int operationNdx,tcu::Texture2D & ref)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 
glTargetToString(GLenum target)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 
glFormatToString(GLenum format)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 
glTypeToString(GLenum type)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 
createTexture2D(tcu::Texture2D & reference,GLenum target,GLenum format,GLenum type)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 
glRenderbufferTargetToString(GLenum format)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 
createRenderBuffer(tcu::Texture2D & ref,GLenum format)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 
render(int operationNdx,EGLImageKHR img,const tcu::Texture2D & reference)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 
renderTexture2D(EGLImageKHR img,const tcu::Texture2D & reference)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 
renderDepth(EGLImageKHR img,const tcu::Texture2D & reference)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 
renderReadPixelsRenderBuffer(EGLImageKHR img,const tcu::Texture2D & reference)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 
renderTryAll(EGLImageKHR img,const tcu::Texture2D & reference)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 
renderCubeMap(EGLImageKHR img,const tcu::Surface & reference,GLenum face)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 
modify(int operationNdx,EGLImageKHR img,tcu::Texture2D & reference)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 
modifyTexSubImage(EGLImageKHR img,tcu::Texture2D & reference,GLenum format,GLenum type)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 
modifyRenderbufferClearColor(EGLImageKHR img,tcu::Texture2D & reference)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 
modifyRenderbufferClearDepth(EGLImageKHR img,tcu::Texture2D & reference)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 
modifyRenderbufferClearStencil(EGLImageKHR img,tcu::Texture2D & reference)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 
checkRequiredExtensions(set<string> & extensions,TestSpec::Operation::Type type,int operationNdx)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 
getConfig(void)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 
ImageFormatCase(EglTestContext & eglTestCtx,const TestSpec & spec)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 
~ImageFormatCase(void)1661 ImageFormatCase::~ImageFormatCase (void)
1662 {
1663 	deinit();
1664 }
1665 
checkExtensions(void)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 
init(void)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 
deinit(void)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 
iterate(void)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 
SimpleCreationTests(EglTestContext & eglTestCtx)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 
init(void)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 
MultiContextRenderTests(EglTestContext & eglTestCtx)1932 MultiContextRenderTests::MultiContextRenderTests (EglTestContext& eglTestCtx)
1933 	: TestCaseGroup	(eglTestCtx, "render_multiple_contexts", "EGLImage render tests on multiple contexts")
1934 {
1935 }
1936 
init(void)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 
ModifyTests(EglTestContext & eglTestCtx)2040 ModifyTests::ModifyTests (EglTestContext& eglTestCtx)
2041 	: TestCaseGroup	(eglTestCtx, "modify", "EGLImage modifying tests")
2042 {
2043 }
2044 
init(void)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