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