• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program EGL Module
3  * ---------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief EGL 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 
createResource(void)110 	virtual void	createResource		(void)  { DE_ASSERT(false); }
destroyResource(void)111 	virtual void	destroyResource		(void)	{ DE_ASSERT(false); }
renderResource(tcu::Surface * screen,tcu::Surface * reference)112 	virtual void	renderResource		(tcu::Surface* screen, tcu::Surface* reference) { DE_UNREF(screen); DE_UNREF(reference); DE_ASSERT(false); }
113 };
114 
GLES2SharingTest(EglTestContext & eglTestCtx,const char * name,const char * desc,const TestSpec & spec)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 
init(void)123 void GLES2SharingTest::init (void)
124 {
125 	m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(2,0));
126 }
127 
createContext(EGLDisplay display,EGLContext share,EGLConfig config)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 
makeCurrent(EGLDisplay display,EGLContext context,EGLSurface surface)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 
iterate(void)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 
GLES2BufferSharingTest(EglTestContext & eglTestCtx,const char * name,const char * desc,const GLES2SharingTest::TestSpec & spec)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 
createResource(void)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 
destroyResource(void)330 void GLES2BufferSharingTest::destroyResource (void)
331 {
332 	GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_glBuffer));
333 	m_buffer.clear();
334 }
335 
renderResource(tcu::Surface * screen,tcu::Surface * reference)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, bool asColorAttachment);
471 
472 private:
473 	GLuint					m_glTexture;
474 	tcu::Texture2D			m_texture;
475 	bool					m_glTextureAsColorAttachment;
476 
477 	virtual void	createResource		(void);
478 	virtual void	destroyResource		(void);
479 	virtual void	renderResource		(tcu::Surface* screen, tcu::Surface* reference);
480 
481 };
482 
GLES2TextureSharingTest(EglTestContext & eglTestCtx,const char * name,const char * desc,const GLES2SharingTest::TestSpec & spec,bool asColorAttachment)483 GLES2TextureSharingTest::GLES2TextureSharingTest (EglTestContext& eglTestCtx, const char* name, const char* desc, const GLES2SharingTest::TestSpec& spec,  bool asColorAttachment)
484 	: GLES2SharingTest	(eglTestCtx, name, desc, spec)
485 	, m_glTexture		(0)
486 	, m_texture			(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1)
487 	, m_glTextureAsColorAttachment(asColorAttachment)
488 {
489 }
490 
createResource(void)491 void GLES2TextureSharingTest::createResource (void)
492 {
493 	int width	= 128;
494 	int	height	= 128;
495 	m_texture = tcu::Texture2D(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), width, height);
496 	m_texture.allocLevel(0);
497 
498 	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));
499 	GLU_CHECK_GLW_CALL(m_gl, genTextures(1, &m_glTexture));
500 	GLU_CHECK_GLW_CALL(m_gl, bindTexture(GL_TEXTURE_2D, m_glTexture));
501 	GLU_CHECK_GLW_CALL(m_gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
502 	GLU_CHECK_GLW_CALL(m_gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
503 	GLU_CHECK_GLW_CALL(m_gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
504 	GLU_CHECK_GLW_CALL(m_gl, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
505 	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()));
506 	GLU_CHECK_GLW_CALL(m_gl, bindTexture(GL_TEXTURE_2D, 0));
507 }
508 
destroyResource(void)509 void GLES2TextureSharingTest::destroyResource (void)
510 {
511 	GLU_CHECK_GLW_CALL(m_gl, deleteTextures(1, &m_glTexture));
512 }
513 
renderResource(tcu::Surface * screen,tcu::Surface * reference)514 void GLES2TextureSharingTest::renderResource (tcu::Surface* screen, tcu::Surface* reference)
515 {
516 	DE_ASSERT((screen && reference) || (!screen && !reference));
517 
518 	const char* vertexShader = ""
519 	"attribute mediump vec2 a_pos;\n"
520 	"attribute mediump vec2 a_texCorod;\n"
521 	"varying mediump vec2 v_texCoord;\n"
522 	"void main(void)\n"
523 	"{\n"
524 	"\tv_texCoord = a_texCorod;\n"
525 	"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
526 	"}\n";
527 
528 	const char* fragmentShader = ""
529 	"varying mediump vec2 v_texCoord;\n"
530 	"uniform sampler2D u_sampler;\n"
531 	"void main(void)\n"
532 	"{\n"
533 	"\tgl_FragColor = texture2D(u_sampler, v_texCoord);\n"
534 	"}\n";
535 
536 	glu::ShaderProgram program(m_gl, glu::makeVtxFragSources(vertexShader, fragmentShader));
537 
538 	if (!program.isOk())
539 		TCU_FAIL("Failed to compile shader program");
540 
541 	int width = 240;
542 	int height = 240;
543 
544 	if (screen)
545 	{
546 		width = screen->getWidth();
547 		height = screen->getHeight();
548 	}
549 
550 	static const GLfloat coords[] = {
551 		-1.0f, -1.0f,
552 		 1.0f, -1.0f,
553 		 1.0f,  1.0f,
554 		-1.0f,  1.0f
555 	};
556 
557 	static const GLfloat texCoords[] = {
558 		0.0f, 0.0f,
559 		1.0f, 0.0f,
560 		1.0f, 1.0f,
561 		0.0f, 1.0f
562 	};
563 
564 	static const GLushort indices[] = {
565 		0, 1, 2,
566 		2, 3, 0
567 	};
568 
569 	GLU_CHECK_GLW_CALL(m_gl, viewport(0, 0, width, height));
570 
571 	GLU_CHECK_GLW_CALL(m_gl, clearColor(1.0f, 0.0f, 0.0f, 1.0f));
572 	GLU_CHECK_GLW_CALL(m_gl, clear(GL_COLOR_BUFFER_BIT));
573 
574 	GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));
575 
576 	GLuint coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_pos");
577 	GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
578 	TCU_CHECK(coordLocation != (GLuint)-1);
579 
580 	GLuint texCoordLocation = m_gl.getAttribLocation(program.getProgram(), "a_texCorod");
581 	GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
582 	TCU_CHECK(texCoordLocation != (GLuint)-1);
583 
584 
585 	GLuint samplerLocation = m_gl.getUniformLocation(program.getProgram(), "u_sampler");
586 	GLU_CHECK_GLW_MSG(m_gl, "glGetUniformLocation()");
587 	TCU_CHECK(samplerLocation != (GLuint)-1);
588 
589 	GLU_CHECK_GLW_CALL(m_gl, activeTexture(GL_TEXTURE0));
590 	GLU_CHECK_GLW_CALL(m_gl, bindTexture(GL_TEXTURE_2D, m_glTexture));
591 
592 	GLU_CHECK_GLW_CALL(m_gl, uniform1i(samplerLocation, 0));
593 	if(!m_glTextureAsColorAttachment)
594 	{
595 
596 		GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(texCoordLocation));
597 		GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation));
598 
599 		GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, texCoords));
600 		GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, coords));
601 
602 		GLU_CHECK_GLW_CALL(m_gl, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices));
603 		GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(coordLocation));
604 		GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(texCoordLocation));
605 
606 		GLU_CHECK_GLW_CALL(m_gl, bindTexture(GL_TEXTURE_2D, 0));
607 		GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
608 
609 		if (screen)
610 		{
611 			m_gl.readPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen->getAccess().getDataPtr());
612 
613 			for (int x = 0; x < width; x++)
614 			{
615 				for (int y = 0; y < height; y++)
616 				{
617 					float t = ((float)x / ((float)width - 1.0f));
618 					float s = ((float)y / ((float)height - 1.0f));
619 					float lod = 0.0f;
620 
621 					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);
622 
623 					int r = deClamp32((int)(255.0f * color.x()), 0, 255);
624 					int g = deClamp32((int)(255.0f * color.y()), 0, 255);
625 					int b = deClamp32((int)(255.0f * color.z()), 0, 255);
626 					int a = deClamp32((int)(255.0f * color.w()), 0, 255);
627 
628 					reference->setPixel(x, y, tcu::RGBA(r, g, b, a));
629 				}
630 			}
631 		}
632 	}
633 	else
634 	{
635 		DE_ASSERT(m_glTextureAsColorAttachment);
636 
637 		for(int i=0; i < 2; i++)
638 		{
639 			/* Draw left half of rectangle */
640 			{
641 				GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f };
642 				GLfloat texcoords[] = {0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 1.0f, 0.0f, 1.0f};
643 				GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(texCoordLocation));
644 				GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation));
645 
646 				GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords));
647 				GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
648 				GLU_CHECK_GLW_CALL(m_gl, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices));
649 
650 			}
651 			/* Bind the m_glTexture as user fbo color attachments */
652 			{
653 				GLuint fbo = 0;
654 				GLU_CHECK_GLW_CALL(m_gl, bindTexture(GL_TEXTURE_2D, m_glTexture));
655 				GLU_CHECK_GLW_CALL(m_gl, genFramebuffers(1, &fbo));
656 				GLU_CHECK_GLW_CALL(m_gl, bindFramebuffer(GL_FRAMEBUFFER, fbo));
657 				GLU_CHECK_GLW_CALL(m_gl, framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_glTexture, 0));
658 				GLU_CHECK_GLW_CALL(m_gl, checkFramebufferStatus(GL_FRAMEBUFFER));
659 				GLubyte data[] = { 0, 0, 0, 0 };
660 				m_gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
661 				GLU_CHECK_GLW_CALL(m_gl, bindFramebuffer(GL_FRAMEBUFFER, 0));
662 				GLU_CHECK_GLW_CALL(m_gl, deleteFramebuffers(1, &fbo));
663 			}
664 			/* Draw right half of rectangle */
665 			{
666 				GLfloat vertices[] = { 0.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f};
667 				GLfloat texcoords[] = {0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.5f, 1.0f};
668 				GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(texCoordLocation));
669 				GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation));
670 
671 				GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords));
672 				GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
673 				GLU_CHECK_GLW_CALL(m_gl, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices));
674 			}
675 
676 			if(0 == i)
677 			{
678 				/* Get the reference data */
679 				m_gl.readPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, reference->getAccess().getDataPtr());
680 			}
681 			else
682 			{
683 				m_gl.readPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen->getAccess().getDataPtr());
684 			}
685 		}
686 	}
687 
688 }
689 
690 class GLES2ProgramSharingTest : public GLES2SharingTest
691 {
692 public:
693 						GLES2ProgramSharingTest	(EglTestContext& eglTestCtx, const char* name, const char* desc, const GLES2SharingTest::TestSpec& spec);
694 
695 private:
696 	glu::ShaderProgram*	m_program;
697 
698 	virtual void		createResource			(void);
699 	virtual void		destroyResource			(void);
700 	virtual void		renderResource			(tcu::Surface* screen, tcu::Surface* reference);
701 
702 };
703 
GLES2ProgramSharingTest(EglTestContext & eglTestCtx,const char * name,const char * desc,const GLES2SharingTest::TestSpec & spec)704 GLES2ProgramSharingTest::GLES2ProgramSharingTest (EglTestContext& eglTestCtx, const char* name, const char* desc, const GLES2SharingTest::TestSpec& spec)
705 	: GLES2SharingTest	(eglTestCtx, name, desc, spec)
706 	, m_program			(DE_NULL)
707 {
708 }
709 
createResource(void)710 void GLES2ProgramSharingTest::createResource (void)
711 {
712 	const char* vertexShader = ""
713 	"attribute mediump vec2 a_pos;\n"
714 	"attribute mediump vec4 a_color;\n"
715 	"varying mediump vec4 v_color;\n"
716 	"void main(void)\n"
717 	"{\n"
718 	"\tv_color = a_color;\n"
719 	"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
720 	"}\n";
721 
722 	const char* fragmentShader = ""
723 	"varying mediump vec4 v_color;\n"
724 	"void main(void)\n"
725 	"{\n"
726 	"\tgl_FragColor = v_color;\n"
727 	"}\n";
728 
729 	m_program = new glu::ShaderProgram(m_gl, glu::makeVtxFragSources(vertexShader, fragmentShader));
730 
731 	if (!m_program->isOk())
732 		TCU_FAIL("Failed to compile shader program");
733 }
734 
destroyResource(void)735 void GLES2ProgramSharingTest::destroyResource (void)
736 {
737 	delete m_program;
738 }
739 
renderResource(tcu::Surface * screen,tcu::Surface * reference)740 void GLES2ProgramSharingTest::renderResource (tcu::Surface* screen, tcu::Surface* reference)
741 {
742 	DE_ASSERT((screen && reference) || (!screen && !reference));
743 
744 	int width = 240;
745 	int height = 240;
746 
747 	if (screen)
748 	{
749 		width = screen->getWidth();
750 		height = screen->getHeight();
751 	}
752 
753 	static const GLfloat coords[] = {
754 		-0.9f, -0.9f,
755 		 0.9f, -0.9f,
756 		 0.9f,  0.9f,
757 		-0.9f,  0.9f
758 	};
759 
760 	static const GLfloat colors [] = {
761 		0.0f, 0.0f, 0.0f, 1.0f,
762 		1.0f, 0.0f, 0.0f, 1.0f,
763 		0.0f, 1.0f, 0.0f, 1.0f,
764 		0.0f, 0.0f, 1.0f, 1.0f
765 	};
766 
767 	static const GLushort indices[] = {
768 		0, 1, 2,
769 		2, 3, 0
770 	};
771 
772 	GLU_CHECK_GLW_CALL(m_gl, viewport(0, 0, width, height));
773 
774 	GLU_CHECK_GLW_CALL(m_gl, clearColor(1.0f, 0.0f, 0.0f, 1.0f));
775 	GLU_CHECK_GLW_CALL(m_gl, clear(GL_COLOR_BUFFER_BIT));
776 
777 	GLU_CHECK_GLW_CALL(m_gl, useProgram(m_program->getProgram()));
778 
779 	GLuint coordLocation = m_gl.getAttribLocation(m_program->getProgram(), "a_pos");
780 	GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
781 	TCU_CHECK(coordLocation != (GLuint)-1);
782 
783 	GLuint colorLocation = m_gl.getAttribLocation(m_program->getProgram(), "a_color");
784 	GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
785 	TCU_CHECK(colorLocation != (GLuint)-1);
786 
787 	GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(colorLocation));
788 	GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation));
789 
790 	GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, colors));
791 	GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, coords));
792 
793 	GLU_CHECK_GLW_CALL(m_gl, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices));
794 	GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(coordLocation));
795 	GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(colorLocation));
796 	GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
797 
798 	if (screen)
799 	{
800 		m_gl.readPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen->getAccess().getDataPtr());
801 
802 		tcu::clear(reference->getAccess(), tcu::IVec4(0xff, 0, 0, 0xff));
803 
804 		int x1 = (int)(((float)width/2.0f)  * (-0.9f) + ((float)width/2.0f));
805 		int x2 = (int)(((float)width/2.0f)  *   0.9f  + ((float)width/2.0f));
806 		int y1 = (int)(((float)height/2.0f) * (-0.9f) + ((float)height/2.0f));
807 		int y2 = (int)(((float)height/2.0f) *   0.9f  + ((float)height/2.0f));
808 
809 		for (int x = x1; x <= x2; x++)
810 		{
811 			for (int y = y1; y <= y2; y++)
812 			{
813 				float t = ((float)(x-x1) / (float)(x2-x1));
814 				float s = ((float)(y-y1) / (float)(y2-y1));
815 				bool isUpper = t > s;
816 
817 				tcu::Vec4 a(colors[0],		colors[1],		colors[2],		colors[3]);
818 				tcu::Vec4 b(colors[4 + 0],	colors[4 + 1],	colors[4 + 2],	colors[4 + 3]);
819 				tcu::Vec4 c(colors[8 + 0],	colors[8 + 1],	colors[8 + 2],	colors[8 + 3]);
820 				tcu::Vec4 d(colors[12 + 0],	colors[12 + 1],	colors[12 + 2],	colors[12 + 3]);
821 
822 
823 				tcu::Vec4 color;
824 
825 				if (isUpper)
826 					color = a * (1.0f - t)  + b * (t - s) + s * c;
827 				else
828 					color = a * (1.0f - s)  + d * (s - t) + t * c;
829 
830 				int red		= deClamp32((int)(255.0f * color.x()), 0, 255);
831 				int green	= deClamp32((int)(255.0f * color.y()), 0, 255);
832 				int blue	= deClamp32((int)(255.0f * color.z()), 0, 255);
833 				int alpha	= deClamp32((int)(255.0f * color.w()), 0, 255);
834 
835 				reference->setPixel(x, y, tcu::RGBA(red, green, blue, alpha));
836 			}
837 		}
838 	}
839 }
840 
841 class GLES2ShaderSharingTest : public GLES2SharingTest
842 {
843 public:
844 					GLES2ShaderSharingTest	(EglTestContext& eglTestCtx, const char* name, const char* desc, GLenum shaderType, const GLES2SharingTest::TestSpec& spec);
845 
846 private:
847 	GLuint			m_shader;
848 	GLenum			m_shaderType;
849 
850 	virtual void	createResource		(void);
851 	virtual void	destroyResource		(void);
852 	virtual void	renderResource		(tcu::Surface* screen, tcu::Surface* reference);
853 
854 };
855 
GLES2ShaderSharingTest(EglTestContext & eglTestCtx,const char * name,const char * desc,GLenum shaderType,const GLES2SharingTest::TestSpec & spec)856 GLES2ShaderSharingTest::GLES2ShaderSharingTest (EglTestContext& eglTestCtx, const char* name, const char* desc, GLenum shaderType, const GLES2SharingTest::TestSpec& spec)
857 	: GLES2SharingTest	(eglTestCtx, name, desc, spec)
858 	, m_shader			(0)
859 	, m_shaderType		(shaderType)
860 {
861 }
862 
createResource(void)863 void GLES2ShaderSharingTest::createResource (void)
864 {
865 	const char* vertexShader = ""
866 	"attribute mediump vec2 a_pos;\n"
867 	"attribute mediump vec4 a_color;\n"
868 	"varying mediump vec4 v_color;\n"
869 	"void main(void)\n"
870 	"{\n"
871 	"\tv_color = a_color;\n"
872 	"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
873 	"}\n";
874 
875 	const char* fragmentShader = ""
876 	"varying mediump vec4 v_color;\n"
877 	"void main(void)\n"
878 	"{\n"
879 	"\tgl_FragColor = v_color;\n"
880 	"}\n";
881 
882 
883 	m_shader = m_gl.createShader(m_shaderType);
884 	GLU_CHECK_GLW_MSG(m_gl, "glCreateShader()");
885 
886 	switch (m_shaderType)
887 	{
888 		case GL_VERTEX_SHADER:
889 			GLU_CHECK_GLW_CALL(m_gl, shaderSource(m_shader, 1, &vertexShader, DE_NULL));
890 			break;
891 
892 		case GL_FRAGMENT_SHADER:
893 			GLU_CHECK_GLW_CALL(m_gl, shaderSource(m_shader, 1, &fragmentShader, DE_NULL));
894 			break;
895 
896 		default:
897 			DE_ASSERT(false);
898 	}
899 
900 	GLU_CHECK_GLW_CALL(m_gl, compileShader(m_shader));
901 
902 	GLint status = 0;
903 	GLU_CHECK_GLW_CALL(m_gl, getShaderiv(m_shader, GL_COMPILE_STATUS, &status));
904 
905 	if (!status)
906 	{
907 		char buffer[256];
908 		GLU_CHECK_GLW_CALL(m_gl, getShaderInfoLog(m_shader, 256, DE_NULL, buffer));
909 
910 		m_log << tcu::TestLog::Message << "Failed to compile shader" << tcu::TestLog::EndMessage;
911 
912 		switch (m_shaderType)
913 		{
914 			case GL_VERTEX_SHADER:
915 				m_log << tcu::TestLog::Message << vertexShader << tcu::TestLog::EndMessage;
916 				break;
917 
918 			case GL_FRAGMENT_SHADER:
919 				m_log << tcu::TestLog::Message << fragmentShader << tcu::TestLog::EndMessage;
920 				break;
921 
922 			default:
923 				DE_ASSERT(false);
924 		}
925 
926 		m_log << tcu::TestLog::Message << buffer << tcu::TestLog::EndMessage;
927 		TCU_FAIL("Failed to compile shader");
928 	}
929 }
930 
destroyResource(void)931 void GLES2ShaderSharingTest::destroyResource (void)
932 {
933 	GLU_CHECK_GLW_CALL(m_gl, deleteShader(m_shader));
934 }
935 
renderResource(tcu::Surface * screen,tcu::Surface * reference)936 void GLES2ShaderSharingTest::renderResource (tcu::Surface* screen, tcu::Surface* reference)
937 {
938 	DE_ASSERT((screen && reference) || (!screen && !reference));
939 
940 	int width = 240;
941 	int height = 240;
942 
943 	const char* vertexShader = ""
944 	"attribute mediump vec2 a_pos;\n"
945 	"attribute mediump vec4 a_color;\n"
946 	"varying mediump vec4 v_color;\n"
947 	"void main(void)\n"
948 	"{\n"
949 	"\tv_color = a_color;\n"
950 	"\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
951 	"}\n";
952 
953 	const char* fragmentShader = ""
954 	"varying mediump vec4 v_color;\n"
955 	"void main(void)\n"
956 	"{\n"
957 	"\tgl_FragColor = v_color;\n"
958 	"}\n";
959 
960 
961 	GLuint otherShader = (GLuint)-1;
962 
963 	switch (m_shaderType)
964 	{
965 		case GL_VERTEX_SHADER:
966 			otherShader = m_gl.createShader(GL_FRAGMENT_SHADER);
967 			GLU_CHECK_GLW_MSG(m_gl, "glCreateShader()");
968 			GLU_CHECK_GLW_CALL(m_gl, shaderSource(otherShader, 1, &fragmentShader, DE_NULL));
969 			break;
970 
971 		case GL_FRAGMENT_SHADER:
972 			otherShader = m_gl.createShader(GL_VERTEX_SHADER);
973 			GLU_CHECK_GLW_MSG(m_gl, "glCreateShader()");
974 			GLU_CHECK_GLW_CALL(m_gl, shaderSource(otherShader, 1, &vertexShader, DE_NULL));
975 			break;
976 
977 		default:
978 			DE_ASSERT(false);
979 	}
980 
981 	GLU_CHECK_GLW_CALL(m_gl, compileShader(otherShader));
982 
983 	GLint status = 0;
984 	GLU_CHECK_GLW_CALL(m_gl, getShaderiv(otherShader, GL_COMPILE_STATUS, &status));
985 
986 	if (!status)
987 	{
988 		char buffer[256];
989 		GLU_CHECK_GLW_CALL(m_gl, getShaderInfoLog(otherShader, 256, DE_NULL, buffer));
990 
991 		m_log << tcu::TestLog::Message << "Failed to compile shader" << tcu::TestLog::EndMessage;
992 
993 		switch (m_shaderType)
994 		{
995 			case GL_FRAGMENT_SHADER:
996 				m_log << tcu::TestLog::Message << vertexShader << tcu::TestLog::EndMessage;
997 				break;
998 
999 			case GL_VERTEX_SHADER:
1000 				m_log << tcu::TestLog::Message << fragmentShader << tcu::TestLog::EndMessage;
1001 				break;
1002 
1003 			default:
1004 				DE_ASSERT(false);
1005 		}
1006 
1007 		m_log << tcu::TestLog::Message << buffer << tcu::TestLog::EndMessage;
1008 		TCU_FAIL("Failed to compile shader");
1009 	}
1010 
1011 	GLuint program = m_gl.createProgram();
1012 	GLU_CHECK_GLW_MSG(m_gl, "glCreateProgram()");
1013 
1014 	GLU_CHECK_GLW_CALL(m_gl, attachShader(program, m_shader));
1015 	GLU_CHECK_GLW_CALL(m_gl, attachShader(program, otherShader));
1016 
1017 	GLU_CHECK_GLW_CALL(m_gl, linkProgram(program));
1018 	GLU_CHECK_GLW_CALL(m_gl, deleteShader(otherShader));
1019 
1020 	status = 0;
1021 	GLU_CHECK_GLW_CALL(m_gl, getProgramiv(program, GL_LINK_STATUS, &status));
1022 
1023 	if (!status)
1024 	{
1025 		char buffer[256];
1026 		GLU_CHECK_GLW_CALL(m_gl, getProgramInfoLog(program, 256, DE_NULL, buffer));
1027 
1028 		m_log << tcu::TestLog::Message << "Failed to link program" << tcu::TestLog::EndMessage;
1029 
1030 		m_log << tcu::TestLog::Message << vertexShader << tcu::TestLog::EndMessage;
1031 		m_log << tcu::TestLog::Message << fragmentShader << tcu::TestLog::EndMessage;
1032 		m_log << tcu::TestLog::Message << buffer << tcu::TestLog::EndMessage;
1033 		TCU_FAIL("Failed to link program");
1034 	}
1035 
1036 	if (screen)
1037 	{
1038 		width = screen->getWidth();
1039 		height = screen->getHeight();
1040 	}
1041 
1042 	static const GLfloat coords[] = {
1043 		-0.9f, -0.9f,
1044 		 0.9f, -0.9f,
1045 		 0.9f,  0.9f,
1046 		-0.9f,  0.9f
1047 	};
1048 
1049 	static const GLfloat colors [] = {
1050 		0.0f, 0.0f, 0.0f, 1.0f,
1051 		1.0f, 0.0f, 0.0f, 1.0f,
1052 		0.0f, 1.0f, 0.0f, 1.0f,
1053 		0.0f, 0.0f, 1.0f, 1.0f
1054 	};
1055 
1056 	static const GLushort indices[] = {
1057 		0, 1, 2,
1058 		2, 3, 0
1059 	};
1060 
1061 	GLU_CHECK_GLW_CALL(m_gl, viewport(0, 0, width, height));
1062 
1063 	GLU_CHECK_GLW_CALL(m_gl, clearColor(1.0f, 0.0f, 0.0f, 1.0f));
1064 	GLU_CHECK_GLW_CALL(m_gl, clear(GL_COLOR_BUFFER_BIT));
1065 
1066 	GLU_CHECK_GLW_CALL(m_gl, useProgram(program));
1067 
1068 	GLuint coordLocation = m_gl.getAttribLocation(program, "a_pos");
1069 	GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
1070 	TCU_CHECK(coordLocation != (GLuint)-1);
1071 
1072 	GLuint colorLocation = m_gl.getAttribLocation(program, "a_color");
1073 	GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
1074 	TCU_CHECK(colorLocation != (GLuint)-1);
1075 
1076 	GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(colorLocation));
1077 	GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation));
1078 
1079 	GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, colors));
1080 	GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, coords));
1081 
1082 	GLU_CHECK_GLW_CALL(m_gl, drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices));
1083 	GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(coordLocation));
1084 	GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(colorLocation));
1085 	GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
1086 
1087 	if (screen)
1088 	{
1089 		m_gl.readPixels(0, 0, screen->getWidth(), screen->getHeight(), GL_RGBA, GL_UNSIGNED_BYTE, screen->getAccess().getDataPtr());
1090 
1091 		tcu::clear(reference->getAccess(), tcu::IVec4(0xff, 0, 0, 0xff));
1092 
1093 		int x1 = (int)(((float)width/2.0f)  * (-0.9f) + ((float)width/2.0f));
1094 		int x2 = (int)(((float)width/2.0f)  *   0.9f  + ((float)width/2.0f));
1095 		int y1 = (int)(((float)height/2.0f) * (-0.9f) + ((float)height/2.0f));
1096 		int y2 = (int)(((float)height/2.0f) *   0.9f  + ((float)height/2.0f));
1097 
1098 		for (int x = x1; x <= x2; x++)
1099 		{
1100 			for (int y = y1; y <= y2; y++)
1101 			{
1102 				float t = ((float)(x-x1) / (float)(x2-x1));
1103 				float s = ((float)(y-y1) / (float)(y2-y1));
1104 				bool isUpper = t > s;
1105 
1106 				tcu::Vec4 a(colors[0],		colors[1],		colors[2],		colors[3]);
1107 				tcu::Vec4 b(colors[4 + 0],	colors[4 + 1],	colors[4 + 2],	colors[4 + 3]);
1108 				tcu::Vec4 c(colors[8 + 0],	colors[8 + 1],	colors[8 + 2],	colors[8 + 3]);
1109 				tcu::Vec4 d(colors[12 + 0],	colors[12 + 1],	colors[12 + 2],	colors[12 + 3]);
1110 
1111 
1112 				tcu::Vec4 color;
1113 
1114 				if (isUpper)
1115 					color = a * (1.0f - t)  + b * (t - s) + s * c;
1116 				else
1117 					color = a * (1.0f - s)  + d * (s - t) + t * c;
1118 
1119 				int red		= deClamp32((int)(255.0f * color.x()), 0, 255);
1120 				int green	= deClamp32((int)(255.0f * color.y()), 0, 255);
1121 				int blue	= deClamp32((int)(255.0f * color.z()), 0, 255);
1122 				int alpha	= deClamp32((int)(255.0f * color.w()), 0, 255);
1123 
1124 				reference->setPixel(x, y, tcu::RGBA(red, green, blue, alpha));
1125 			}
1126 		}
1127 	}
1128 }
1129 
SharingTests(EglTestContext & eglTestCtx)1130 SharingTests::SharingTests (EglTestContext& eglTestCtx)
1131 	: TestCaseGroup	(eglTestCtx, "sharing", "Sharing test cases")
1132 {
1133 }
1134 
init(void)1135 void SharingTests::init (void)
1136 {
1137 	TestCaseGroup* gles2 = new TestCaseGroup(m_eglTestCtx, "gles2", "OpenGL ES 2 sharing test");
1138 
1139 	TestCaseGroup* context = new TestCaseGroup(m_eglTestCtx, "context", "Context creation and destruction tests");
1140 
1141 	{
1142 		GLES2SharingTest::TestSpec spec;
1143 		spec.destroyContextBFirst	= false;
1144 		spec.useResource			= false;
1145 		spec.destroyOnContexB		= false;
1146 		spec.initializeData			= true;
1147 		spec.renderOnContexA		= true;
1148 		spec.renderOnContexB		= true;
1149 		spec.verifyOnContexA		= true;
1150 		spec.verifyOnContexB		= true;
1151 
1152 		context->addChild(new GLES2SharingTest(m_eglTestCtx, "create_destroy", "Simple context creation and destruction", spec));
1153 	}
1154 	{
1155 		GLES2SharingTest::TestSpec spec;
1156 		spec.destroyContextBFirst	= true;
1157 		spec.useResource			= false;
1158 		spec.destroyOnContexB		= false;
1159 		spec.initializeData			= false;
1160 		spec.renderOnContexA		= false;
1161 		spec.renderOnContexB		= false;
1162 		spec.verifyOnContexA		= false;
1163 		spec.verifyOnContexB		= false;
1164 
1165 		context->addChild(new GLES2SharingTest(m_eglTestCtx, "create_destroy_mixed", "Simple context creation and destruction test with different destruction order", spec));
1166 	}
1167 
1168 	gles2->addChild(context);
1169 
1170 	TestCaseGroup* buffer = new TestCaseGroup(m_eglTestCtx, "buffer", "Buffer creation, destruction and rendering test");
1171 
1172 	{
1173 		GLES2SharingTest::TestSpec spec;
1174 		spec.destroyContextBFirst	= false;
1175 		spec.useResource			= true;
1176 		spec.destroyOnContexB		= false;
1177 		spec.initializeData			= true;
1178 		spec.renderOnContexA		= false;
1179 		spec.renderOnContexB		= false;
1180 		spec.verifyOnContexA		= false;
1181 		spec.verifyOnContexB		= false;
1182 
1183 		buffer->addChild(new GLES2BufferSharingTest(m_eglTestCtx, "create_delete", "Create and delete on shared context", spec));
1184 	}
1185 	{
1186 		GLES2SharingTest::TestSpec spec;
1187 		spec.destroyContextBFirst	= false;
1188 		spec.useResource			= true;
1189 		spec.destroyOnContexB		= true;
1190 		spec.initializeData			= true;
1191 		spec.renderOnContexA		= false;
1192 		spec.renderOnContexB		= false;
1193 		spec.verifyOnContexA		= false;
1194 		spec.verifyOnContexB		= false;
1195 
1196 		buffer->addChild(new GLES2BufferSharingTest(m_eglTestCtx, "create_delete_mixed", "Create and delet on different contexts", spec));
1197 	}
1198 	{
1199 		GLES2SharingTest::TestSpec spec;
1200 		spec.destroyContextBFirst	= false;
1201 		spec.useResource			= true;
1202 		spec.destroyOnContexB		= false;
1203 		spec.initializeData			= true;
1204 		spec.renderOnContexA		= true;
1205 		spec.renderOnContexB		= true;
1206 		spec.verifyOnContexA		= true;
1207 		spec.verifyOnContexB		= true;
1208 
1209 		buffer->addChild(new GLES2BufferSharingTest(m_eglTestCtx, "render", "Create, rendering on two different contexts and delete", spec));
1210 	}
1211 
1212 	gles2->addChild(buffer);
1213 
1214 	TestCaseGroup* texture = new TestCaseGroup(m_eglTestCtx, "texture", "Texture creation, destruction and rendering tests");
1215 
1216 	{
1217 		GLES2SharingTest::TestSpec spec;
1218 		spec.destroyContextBFirst	= false;
1219 		spec.useResource			= true;
1220 		spec.destroyOnContexB		= false;
1221 		spec.initializeData			= true;
1222 		spec.renderOnContexA		= false;
1223 		spec.renderOnContexB		= false;
1224 		spec.verifyOnContexA		= false;
1225 		spec.verifyOnContexB		= false;
1226 
1227 		texture->addChild(new GLES2TextureSharingTest(m_eglTestCtx, "create_delete", "Create and delete on shared context", spec, false));
1228 	}
1229 	{
1230 		GLES2SharingTest::TestSpec spec;
1231 		spec.destroyContextBFirst	= false;
1232 		spec.useResource			= true;
1233 		spec.destroyOnContexB		= true;
1234 		spec.initializeData			= true;
1235 		spec.renderOnContexA		= false;
1236 		spec.renderOnContexB		= false;
1237 		spec.verifyOnContexA		= false;
1238 		spec.verifyOnContexB		= false;
1239 
1240 		texture->addChild(new GLES2TextureSharingTest(m_eglTestCtx, "create_delete_mixed", "Create and delete on different contexts", spec, false));
1241 	}
1242 	{
1243 		GLES2SharingTest::TestSpec spec;
1244 		spec.destroyContextBFirst	= false;
1245 		spec.useResource			= true;
1246 		spec.destroyOnContexB		= false;
1247 		spec.initializeData			= true;
1248 		spec.renderOnContexA		= true;
1249 		spec.renderOnContexB		= true;
1250 		spec.verifyOnContexA		= true;
1251 		spec.verifyOnContexB		= true;
1252 
1253 		texture->addChild(new GLES2TextureSharingTest(m_eglTestCtx,"render", "Create, render in two contexts and delete" , spec, false));
1254 	}
1255 	{
1256 		GLES2SharingTest::TestSpec spec;
1257 		spec.destroyContextBFirst	= false;
1258 		spec.useResource			= true;
1259 		spec.destroyOnContexB		= false;
1260 		spec.initializeData			= true;
1261 		spec.renderOnContexA		= true;
1262 		spec.renderOnContexB		= false;
1263 		spec.verifyOnContexA		= true;
1264 		spec.verifyOnContexB		= false;
1265 
1266 		texture->addChild(new GLES2TextureSharingTest(m_eglTestCtx, "render_sample_mixed", "sampling, read pixels in different fbo", spec, true));
1267 	}
1268 	gles2->addChild(texture);
1269 
1270 	TestCaseGroup* program = new TestCaseGroup(m_eglTestCtx, "program", "Program creation, destruction and rendering test");
1271 
1272 	{
1273 		GLES2SharingTest::TestSpec spec;
1274 		spec.destroyContextBFirst	= false;
1275 		spec.useResource			= true;
1276 		spec.destroyOnContexB		= false;
1277 		spec.initializeData			= true;
1278 		spec.renderOnContexA		= false;
1279 		spec.renderOnContexB		= false;
1280 		spec.verifyOnContexA		= false;
1281 		spec.verifyOnContexB		= false;
1282 
1283 		program->addChild(new GLES2ProgramSharingTest(m_eglTestCtx, "create_delete", "Create and delete on shared context", spec));
1284 	}
1285 	{
1286 		GLES2SharingTest::TestSpec spec;
1287 		spec.destroyContextBFirst	= false;
1288 		spec.useResource			= true;
1289 		spec.destroyOnContexB		= true;
1290 		spec.initializeData			= true;
1291 		spec.renderOnContexA		= false;
1292 		spec.renderOnContexB		= false;
1293 		spec.verifyOnContexA		= false;
1294 		spec.verifyOnContexB		= false;
1295 
1296 		program->addChild(new GLES2ProgramSharingTest(m_eglTestCtx, "create_delete_mixed", "Create and delete on different contexts", spec));
1297 	}
1298 	{
1299 		GLES2SharingTest::TestSpec spec;
1300 		spec.destroyContextBFirst	= false;
1301 		spec.useResource			= true;
1302 		spec.destroyOnContexB		= false;
1303 		spec.initializeData			= true;
1304 		spec.renderOnContexA		= true;
1305 		spec.renderOnContexB		= true;
1306 		spec.verifyOnContexA		= true;
1307 		spec.verifyOnContexB		= true;
1308 
1309 		program->addChild(new GLES2ProgramSharingTest(m_eglTestCtx, "render", "Create, render in two contexts and delete", spec));
1310 	}
1311 
1312 	gles2->addChild(program);
1313 
1314 	TestCaseGroup* shader = new TestCaseGroup(m_eglTestCtx, "shader", "Shader creation, destruction and rendering test");
1315 
1316 	{
1317 		GLES2SharingTest::TestSpec spec;
1318 		spec.destroyContextBFirst	= false;
1319 		spec.useResource			= true;
1320 		spec.destroyOnContexB		= false;
1321 		spec.initializeData			= true;
1322 		spec.renderOnContexA		= false;
1323 		spec.renderOnContexB		= false;
1324 		spec.verifyOnContexA		= false;
1325 		spec.verifyOnContexB		= false;
1326 
1327 		shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "create_delete_vert", "Create and delete on shared context", GL_VERTEX_SHADER, spec));
1328 	}
1329 	{
1330 		GLES2SharingTest::TestSpec spec;
1331 		spec.destroyContextBFirst	= false;
1332 		spec.useResource			= true;
1333 		spec.destroyOnContexB		= true;
1334 		spec.initializeData			= true;
1335 		spec.renderOnContexA		= false;
1336 		spec.renderOnContexB		= false;
1337 		spec.verifyOnContexA		= false;
1338 		spec.verifyOnContexB		= false;
1339 
1340 		shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "create_delete_mixed_vert", "Create and delete on different contexts", GL_VERTEX_SHADER, spec));
1341 	}
1342 	{
1343 		GLES2SharingTest::TestSpec spec;
1344 		spec.destroyContextBFirst	= false;
1345 		spec.useResource			= true;
1346 		spec.destroyOnContexB		= false;
1347 		spec.initializeData			= true;
1348 		spec.renderOnContexA		= true;
1349 		spec.renderOnContexB		= true;
1350 		spec.verifyOnContexA		= true;
1351 		spec.verifyOnContexB		= true;
1352 
1353 		shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "render_vert", "Create, render on two contexts and delete", GL_VERTEX_SHADER, spec));
1354 	}
1355 	{
1356 		GLES2SharingTest::TestSpec spec;
1357 		spec.destroyContextBFirst	= false;
1358 		spec.useResource			= true;
1359 		spec.destroyOnContexB		= false;
1360 		spec.initializeData			= true;
1361 		spec.renderOnContexA		= false;
1362 		spec.renderOnContexB		= false;
1363 		spec.verifyOnContexA		= false;
1364 		spec.verifyOnContexB		= false;
1365 
1366 		shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "create_delete_frag", "Create and delete on shared context", GL_FRAGMENT_SHADER, spec));
1367 	}
1368 	{
1369 		GLES2SharingTest::TestSpec spec;
1370 		spec.destroyContextBFirst	= false;
1371 		spec.useResource			= true;
1372 		spec.destroyOnContexB		= true;
1373 		spec.initializeData			= true;
1374 		spec.renderOnContexA		= false;
1375 		spec.renderOnContexB		= false;
1376 		spec.verifyOnContexA		= false;
1377 		spec.verifyOnContexB		= false;
1378 
1379 		shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "create_delete_mixed_frag", "Create and delete on different contexts", GL_FRAGMENT_SHADER, spec));
1380 	}
1381 	{
1382 		GLES2SharingTest::TestSpec spec;
1383 		spec.destroyContextBFirst	= false;
1384 		spec.useResource			= true;
1385 		spec.destroyOnContexB		= false;
1386 		spec.initializeData			= true;
1387 		spec.renderOnContexA		= true;
1388 		spec.renderOnContexB		= true;
1389 		spec.verifyOnContexA		= true;
1390 		spec.verifyOnContexB		= true;
1391 
1392 		shader->addChild(new GLES2ShaderSharingTest(m_eglTestCtx, "render_frag", "Create, render on two contexts and delete", GL_FRAGMENT_SHADER, spec));
1393 	}
1394 
1395 
1396 	gles2->addChild(shader);
1397 
1398 
1399 	gles2->addChild(new GLES2SharingThreadedTests(m_eglTestCtx));
1400 
1401 	addChild(gles2);
1402 }
1403 
1404 } // egl
1405 } // deqp
1406