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 gles2 sharing tests
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "teglGLES2SharingTests.hpp"
     25 
     26 #include "teglGLES2SharingThreadedTests.hpp"
     27 
     28 #include "egluNativeWindow.hpp"
     29 #include "egluUtil.hpp"
     30 
     31 #include "tcuCommandLine.hpp"
     32 #include "tcuImageCompare.hpp"
     33 #include "tcuSurface.hpp"
     34 #include "tcuTestLog.hpp"
     35 #include "tcuTexture.hpp"
     36 #include "tcuTextureUtil.hpp"
     37 
     38 #include "deUniquePtr.hpp"
     39 #include "deRandom.hpp"
     40 
     41 #include "deMath.h"
     42 #include "deMemory.h"
     43 #include "deString.h"
     44 
     45 #include "gluDefs.hpp"
     46 
     47 #include <GLES2/gl2.h>
     48 
     49 #include <memory>
     50 #include <sstream>
     51 #include <vector>
     52 
     53 using std::vector;
     54 
     55 namespace deqp
     56 {
     57 namespace egl
     58 {
     59 
     60 namespace
     61 {
     62 
     63 // \todo [2013-04-09 pyry] Use glu::Program
     64 class Program
     65 {
     66 public:
     67 	Program (const char* vertexSource, const char* fragmentSource)
     68 		: m_program			(0)
     69 		, m_vertexShader	(0)
     70 		, m_fragmentShader	(0)
     71 		, m_isOk			(false)
     72 	{
     73 		m_program			= glCreateProgram();
     74 		m_vertexShader		= glCreateShader(GL_VERTEX_SHADER);
     75 		m_fragmentShader	= glCreateShader(GL_FRAGMENT_SHADER);
     76 
     77 		try
     78 		{
     79 			bool	vertexCompileOk		= false;
     80 			bool	fragmentCompileOk	= false;
     81 			bool	linkOk				= false;
     82 
     83 			for (int ndx = 0; ndx < 2; ndx++)
     84 			{
     85 				const char*		source			= ndx ? fragmentSource		: vertexSource;
     86 				const deUint32	shader			= ndx ? m_fragmentShader	: m_vertexShader;
     87 				int				compileStatus	= 0;
     88 				bool&			compileOk		= ndx ? fragmentCompileOk	: vertexCompileOk;
     89 
     90 				glShaderSource(shader, 1, &source, DE_NULL);
     91 				glCompileShader(shader);
     92 				glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
     93 
     94 				compileOk = (compileStatus == GL_TRUE);
     95 			}
     96 
     97 			if (vertexCompileOk && fragmentCompileOk)
     98 			{
     99 				int linkStatus = 0;
    100 
    101 				glAttachShader(m_program, m_vertexShader);
    102 				glAttachShader(m_program, m_fragmentShader);
    103 				glLinkProgram(m_program);
    104 				glGetProgramiv(m_program, GL_LINK_STATUS, &linkStatus);
    105 
    106 				linkOk = (linkStatus == GL_TRUE);
    107 			}
    108 
    109 			m_isOk = linkOk;
    110 		}
    111 		catch (const std::exception&)
    112 		{
    113 			glDeleteShader(m_vertexShader);
    114 			glDeleteShader(m_fragmentShader);
    115 			glDeleteProgram(m_program);
    116 			throw;
    117 		}
    118 	}
    119 
    120 	~Program (void)
    121 	{
    122 		glDeleteShader(m_vertexShader);
    123 		glDeleteShader(m_fragmentShader);
    124 		glDeleteProgram(m_program);
    125 	}
    126 
    127 	bool			isOk			(void) const { return m_isOk;	}
    128 	deUint32		getProgram		(void) const {return m_program;	}
    129 
    130 private:
    131 	deUint32		m_program;
    132 	deUint32		m_vertexShader;
    133 	deUint32		m_fragmentShader;
    134 	bool			m_isOk;
    135 };
    136 
    137 } // anonymous
    138 
    139 class GLES2SharingTest : public TestCase
    140 {
    141 public:
    142 	enum ResourceType
    143 	{
    144 		BUFFER = 0,
    145 		TEXTURE,
    146 		RENDERBUFFER,
    147 		SHADER_PROGRAM
    148 	};
    149 
    150 	struct TestSpec
    151 	{
    152 		ResourceType	type;
    153 		bool			destroyContextBFirst;
    154 		bool			useResource;
    155 		bool			destroyOnContexB;
    156 		bool			initializeData;
    157 		bool			renderOnContexA;
    158 		bool			renderOnContexB;
    159 		bool			verifyOnContexA;
    160 		bool			verifyOnContexB;
    161 	};
    162 
    163 					GLES2SharingTest	(EglTestContext& eglTestCtx, const char* name , const char* desc, const TestSpec& spec);
    164 	IterateResult	iterate				(void);
    165 
    166 private:
    167 	TestSpec		m_spec;
    168 
    169 	EGLContext		createContext		(EGLDisplay display, EGLContext share, EGLConfig config);
    170 	void			destroyContext		(EGLDisplay display, EGLContext context);
    171 	void			makeCurrent			(EGLDisplay display, EGLContext context, EGLSurface surafec);
    172 
    173 protected:
    174 	de::Random		m_random;
    175 	tcu::TestLog&	m_log;
    176 	virtual void	createResource		(void)  { DE_ASSERT(false); }
    177 	virtual void 	destroyResource		(void)	{ DE_ASSERT(false); }
    178 	virtual void	renderResource		(tcu::Surface* screen, tcu::Surface* reference) { DE_UNREF(screen); DE_UNREF(reference); DE_ASSERT(false); }
    179 };
    180 
    181 GLES2SharingTest::GLES2SharingTest (EglTestContext& eglTestCtx, const char* name , const char* desc, const TestSpec& spec)
    182 	: TestCase	(eglTestCtx, name, desc)
    183 	, m_spec	(spec)
    184 	, m_random	(deStringHash(name))
    185 	, m_log		(eglTestCtx.getTestContext().getLog())
    186 {
    187 }
    188 
    189 EGLContext GLES2SharingTest::createContext (EGLDisplay display, EGLContext share, EGLConfig config)
    190 {
    191 	EGLContext context = EGL_NO_CONTEXT;
    192 	EGLint attriblist[] =
    193 	{
    194 		EGL_CONTEXT_CLIENT_VERSION, 2,
    195 		EGL_NONE
    196 	};
    197 
    198 	EGLint configId = -1;
    199 	eglGetConfigAttrib(display, config, EGL_CONFIG_ID, &configId);
    200 
    201 	TCU_CHECK_EGL_CALL(eglBindAPI(EGL_OPENGL_ES_API));
    202 
    203 	context = eglCreateContext(display, config, share, attriblist);
    204 	TCU_CHECK_EGL_MSG("Failed to create GLES2 context");
    205 	TCU_CHECK(context != EGL_NO_CONTEXT);
    206 
    207 	return context;
    208 }
    209 
    210 void GLES2SharingTest::destroyContext (EGLDisplay display, EGLContext context)
    211 {
    212 	TCU_CHECK_EGL_CALL(eglDestroyContext(display, context));
    213 }
    214 
    215 void GLES2SharingTest::makeCurrent (EGLDisplay display, EGLContext context, EGLSurface surface)
    216 {
    217 	TCU_CHECK_EGL_CALL(eglMakeCurrent(display, surface, surface, context));
    218 }
    219 
    220 TestCase::IterateResult GLES2SharingTest::iterate (void)
    221 {
    222 	tcu::TestLog&		log		= m_testCtx.getLog();
    223 	vector<EGLConfig>	configs;
    224 
    225 	EGLint attribList[] =
    226 	{
    227 		EGL_RENDERABLE_TYPE, 	EGL_OPENGL_ES2_BIT,
    228 		EGL_SURFACE_TYPE,	 	EGL_WINDOW_BIT,
    229 		EGL_ALPHA_SIZE,			1,
    230 		EGL_NONE
    231 	};
    232 
    233 	tcu::egl::Display& display = m_eglTestCtx.getDisplay();
    234 	display.chooseConfig(attribList, configs);
    235 	EGLConfig config = configs[0];
    236 
    237 	de::UniquePtr<eglu::NativeWindow>	window	(m_eglTestCtx.createNativeWindow(display.getEGLDisplay(), config, DE_NULL, 480, 480, eglu::parseWindowVisibility(m_testCtx.getCommandLine())));
    238 	tcu::egl::WindowSurface				surface	(display, eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, display.getEGLDisplay(), config, DE_NULL));
    239 
    240 	m_log << tcu::TestLog::Message << "Create context A" << tcu::TestLog::EndMessage;
    241 	EGLContext		contextA	= createContext(display.getEGLDisplay(), EGL_NO_CONTEXT, config);
    242 	m_log << tcu::TestLog::Message << "Create context B" << tcu::TestLog::EndMessage;
    243 	EGLContext		contextB	= createContext(display.getEGLDisplay(), contextA, config);
    244 	bool			isOk		= true;
    245 
    246 	if (m_spec.useResource)
    247 	{
    248 		m_log << tcu::TestLog::Message << "Make current context A" << tcu::TestLog::EndMessage;
    249 		makeCurrent(display.getEGLDisplay(), contextA, surface.getEGLSurface());
    250 		m_log << tcu::TestLog::Message << "Creating resource" << tcu::TestLog::EndMessage;
    251 		createResource();
    252 
    253 		int		width	= 240;
    254 		int		height	= 240;
    255 
    256 		if (m_spec.renderOnContexA)
    257 		{
    258 			m_log << tcu::TestLog::Message << "Render resource" << tcu::TestLog::EndMessage;
    259 			if (m_spec.verifyOnContexA)
    260 			{
    261 				tcu::Surface screen	(width, height);
    262 				tcu::Surface ref	(width, height);
    263 				renderResource(&screen, &ref);
    264 
    265 				if (!fuzzyCompare(log, "Rendered image", "Rendering result comparision", ref, screen, 0.05f, tcu::COMPARE_LOG_RESULT))
    266 					isOk = false;
    267 			}
    268 			else
    269 			{
    270 				renderResource(NULL, NULL);
    271 			}
    272 		}
    273 
    274 		if (m_spec.renderOnContexB)
    275 		{
    276 			m_log << tcu::TestLog::Message << "Make current context B" << tcu::TestLog::EndMessage;
    277 			makeCurrent(display.getEGLDisplay(), contextB, surface.getEGLSurface());
    278 			m_log << tcu::TestLog::Message << "Render resource" << tcu::TestLog::EndMessage;
    279 			if (m_spec.verifyOnContexB)
    280 			{
    281 				tcu::Surface screen	(width, height);
    282 				tcu::Surface ref	(width, height);
    283 				renderResource(&screen, &ref);
    284 
    285 				if (!fuzzyCompare(log, "Rendered image", "Rendering result comparision", ref, screen, 0.05f, tcu::COMPARE_LOG_RESULT))
    286 					isOk = false;
    287 			}
    288 			else
    289 			{
    290 				renderResource(NULL, NULL);
    291 			}
    292 		}
    293 
    294 		if (m_spec.destroyOnContexB)
    295 		{
    296 			m_log << tcu::TestLog::Message << "Make current context B" << tcu::TestLog::EndMessage;
    297 			makeCurrent(display.getEGLDisplay(), contextB, surface.getEGLSurface());
    298 			m_log << tcu::TestLog::Message << "Destroy resource" << tcu::TestLog::EndMessage;
    299 			destroyResource();
    300 		}
    301 		else
    302 		{
    303 			m_log << tcu::TestLog::Message << "Make current context A" << tcu::TestLog::EndMessage;
    304 			makeCurrent(display.getEGLDisplay(), contextA, surface.getEGLSurface());
    305 			m_log << tcu::TestLog::Message << "Destroy resource" << tcu::TestLog::EndMessage;
    306 			destroyResource();
    307 		}
    308 	}
    309 
    310 	if (m_spec.destroyContextBFirst)
    311 	{
    312 		m_log << tcu::TestLog::Message << "Destroy context B" << tcu::TestLog::EndMessage;
    313 		destroyContext(display.getEGLDisplay(), contextB);
    314 		m_log << tcu::TestLog::Message << "Destroy context A" << tcu::TestLog::EndMessage;
    315 		destroyContext(display.getEGLDisplay(), contextA);
    316 	}
    317 	else
    318 	{
    319 		m_log << tcu::TestLog::Message << "Destroy context A" << tcu::TestLog::EndMessage;
    320 		destroyContext(display.getEGLDisplay(), contextA);
    321 		m_log << tcu::TestLog::Message << "Destroy context B" << tcu::TestLog::EndMessage;
    322 		destroyContext(display.getEGLDisplay(), contextB);
    323 	}
    324 
    325 	if (isOk)
    326 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    327 	else
    328 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    329 
    330 	return STOP;
    331 }
    332 
    333 class GLES2BufferSharingTest : public GLES2SharingTest
    334 {
    335 public:
    336 							GLES2BufferSharingTest	(EglTestContext& eglTestCtx, const char* name, const char* desc, const GLES2SharingTest::TestSpec& spec);
    337 
    338 private:
    339 	GLuint					m_glBuffer;
    340 	std::vector<GLubyte>	m_buffer;
    341 
    342 	virtual void	createResource		(void);
    343 	virtual void 	destroyResource		(void);
    344 	virtual void	renderResource		(tcu::Surface* screen, tcu::Surface* reference);
    345 
    346 };
    347 
    348 GLES2BufferSharingTest::GLES2BufferSharingTest (EglTestContext& eglTestCtx, const char* name, const char* desc, const GLES2SharingTest::TestSpec& spec)
    349 	: GLES2SharingTest	(eglTestCtx, name, desc, spec)
    350 	, m_glBuffer		(0)
    351 {
    352 }
    353 
    354 void GLES2BufferSharingTest::createResource (void)
    355 {
    356 	int						size	= 16*16*4;
    357 
    358 	m_buffer.reserve(size);
    359 
    360 	for (int i = 0; i < size; i++)
    361 		m_buffer.push_back((GLubyte)m_random.getInt(0, 255));
    362 
    363 	GLU_CHECK_CALL(glGenBuffers(1, &m_glBuffer));
    364 	GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, m_glBuffer));
    365 	GLU_CHECK_CALL(glBufferData(GL_ARRAY_BUFFER, (GLsizei)(m_buffer.size() * sizeof(GLubyte)), &(m_buffer[0]), GL_DYNAMIC_DRAW));
    366 	GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
    367 }
    368 
    369 void GLES2BufferSharingTest::destroyResource (void)
    370 {
    371 	GLU_CHECK_CALL(glDeleteBuffers(1, &m_glBuffer));
    372 	m_buffer.clear();
    373 }
    374 
    375 void GLES2BufferSharingTest::renderResource (tcu::Surface* screen, tcu::Surface* reference)
    376 {
    377 	DE_ASSERT((screen && reference) || (!screen && !reference));
    378 
    379 	const char* vertexShader = ""
    380 	"attribute mediump vec2 a_pos;\n"
    381 	"attribute mediump float a_color;\n"
    382 	"varying mediump float v_color;\n"
    383 	"void main(void)\n"
    384 	"{\n"
    385 	"\tv_color = a_color;\n"
    386 	"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
    387 	"}\n";
    388 
    389 	const char* fragmentShader = ""
    390 	"varying mediump float v_color;\n"
    391 	"void main(void)\n"
    392 	"{\n"
    393 	"\tgl_FragColor = vec4(v_color, v_color, v_color, 1.0);\n"
    394 	"}\n";
    395 
    396 	Program program(vertexShader, fragmentShader);
    397 
    398 	if (!program.isOk())
    399 		TCU_FAIL("Failed to compile shader program");
    400 
    401 	std::vector<deUint16>	indices;
    402 	std::vector<float>		coords;
    403 
    404 	DE_ASSERT(m_buffer.size() % 4 == 0);
    405 
    406 	for (int i = 0; i < (int)m_buffer.size() / 4; i++)
    407 	{
    408 		indices.push_back(i*4);
    409 		indices.push_back(i*4 + 1);
    410 		indices.push_back(i*4 + 2);
    411 		indices.push_back(i*4 + 2);
    412 		indices.push_back(i*4 + 3);
    413 		indices.push_back(i*4);
    414 
    415 		coords.push_back(0.125f * (i % 16) - 1.0f);
    416 		coords.push_back(0.125f * ((int)(i / 16.0f)) - 1.0f);
    417 
    418 		coords.push_back(0.125f * (i % 16) - 1.0f);
    419 		coords.push_back(0.125f * ((int)(i / 16.0f) + 1) - 1.0f);
    420 
    421 		coords.push_back(0.125f * ((i % 16) + 1) - 1.0f);
    422 		coords.push_back(0.125f * ((int)(i / 16.0f) + 1) - 1.0f);
    423 
    424 		coords.push_back(0.125f * ((i % 16) + 1) - 1.0f);
    425 		coords.push_back(0.125f * ((int)(i / 16.0f)) - 1.0f);
    426 	}
    427 
    428 	int width = 240;
    429 	int height = 240;
    430 
    431 	if (screen)
    432 	{
    433 		width = screen->getWidth();
    434 		height = screen->getHeight();
    435 	}
    436 
    437 	GLU_CHECK_CALL(glViewport(0, 0, width, height));
    438 
    439 	GLU_CHECK_CALL(glClearColor(1.0f, 0.0f, 0.0f, 1.0f));
    440 	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
    441 
    442 	GLU_CHECK_CALL(glUseProgram(program.getProgram()));
    443 
    444 	GLuint gridLocation = glGetAttribLocation(program.getProgram(), "a_pos");
    445 	GLU_CHECK_MSG("glGetAttribLocation()");
    446 	TCU_CHECK(gridLocation != (GLuint)-1);
    447 
    448 	GLuint colorLocation = glGetAttribLocation(program.getProgram(), "a_color");
    449 	GLU_CHECK_MSG("glGetAttribLocation()");
    450 	TCU_CHECK(colorLocation != (GLuint)-1);
    451 
    452 	GLU_CHECK_CALL(glEnableVertexAttribArray(colorLocation));
    453 	GLU_CHECK_CALL(glEnableVertexAttribArray(gridLocation));
    454 
    455 	GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, m_glBuffer));
    456 	GLU_CHECK_CALL(glVertexAttribPointer(colorLocation, 1, GL_UNSIGNED_BYTE, GL_TRUE, 0, NULL));
    457 	GLU_CHECK_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
    458 
    459 	GLU_CHECK_CALL(glVertexAttribPointer(gridLocation, 2, GL_FLOAT, GL_FALSE, 0, &(coords[0])));
    460 
    461 	GLU_CHECK_CALL(glDrawElements(GL_TRIANGLES, (GLsizei)indices.size(), GL_UNSIGNED_SHORT, &(indices[0])));
    462 	GLU_CHECK_CALL(glDisableVertexAttribArray(colorLocation));
    463 	GLU_CHECK_CALL(glDisableVertexAttribArray(gridLocation));
    464 
    465 	GLU_CHECK_CALL(glUseProgram(0));
    466 
    467 	if (screen)
    468 	{
    469 		tcu::clear(reference->getAccess(), tcu::IVec4(0xff, 0, 0, 0xff));
    470 		glReadPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen->getAccess().getDataPtr());
    471 		for (int i = 0; i < (int)m_buffer.size() / 4; i++)
    472 		{
    473 			float fx1 = 0.125f * (i % 16) - 1.0f;
    474 			float fy1 = 0.125f * ((int)(i / 16.0f)) - 1.0f;
    475 			float fx2 = 0.125f * ((i % 16) + 1) - 1.0f;
    476 			float fy2 = 0.125f * ((int)((i / 16.0f) + 1)) - 1.0f;
    477 
    478 			int ox = deRoundFloatToInt32(width		/ 2.0f);
    479 			int oy = deRoundFloatToInt32(height		/ 2.0f);
    480 			int x1 = deRoundFloatToInt32((width		 * fx1 / 2.0f) + ox);
    481 			int y1 = deRoundFloatToInt32((height	 * fy1 / 2.0f) + oy);
    482 			int x2 = deRoundFloatToInt32((width		 * fx2 / 2.0f) + ox);
    483 			int y2 = deRoundFloatToInt32((height	 * fy2 / 2.0f) + oy);
    484 
    485 			for (int x = x1; x < x2; x++)
    486 			{
    487 				for (int y = y1; y < y2; y++)
    488 				{
    489 					float		xf		= ((float)(x-x1) + 0.5f) / (float)(x2 - x1);
    490 					float		yf		= ((float)(y-y1) + 0.5f) / (float)(y2 - y1);
    491 					bool		tri		= yf >= xf;
    492 					deUint8		a		= m_buffer[i*4 + (tri ? 1 : 3)];
    493 					deUint8		b		= m_buffer[i*4 + (tri ? 2 : 0)];
    494 					deUint8		c		= m_buffer[i*4 + (tri ? 0 : 2)];
    495 					float		s		= tri ? xf : 1.0f-xf;
    496 					float		t		= tri ? 1.0f-yf : yf;
    497 					float		val		= (float)a + (float)(b-a)*s + (float)(c-a)*t;
    498 
    499 					reference->setPixel(x, y, tcu::RGBA((deUint8)val, (deUint8)val, (deUint8)val, 255));
    500 				}
    501 			}
    502 		}
    503 	}
    504 }
    505 
    506 class GLES2TextureSharingTest : public GLES2SharingTest
    507 {
    508 public:
    509 							GLES2TextureSharingTest	(EglTestContext& eglTestCtx, const char* name, const char* desc, const GLES2SharingTest::TestSpec& spec);
    510 
    511 private:
    512 	GLuint					m_glTexture;
    513 	tcu::Texture2D			m_texture;
    514 
    515 	virtual void	createResource		(void);
    516 	virtual void 	destroyResource		(void);
    517 	virtual void	renderResource		(tcu::Surface* screen, tcu::Surface* reference);
    518 
    519 };
    520 
    521 GLES2TextureSharingTest::GLES2TextureSharingTest (EglTestContext& eglTestCtx, const char* name, const char* desc, const GLES2SharingTest::TestSpec& spec)
    522 	: GLES2SharingTest	(eglTestCtx, name, desc, spec)
    523 	, m_glTexture		(0)
    524 	, m_texture			(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1)
    525 {
    526 }
    527 
    528 void GLES2TextureSharingTest::createResource (void)
    529 {
    530 	int width	= 128;
    531 	int	height	= 128;
    532 	m_texture = tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), width, height);
    533 	m_texture.allocLevel(0);
    534 
    535 	tcu::fillWithComponentGradients(m_texture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    536 	GLU_CHECK_CALL(glGenTextures(1, &m_glTexture));
    537 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, m_glTexture));
    538 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
    539 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
    540 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
    541 	GLU_CHECK_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
    542 	GLU_CHECK_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_texture.getLevel(0).getDataPtr()));
    543 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, 0));
    544 }
    545 
    546 void GLES2TextureSharingTest::destroyResource (void)
    547 {
    548 	GLU_CHECK_CALL(glDeleteTextures(1, &m_glTexture));
    549 }
    550 
    551 void GLES2TextureSharingTest::renderResource (tcu::Surface* screen, tcu::Surface* reference)
    552 {
    553 	DE_ASSERT((screen && reference) || (!screen && !reference));
    554 
    555 	const char* vertexShader = ""
    556 	"attribute mediump vec2 a_pos;\n"
    557 	"attribute mediump vec2 a_texCorod;\n"
    558 	"varying mediump vec2 v_texCoord;\n"
    559 	"void main(void)\n"
    560 	"{\n"
    561 	"\tv_texCoord = a_texCorod;\n"
    562 	"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
    563 	"}\n";
    564 
    565 	const char* fragmentShader = ""
    566 	"varying mediump vec2 v_texCoord;\n"
    567 	"uniform sampler2D u_sampler;\n"
    568 	"void main(void)\n"
    569 	"{\n"
    570 	"\tgl_FragColor = texture2D(u_sampler, v_texCoord);\n"
    571 	"}\n";
    572 
    573 	Program program(vertexShader, fragmentShader);
    574 
    575 	if (!program.isOk())
    576 		TCU_FAIL("Failed to compile shader program");
    577 
    578 	int width = 240;
    579 	int height = 240;
    580 
    581 	if (screen)
    582 	{
    583 		width = screen->getWidth();
    584 		height = screen->getHeight();
    585 	}
    586 
    587 	static const GLfloat coords[] = {
    588 		-1.0f, -1.0f,
    589 		 1.0f, -1.0f,
    590 		 1.0f,  1.0f,
    591 		-1.0f,  1.0f
    592 	};
    593 
    594 	static const GLfloat texCoords[] = {
    595 		0.0f, 0.0f,
    596 		1.0f, 0.0f,
    597 		1.0f, 1.0f,
    598 		0.0f, 1.0f
    599 	};
    600 
    601 	static const GLushort indices[] = {
    602 		0, 1, 2,
    603 		2, 3, 0
    604 	};
    605 
    606 	GLU_CHECK_CALL(glViewport(0, 0, width, height));
    607 
    608 	GLU_CHECK_CALL(glClearColor(1.0f, 0.0f, 0.0f, 1.0f));
    609 	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
    610 
    611 	GLU_CHECK_CALL(glUseProgram(program.getProgram()));
    612 
    613 	GLuint coordLocation = glGetAttribLocation(program.getProgram(), "a_pos");
    614 	GLU_CHECK_MSG("glGetAttribLocation()");
    615 	TCU_CHECK(coordLocation != (GLuint)-1);
    616 
    617 	GLuint texCoordLocation = glGetAttribLocation(program.getProgram(), "a_texCorod");
    618 	GLU_CHECK_MSG("glGetAttribLocation()");
    619 	TCU_CHECK(texCoordLocation != (GLuint)-1);
    620 
    621 
    622 	GLuint samplerLocation = glGetUniformLocation(program.getProgram(), "u_sampler");
    623 	GLU_CHECK_MSG("glGetUniformLocation()");
    624 	TCU_CHECK(samplerLocation != (GLuint)-1);
    625 
    626 	GLU_CHECK_CALL(glActiveTexture(GL_TEXTURE0));
    627 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, m_glTexture));
    628 
    629 	GLU_CHECK_CALL(glUniform1i(samplerLocation, 0));
    630 
    631 	GLU_CHECK_CALL(glEnableVertexAttribArray(texCoordLocation));
    632 	GLU_CHECK_CALL(glEnableVertexAttribArray(coordLocation));
    633 
    634 	GLU_CHECK_CALL(glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, texCoords));
    635 	GLU_CHECK_CALL(glVertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, coords));
    636 
    637 	GLU_CHECK_CALL(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices));
    638 	GLU_CHECK_CALL(glDisableVertexAttribArray(coordLocation));
    639 	GLU_CHECK_CALL(glDisableVertexAttribArray(texCoordLocation));
    640 
    641 	GLU_CHECK_CALL(glBindTexture(GL_TEXTURE_2D, 0));
    642 	GLU_CHECK_CALL(glUseProgram(0));
    643 
    644 	if (screen)
    645 	{
    646 		glReadPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen->getAccess().getDataPtr());
    647 
    648 		for (int x = 0; x < width; x++)
    649 		{
    650 			for (int y = 0; y < height; y++)
    651 			{
    652 				float t = ((float)x / (width - 1.0f));
    653 				float s = ((float)y / (height - 1.0f));
    654 				float lod = 0.0f;
    655 
    656 				tcu::Vec4 color = m_texture.sample(tcu::Sampler(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR), t, s, lod);
    657 
    658 				int r = deClamp32((int)(255.0f * color.x()), 0, 255);
    659 				int g = deClamp32((int)(255.0f * color.y()), 0, 255);
    660 				int b = deClamp32((int)(255.0f * color.z()), 0, 255);
    661 				int a = deClamp32((int)(255.0f * color.w()), 0, 255);
    662 
    663 				reference->setPixel(x, y, tcu::RGBA(r, g, b, a));
    664 			}
    665 		}
    666 	}
    667 }
    668 
    669 class GLES2ProgramSharingTest : public GLES2SharingTest
    670 {
    671 public:
    672 					GLES2ProgramSharingTest	(EglTestContext& eglTestCtx, const char* name, const char* desc, const GLES2SharingTest::TestSpec& spec);
    673 
    674 private:
    675 	Program*		m_program;
    676 
    677 	virtual void	createResource		(void);
    678 	virtual void 	destroyResource		(void);
    679 	virtual void	renderResource		(tcu::Surface* screen, tcu::Surface* reference);
    680 
    681 };
    682 
    683 GLES2ProgramSharingTest::GLES2ProgramSharingTest (EglTestContext& eglTestCtx, const char* name, const char* desc, const GLES2SharingTest::TestSpec& spec)
    684 	: GLES2SharingTest	(eglTestCtx, name, desc, spec)
    685 	, m_program			(NULL)
    686 {
    687 }
    688 
    689 void GLES2ProgramSharingTest::createResource (void)
    690 {
    691 	const char* vertexShader = ""
    692 	"attribute mediump vec2 a_pos;\n"
    693 	"attribute mediump vec4 a_color;\n"
    694 	"varying mediump vec4 v_color;\n"
    695 	"void main(void)\n"
    696 	"{\n"
    697 	"\tv_color = a_color;\n"
    698 	"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
    699 	"}\n";
    700 
    701 	const char* fragmentShader = ""
    702 	"varying mediump vec4 v_color;\n"
    703 	"void main(void)\n"
    704 	"{\n"
    705 	"\tgl_FragColor = v_color;\n"
    706 	"}\n";
    707 
    708 	m_program = new Program(vertexShader, fragmentShader);
    709 
    710 	if (!m_program->isOk())
    711 		TCU_FAIL("Failed to compile shader program");
    712 }
    713 
    714 void GLES2ProgramSharingTest::destroyResource (void)
    715 {
    716 	delete m_program;
    717 }
    718 
    719 void GLES2ProgramSharingTest::renderResource (tcu::Surface* screen, tcu::Surface* reference)
    720 {
    721 	DE_ASSERT((screen && reference) || (!screen && !reference));
    722 
    723 	int width = 240;
    724 	int height = 240;
    725 
    726 	if (screen)
    727 	{
    728 		width = screen->getWidth();
    729 		height = screen->getHeight();
    730 	}
    731 
    732 	static const GLfloat coords[] = {
    733 		-0.9f, -0.9f,
    734 		 0.9f, -0.9f,
    735 		 0.9f,  0.9f,
    736 		-0.9f,  0.9f
    737 	};
    738 
    739 	static const GLfloat colors [] = {
    740 		0.0f, 0.0f, 0.0f, 1.0f,
    741 		1.0f, 0.0f, 0.0f, 1.0f,
    742 		0.0f, 1.0f, 0.0f, 1.0f,
    743 		0.0f, 0.0f, 1.0f, 1.0f
    744 	};
    745 
    746 	static const GLushort indices[] = {
    747 		0, 1, 2,
    748 		2, 3, 0
    749 	};
    750 
    751 	GLU_CHECK_CALL(glViewport(0, 0, width, height));
    752 
    753 	GLU_CHECK_CALL(glClearColor(1.0f, 0.0f, 0.0f, 1.0f));
    754 	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
    755 
    756 	GLU_CHECK_CALL(glUseProgram(m_program->getProgram()));
    757 
    758 	GLuint coordLocation = glGetAttribLocation(m_program->getProgram(), "a_pos");
    759 	GLU_CHECK_MSG("glGetAttribLocation()");
    760 	TCU_CHECK(coordLocation != (GLuint)-1);
    761 
    762 	GLuint colorLocation = glGetAttribLocation(m_program->getProgram(), "a_color");
    763 	GLU_CHECK_MSG("glGetAttribLocation()");
    764 	TCU_CHECK(colorLocation != (GLuint)-1);
    765 
    766 	GLU_CHECK_CALL(glEnableVertexAttribArray(colorLocation));
    767 	GLU_CHECK_CALL(glEnableVertexAttribArray(coordLocation));
    768 
    769 	GLU_CHECK_CALL(glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, colors));
    770 	GLU_CHECK_CALL(glVertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, coords));
    771 
    772 	GLU_CHECK_CALL(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices));
    773 	GLU_CHECK_CALL(glDisableVertexAttribArray(coordLocation));
    774 	GLU_CHECK_CALL(glDisableVertexAttribArray(colorLocation));
    775 	GLU_CHECK_CALL(glUseProgram(0));
    776 
    777 	if (screen)
    778 	{
    779 		glReadPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen->getAccess().getDataPtr());
    780 
    781 		tcu::clear(reference->getAccess(), tcu::IVec4(0xff, 0, 0, 0xff));
    782 
    783 		int x1 = (int)((width/2.0f) * (-0.9f) + (width/2.0f));
    784 		int x2 = (int)((width/2.0f) * 0.9f + (width/2.0f));
    785 		int y1 = (int)((height/2.0f) * (-0.9f) + (height/2.0f));
    786 		int y2 = (int)((height/2.0f) * 0.9f + (height/2.0f));
    787 
    788 		for (int x = x1; x <= x2; x++)
    789 		{
    790 			for (int y = y1; y <= y2; y++)
    791 			{
    792 				float t = ((float)(x-x1) / (x2 - x1));
    793 				float s = ((float)(y-y1) / (y2-y1));
    794 				bool isUpper = t > s;
    795 
    796 				tcu::Vec4 a(colors[0],		colors[1],		colors[2],		colors[3]);
    797 				tcu::Vec4 b(colors[4 + 0],	colors[4 + 1],	colors[4 + 2],	colors[4 + 3]);
    798 				tcu::Vec4 c(colors[8 + 0],	colors[8 + 1],	colors[8 + 2],	colors[8 + 3]);
    799 				tcu::Vec4 d(colors[12 + 0],	colors[12 + 1],	colors[12 + 2],	colors[12 + 3]);
    800 
    801 
    802 				tcu::Vec4 color;
    803 
    804 				if (isUpper)
    805 					color = a * (1.0f - t)  + b * (t - s) + s * c;
    806 				else
    807 					color = a * (1.0f - s)  + d * (s - t) + t * c;
    808 
    809 				int red		= deClamp32((int)(255.0f * color.x()), 0, 255);
    810 				int green	= deClamp32((int)(255.0f * color.y()), 0, 255);
    811 				int blue	= deClamp32((int)(255.0f * color.z()), 0, 255);
    812 				int alpha	= deClamp32((int)(255.0f * color.w()), 0, 255);
    813 
    814 				reference->setPixel(x, y, tcu::RGBA(red, green, blue, alpha));
    815 			}
    816 		}
    817 	}
    818 }
    819 
    820 class GLES2ShaderSharingTest : public GLES2SharingTest
    821 {
    822 public:
    823 					GLES2ShaderSharingTest	(EglTestContext& eglTestCtx, const char* name, const char* desc, GLenum shaderType, const GLES2SharingTest::TestSpec& spec);
    824 
    825 private:
    826 	GLuint			m_shader;
    827 	GLenum			m_shaderType;
    828 
    829 	virtual void	createResource		(void);
    830 	virtual void 	destroyResource		(void);
    831 	virtual void	renderResource		(tcu::Surface* screen, tcu::Surface* reference);
    832 
    833 };
    834 
    835 GLES2ShaderSharingTest::GLES2ShaderSharingTest (EglTestContext& eglTestCtx, const char* name, const char* desc, GLenum shaderType, const GLES2SharingTest::TestSpec& spec)
    836 	: GLES2SharingTest	(eglTestCtx, name, desc, spec)
    837 	, m_shader			(0)
    838 	, m_shaderType		(shaderType)
    839 {
    840 }
    841 
    842 void GLES2ShaderSharingTest::createResource (void)
    843 {
    844 	const char* vertexShader = ""
    845 	"attribute mediump vec2 a_pos;\n"
    846 	"attribute mediump vec4 a_color;\n"
    847 	"varying mediump vec4 v_color;\n"
    848 	"void main(void)\n"
    849 	"{\n"
    850 	"\tv_color = a_color;\n"
    851 	"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
    852 	"}\n";
    853 
    854 	const char* fragmentShader = ""
    855 	"varying mediump vec4 v_color;\n"
    856 	"void main(void)\n"
    857 	"{\n"
    858 	"\tgl_FragColor = v_color;\n"
    859 	"}\n";
    860 
    861 
    862 	m_shader = glCreateShader(m_shaderType);
    863 	GLU_CHECK_MSG("glCreateShader()");
    864 
    865 	switch (m_shaderType)
    866 	{
    867 		case GL_VERTEX_SHADER:
    868 			GLU_CHECK_CALL(glShaderSource(m_shader, 1, &vertexShader, NULL));
    869 			break;
    870 
    871 		case GL_FRAGMENT_SHADER:
    872 			GLU_CHECK_CALL(glShaderSource(m_shader, 1, &fragmentShader, NULL));
    873 			break;
    874 
    875 		default:
    876 			DE_ASSERT(false);
    877 	}
    878 
    879 	GLU_CHECK_CALL(glCompileShader(m_shader));
    880 
    881 	GLint status = 0;
    882 	GLU_CHECK_CALL(glGetShaderiv(m_shader, GL_COMPILE_STATUS, &status));
    883 
    884 	if (!status)
    885 	{
    886 		char buffer[256];
    887 		GLU_CHECK_CALL(glGetShaderInfoLog(m_shader, 256, NULL, buffer));
    888 
    889 		m_log << tcu::TestLog::Message << "Failed to compile shader" << tcu::TestLog::EndMessage;
    890 
    891 		switch (m_shaderType)
    892 		{
    893 			case GL_VERTEX_SHADER:
    894 				m_log << tcu::TestLog::Message << vertexShader << tcu::TestLog::EndMessage;
    895 				break;
    896 
    897 			case GL_FRAGMENT_SHADER:
    898 				m_log << tcu::TestLog::Message << fragmentShader << tcu::TestLog::EndMessage;
    899 				break;
    900 
    901 			default:
    902 				DE_ASSERT(false);
    903 		}
    904 
    905 		m_log << tcu::TestLog::Message << buffer << tcu::TestLog::EndMessage;
    906 		TCU_FAIL("Failed to compile shader");
    907 	}
    908 }
    909 
    910 void GLES2ShaderSharingTest::destroyResource (void)
    911 {
    912 	GLU_CHECK_CALL(glDeleteShader(m_shader));
    913 }
    914 
    915 void GLES2ShaderSharingTest::renderResource (tcu::Surface* screen, tcu::Surface* reference)
    916 {
    917 	DE_ASSERT((screen && reference) || (!screen && !reference));
    918 
    919 	int width = 240;
    920 	int height = 240;
    921 
    922 	const char* vertexShader = ""
    923 	"attribute mediump vec2 a_pos;\n"
    924 	"attribute mediump vec4 a_color;\n"
    925 	"varying mediump vec4 v_color;\n"
    926 	"void main(void)\n"
    927 	"{\n"
    928 	"\tv_color = a_color;\n"
    929 	"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
    930 	"}\n";
    931 
    932 	const char* fragmentShader = ""
    933 	"varying mediump vec4 v_color;\n"
    934 	"void main(void)\n"
    935 	"{\n"
    936 	"\tgl_FragColor = v_color;\n"
    937 	"}\n";
    938 
    939 
    940 	GLuint otherShader = (GLuint)-1;
    941 
    942 	switch (m_shaderType)
    943 	{
    944 		case GL_VERTEX_SHADER:
    945 			otherShader = glCreateShader(GL_FRAGMENT_SHADER);
    946 			GLU_CHECK_MSG("glCreateShader()");
    947 			GLU_CHECK_CALL(glShaderSource(otherShader, 1, &fragmentShader, NULL));
    948 			break;
    949 
    950 		case GL_FRAGMENT_SHADER:
    951 			otherShader = glCreateShader(GL_VERTEX_SHADER);
    952 			GLU_CHECK_MSG("glCreateShader()");
    953 			GLU_CHECK_CALL(glShaderSource(otherShader, 1, &vertexShader, NULL));
    954 			break;
    955 
    956 		default:
    957 			DE_ASSERT(false);
    958 	}
    959 
    960 	GLU_CHECK_CALL(glCompileShader(otherShader));
    961 
    962 	GLint status = 0;
    963 	GLU_CHECK_CALL(glGetShaderiv(otherShader, GL_COMPILE_STATUS, &status));
    964 
    965 	if (!status)
    966 	{
    967 		char buffer[256];
    968 		GLU_CHECK_CALL(glGetShaderInfoLog(otherShader, 256, NULL, buffer));
    969 
    970 		m_log << tcu::TestLog::Message << "Failed to compile shader" << tcu::TestLog::EndMessage;
    971 
    972 		switch (m_shaderType)
    973 		{
    974 			case GL_FRAGMENT_SHADER:
    975 				m_log << tcu::TestLog::Message << vertexShader << tcu::TestLog::EndMessage;
    976 				break;
    977 
    978 			case GL_VERTEX_SHADER:
    979 				m_log << tcu::TestLog::Message << fragmentShader << tcu::TestLog::EndMessage;
    980 				break;
    981 
    982 			default:
    983 				DE_ASSERT(false);
    984 		}
    985 
    986 		m_log << tcu::TestLog::Message << buffer << tcu::TestLog::EndMessage;
    987 		TCU_FAIL("Failed to compile shader");
    988 	}
    989 
    990 	GLuint program = glCreateProgram();
    991 	GLU_CHECK_MSG("glCreateProgram()");
    992 
    993 	GLU_CHECK_CALL(glAttachShader(program, m_shader));
    994 	GLU_CHECK_CALL(glAttachShader(program, otherShader));
    995 
    996 	GLU_CHECK_CALL(glLinkProgram(program));
    997 	GLU_CHECK_CALL(glDeleteShader(otherShader));
    998 
    999 	status = 0;
   1000 	GLU_CHECK_CALL(glGetProgramiv(program, GL_LINK_STATUS, &status));
   1001 
   1002 	if (!status)
   1003 	{
   1004 		char buffer[256];
   1005 		GLU_CHECK_CALL(glGetProgramInfoLog(program, 256, NULL, buffer));
   1006 
   1007 		m_log << tcu::TestLog::Message << "Failed to link program" << tcu::TestLog::EndMessage;
   1008 
   1009 		m_log << tcu::TestLog::Message << vertexShader << tcu::TestLog::EndMessage;
   1010 		m_log << tcu::TestLog::Message << fragmentShader << tcu::TestLog::EndMessage;
   1011 		m_log << tcu::TestLog::Message << buffer << tcu::TestLog::EndMessage;
   1012 		TCU_FAIL("Failed to link program");
   1013 	}
   1014 
   1015 	if (screen)
   1016 	{
   1017 		width = screen->getWidth();
   1018 		height = screen->getHeight();
   1019 	}
   1020 
   1021 	static const GLfloat coords[] = {
   1022 		-0.9f, -0.9f,
   1023 		 0.9f, -0.9f,
   1024 		 0.9f,  0.9f,
   1025 		-0.9f,  0.9f
   1026 	};
   1027 
   1028 	static const GLfloat colors [] = {
   1029 		0.0f, 0.0f, 0.0f, 1.0f,
   1030 		1.0f, 0.0f, 0.0f, 1.0f,
   1031 		0.0f, 1.0f, 0.0f, 1.0f,
   1032 		0.0f, 0.0f, 1.0f, 1.0f
   1033 	};
   1034 
   1035 	static const GLushort indices[] = {
   1036 		0, 1, 2,
   1037 		2, 3, 0
   1038 	};
   1039 
   1040 	GLU_CHECK_CALL(glViewport(0, 0, width, height));
   1041 
   1042 	GLU_CHECK_CALL(glClearColor(1.0f, 0.0f, 0.0f, 1.0f));
   1043 	GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
   1044 
   1045 	GLU_CHECK_CALL(glUseProgram(program));
   1046 
   1047 	GLuint coordLocation = glGetAttribLocation(program, "a_pos");
   1048 	GLU_CHECK_MSG("glGetAttribLocation()");
   1049 	TCU_CHECK(coordLocation != (GLuint)-1);
   1050 
   1051 	GLuint colorLocation = glGetAttribLocation(program, "a_color");
   1052 	GLU_CHECK_MSG("glGetAttribLocation()");
   1053 	TCU_CHECK(colorLocation != (GLuint)-1);
   1054 
   1055 	GLU_CHECK_CALL(glEnableVertexAttribArray(colorLocation));
   1056 	GLU_CHECK_CALL(glEnableVertexAttribArray(coordLocation));
   1057 
   1058 	GLU_CHECK_CALL(glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, colors));
   1059 	GLU_CHECK_CALL(glVertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, coords));
   1060 
   1061 	GLU_CHECK_CALL(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices));
   1062 	GLU_CHECK_CALL(glDisableVertexAttribArray(coordLocation));
   1063 	GLU_CHECK_CALL(glDisableVertexAttribArray(colorLocation));
   1064 	GLU_CHECK_CALL(glUseProgram(0));
   1065 
   1066 	if (screen)
   1067 	{
   1068 		glReadPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen->getAccess().getDataPtr());
   1069 
   1070 		tcu::clear(reference->getAccess(), tcu::IVec4(0xff, 0, 0, 0xff));
   1071 
   1072 		int x1 = (int)((width/2.0f) * (-0.9f) + (width/2.0f));
   1073 		int x2 = (int)((width/2.0f) * 0.9f + (width/2.0f));
   1074 		int y1 = (int)((height/2.0f) * (-0.9f) + (height/2.0f));
   1075 		int y2 = (int)((height/2.0f) * 0.9f + (height/2.0f));
   1076 
   1077 		for (int x = x1; x <= x2; x++)
   1078 		{
   1079 			for (int y = y1; y <= y2; y++)
   1080 			{
   1081 				float t = ((float)(x-x1) / (x2 - x1));
   1082 				float s = ((float)(y-y1) / (y2-y1));
   1083 				bool isUpper = t > s;
   1084 
   1085 				tcu::Vec4 a(colors[0],		colors[1],		colors[2],		colors[3]);
   1086 				tcu::Vec4 b(colors[4 + 0],	colors[4 + 1],	colors[4 + 2],	colors[4 + 3]);
   1087 				tcu::Vec4 c(colors[8 + 0],	colors[8 + 1],	colors[8 + 2],	colors[8 + 3]);
   1088 				tcu::Vec4 d(colors[12 + 0],	colors[12 + 1],	colors[12 + 2],	colors[12 + 3]);
   1089 
   1090 
   1091 				tcu::Vec4 color;
   1092 
   1093 				if (isUpper)
   1094 					color = a * (1.0f - t)  + b * (t - s) + s * c;
   1095 				else
   1096 					color = a * (1.0f - s)  + d * (s - t) + t * c;
   1097 
   1098 				int red		= deClamp32((int)(255.0f * color.x()), 0, 255);
   1099 				int green	= deClamp32((int)(255.0f * color.y()), 0, 255);
   1100 				int blue	= deClamp32((int)(255.0f * color.z()), 0, 255);
   1101 				int alpha	= deClamp32((int)(255.0f * color.w()), 0, 255);
   1102 
   1103 				reference->setPixel(x, y, tcu::RGBA(red, green, blue, alpha));
   1104 			}
   1105 		}
   1106 	}
   1107 }
   1108 
   1109 SharingTests::SharingTests (EglTestContext& eglTestCtx)
   1110 	: TestCaseGroup	(eglTestCtx, "sharing", "Sharing test cases")
   1111 {
   1112 }
   1113 
   1114 void SharingTests::init (void)
   1115 {
   1116 	TestCaseGroup* gles2 = new TestCaseGroup(m_eglTestCtx, "gles2", "OpenGL ES 2 sharing test");
   1117 
   1118 	TestCaseGroup* context = new TestCaseGroup(m_eglTestCtx, "context", "Context creation and destruction tests");
   1119 
   1120 	{
   1121 		GLES2SharingTest::TestSpec spec;
   1122 		spec.destroyContextBFirst	= false;
   1123 		spec.useResource			= false;
   1124 		spec.destroyOnContexB		= false;
   1125 		spec.initializeData			= true;
   1126 		spec.renderOnContexA		= true;
   1127 		spec.renderOnContexB		= true;
   1128 		spec.verifyOnContexA		= true;
   1129 		spec.verifyOnContexB		= true;
   1130 
   1131 		context->addChild(new GLES2SharingTest(m_eglTestCtx, "create_destroy", "Simple context creation and destruction", spec));
   1132 	}
   1133 	{
   1134 		GLES2SharingTest::TestSpec spec;
   1135 		spec.destroyContextBFirst	= true;
   1136 		spec.useResource			= false;
   1137 		spec.destroyOnContexB		= false;
   1138 		spec.initializeData			= false;
   1139 		spec.renderOnContexA		= false;
   1140 		spec.renderOnContexB		= false;
   1141 		spec.verifyOnContexA		= false;
   1142 		spec.verifyOnContexB		= false;
   1143 
   1144 		context->addChild(new GLES2SharingTest(m_eglTestCtx, "create_destroy_mixed", "Simple context creation and destruction test with different destruction order", spec));
   1145 	}
   1146 
   1147 	gles2->addChild(context);
   1148 
   1149 	TestCaseGroup* buffer = new TestCaseGroup(m_eglTestCtx, "buffer", "Buffer creation, destruction and rendering test");
   1150 
   1151 	{
   1152 		GLES2SharingTest::TestSpec spec;
   1153 		spec.destroyContextBFirst	= false;
   1154 		spec.useResource			= true;
   1155 		spec.destroyOnContexB		= false;
   1156 		spec.initializeData			= true;
   1157 		spec.renderOnContexA		= false;
   1158 		spec.renderOnContexB		= false;
   1159 		spec.verifyOnContexA		= false;
   1160 		spec.verifyOnContexB		= false;
   1161 
   1162 		buffer->addChild(new GLES2BufferSharingTest(m_eglTestCtx, "create_delete", "Create and delete on shared context", spec));
   1163 	}
   1164 	{
   1165 		GLES2SharingTest::TestSpec spec;
   1166 		spec.destroyContextBFirst	= false;
   1167 		spec.useResource			= true;
   1168 		spec.destroyOnContexB		= true;
   1169 		spec.initializeData			= true;
   1170 		spec.renderOnContexA		= false;
   1171 		spec.renderOnContexB		= false;
   1172 		spec.verifyOnContexA		= false;
   1173 		spec.verifyOnContexB		= false;
   1174 
   1175 		buffer->addChild(new GLES2BufferSharingTest(m_eglTestCtx, "create_delete_mixed", "Create and delet on different contexts", spec));
   1176 	}
   1177 	{
   1178 		GLES2SharingTest::TestSpec spec;
   1179 		spec.destroyContextBFirst	= false;
   1180 		spec.useResource			= true;
   1181 		spec.destroyOnContexB		= false;
   1182 		spec.initializeData			= true;
   1183 		spec.renderOnContexA		= true;
   1184 		spec.renderOnContexB		= true;
   1185 		spec.verifyOnContexA		= true;
   1186 		spec.verifyOnContexB		= true;
   1187 
   1188 		buffer->addChild(new GLES2BufferSharingTest(m_eglTestCtx, "render", "Create, rendering on two different contexts and delete", spec));
   1189 	}
   1190 
   1191 	gles2->addChild(buffer);
   1192 
   1193 	TestCaseGroup* texture = new TestCaseGroup(m_eglTestCtx, "texture", "Texture creation, destruction and rendering tests");
   1194 
   1195 	{
   1196 		GLES2SharingTest::TestSpec spec;
   1197 		spec.destroyContextBFirst	= false;
   1198 		spec.useResource			= true;
   1199 		spec.destroyOnContexB		= false;
   1200 		spec.initializeData			= true;
   1201 		spec.renderOnContexA		= false;
   1202 		spec.renderOnContexB		= false;
   1203 		spec.verifyOnContexA		= false;
   1204 		spec.verifyOnContexB		= false;
   1205 
   1206 		texture->addChild(new GLES2TextureSharingTest(m_eglTestCtx, "create_delete", "Create and delete on shared context", spec));
   1207 	}
   1208 	{
   1209 		GLES2SharingTest::TestSpec spec;
   1210 		spec.destroyContextBFirst	= false;
   1211 		spec.useResource			= true;
   1212 		spec.destroyOnContexB		= true;
   1213 		spec.initializeData			= true;
   1214 		spec.renderOnContexA		= false;
   1215 		spec.renderOnContexB		= false;
   1216 		spec.verifyOnContexA		= false;
   1217 		spec.verifyOnContexB		= false;
   1218 
   1219 		texture->addChild(new GLES2TextureSharingTest(m_eglTestCtx, "create_delete_mixed", "Create and delete on different contexts", spec));
   1220 	}
   1221 	{
   1222 		GLES2SharingTest::TestSpec spec;
   1223 		spec.destroyContextBFirst	= false;
   1224 		spec.useResource			= true;
   1225 		spec.destroyOnContexB		= false;
   1226 		spec.initializeData			= true;
   1227 		spec.renderOnContexA		= true;
   1228 		spec.renderOnContexB		= true;
   1229 		spec.verifyOnContexA		= true;
   1230 		spec.verifyOnContexB		= true;
   1231 
   1232 		texture->addChild(new GLES2TextureSharingTest(m_eglTestCtx, "render", "Create, render in two contexts and delete", spec));
   1233 	}
   1234 
   1235 	gles2->addChild(texture);
   1236 
   1237 	TestCaseGroup* program = new TestCaseGroup(m_eglTestCtx, "program", "Program creation, destruction and rendering test");
   1238 
   1239 	{
   1240 		GLES2SharingTest::TestSpec spec;
   1241 		spec.destroyContextBFirst	= false;
   1242 		spec.useResource			= true;
   1243 		spec.destroyOnContexB		= false;
   1244 		spec.initializeData			= true;
   1245 		spec.renderOnContexA		= false;
   1246 		spec.renderOnContexB		= false;
   1247 		spec.verifyOnContexA		= false;
   1248 		spec.verifyOnContexB		= false;
   1249 
   1250 		program->addChild(new GLES2ProgramSharingTest(m_eglTestCtx, "create_delete", "Create and delete on shared context", spec));
   1251 	}
   1252 	{
   1253 		GLES2SharingTest::TestSpec spec;
   1254 		spec.destroyContextBFirst	= false;
   1255 		spec.useResource			= true;
   1256 		spec.destroyOnContexB		= true;
   1257 		spec.initializeData			= true;
   1258 		spec.renderOnContexA		= false;
   1259 		spec.renderOnContexB		= false;
   1260 		spec.verifyOnContexA		= false;
   1261 		spec.verifyOnContexB		= false;
   1262 
   1263 		program->addChild(new GLES2ProgramSharingTest(m_eglTestCtx, "create_delete_mixed", "Create and delete on different contexts", spec));
   1264 	}
   1265 	{
   1266 		GLES2SharingTest::TestSpec spec;
   1267 		spec.destroyContextBFirst	= false;
   1268 		spec.useResource			= true;
   1269 		spec.destroyOnContexB		= false;
   1270 		spec.initializeData			= true;
   1271 		spec.renderOnContexA		= true;
   1272 		spec.renderOnContexB		= true;
   1273 		spec.verifyOnContexA		= true;
   1274 		spec.verifyOnContexB		= true;
   1275 
   1276 		program->addChild(new GLES2ProgramSharingTest(m_eglTestCtx, "render", "Create, render in two contexts and delete", spec));
   1277 	}
   1278 
   1279 	gles2->addChild(program);
   1280 
   1281 	TestCaseGroup* shader = new TestCaseGroup(m_eglTestCtx, "shader", "Shader creation, destruction and rendering test");
   1282 
   1283 	{
   1284 		GLES2SharingTest::TestSpec spec;
   1285 		spec.destroyContextBFirst	= false;
   1286 		spec.useResource			= true;
   1287 		spec.destroyOnContexB		= false;
   1288 		spec.initializeData			= true;
   1289 		spec.renderOnContexA		= false;
   1290 		spec.renderOnContexB		= false;
   1291 		spec.verifyOnContexA		= false;
   1292 		spec.verifyOnContexB		= false;
   1293 
   1294 		shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "create_delete_vert", "Create and delete on shared context", GL_VERTEX_SHADER, spec));
   1295 	}
   1296 	{
   1297 		GLES2SharingTest::TestSpec spec;
   1298 		spec.destroyContextBFirst	= false;
   1299 		spec.useResource			= true;
   1300 		spec.destroyOnContexB		= true;
   1301 		spec.initializeData			= true;
   1302 		spec.renderOnContexA		= false;
   1303 		spec.renderOnContexB		= false;
   1304 		spec.verifyOnContexA		= false;
   1305 		spec.verifyOnContexB		= false;
   1306 
   1307 		shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "create_delete_mixed_vert", "Create and delete on different contexts", GL_VERTEX_SHADER, spec));
   1308 	}
   1309 	{
   1310 		GLES2SharingTest::TestSpec spec;
   1311 		spec.destroyContextBFirst	= false;
   1312 		spec.useResource			= true;
   1313 		spec.destroyOnContexB		= false;
   1314 		spec.initializeData			= true;
   1315 		spec.renderOnContexA		= true;
   1316 		spec.renderOnContexB		= true;
   1317 		spec.verifyOnContexA		= true;
   1318 		spec.verifyOnContexB		= true;
   1319 
   1320 		shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "render_vert", "Create, render on two contexts and delete", GL_VERTEX_SHADER, spec));
   1321 	}
   1322 	{
   1323 		GLES2SharingTest::TestSpec spec;
   1324 		spec.destroyContextBFirst	= false;
   1325 		spec.useResource			= true;
   1326 		spec.destroyOnContexB		= false;
   1327 		spec.initializeData			= true;
   1328 		spec.renderOnContexA		= false;
   1329 		spec.renderOnContexB		= false;
   1330 		spec.verifyOnContexA		= false;
   1331 		spec.verifyOnContexB		= false;
   1332 
   1333 		shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "create_delete_frag", "Create and delete on shared context", GL_FRAGMENT_SHADER, spec));
   1334 	}
   1335 	{
   1336 		GLES2SharingTest::TestSpec spec;
   1337 		spec.destroyContextBFirst	= false;
   1338 		spec.useResource			= true;
   1339 		spec.destroyOnContexB		= true;
   1340 		spec.initializeData			= true;
   1341 		spec.renderOnContexA		= false;
   1342 		spec.renderOnContexB		= false;
   1343 		spec.verifyOnContexA		= false;
   1344 		spec.verifyOnContexB		= false;
   1345 
   1346 		shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "create_delete_mixed_frag", "Create and delete on different contexts", GL_FRAGMENT_SHADER, spec));
   1347 	}
   1348 	{
   1349 		GLES2SharingTest::TestSpec spec;
   1350 		spec.destroyContextBFirst	= false;
   1351 		spec.useResource			= true;
   1352 		spec.destroyOnContexB		= false;
   1353 		spec.initializeData			= true;
   1354 		spec.renderOnContexA		= true;
   1355 		spec.renderOnContexB		= true;
   1356 		spec.verifyOnContexA		= true;
   1357 		spec.verifyOnContexB		= true;
   1358 
   1359 		shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "render_frag", "Create, render on two contexts and delete", GL_FRAGMENT_SHADER, spec));
   1360 	}
   1361 
   1362 
   1363 	gles2->addChild(shader);
   1364 
   1365 
   1366 	gles2->addChild(new GLES2SharingThreadedTests(m_eglTestCtx));
   1367 
   1368 	addChild(gles2);
   1369 }
   1370 
   1371 } // egl
   1372 } // deqp
   1373