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