1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.0 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 State change performance tests.
22 *//*--------------------------------------------------------------------*/
23
24#include "es2pStateChangeTests.hpp"
25#include "glsStateChangePerfTestCases.hpp"
26#include "gluShaderProgram.hpp"
27#include "glwFunctions.hpp"
28#include "glwEnums.hpp"
29
30namespace deqp
31{
32namespace gles2
33{
34namespace Performance
35{
36
37using namespace glw; // GL types
38
39namespace
40{
41
42enum
43{
44	VIEWPORT_WIDTH	= 24,
45	VIEWPORT_HEIGHT	= 24
46};
47
48class StateChangeCase : public gls::StateChangePerformanceCase
49{
50public:
51					StateChangeCase			(Context& context, int drawCallCount, int triangleCount, bool drawArrays, bool useIndexBuffer, const char* name, const char* description);
52					~StateChangeCase		(void);
53
54protected:
55	virtual void	renderTest				(const glw::Functions& gl);
56	virtual void	renderReference			(const glw::Functions& gl);
57
58	virtual void	changeState				(const glw::Functions& gl, int stateId) = 0;
59};
60
61StateChangeCase::StateChangeCase (Context& context, int drawCallCount, int triangleCount, bool drawArrays, bool useIndexBuffer, const char* name, const char* description)
62	: gls::StateChangePerformanceCase(context.getTestContext(), context.getRenderContext(), name, description,
63									  (useIndexBuffer	? DRAWTYPE_INDEXED_BUFFER	:
64									   drawArrays		? DRAWTYPE_NOT_INDEXED		:
65														  DRAWTYPE_INDEXED_USER_PTR), drawCallCount, triangleCount)
66{
67	DE_ASSERT(!useIndexBuffer || !drawArrays);
68}
69
70StateChangeCase::~StateChangeCase (void)
71{
72}
73
74void StateChangeCase::renderTest (const glw::Functions& gl)
75{
76	for (int callNdx = 0; callNdx < m_callCount; callNdx++)
77	{
78		changeState(gl, 0);
79		callDraw(gl);
80
81		changeState(gl, 1);
82		callDraw(gl);
83	}
84}
85
86void StateChangeCase::renderReference (const glw::Functions& gl)
87{
88	changeState(gl, 0);
89
90	for (int callNdx = 0; callNdx < m_callCount; callNdx++)
91		callDraw(gl);
92
93	changeState(gl, 1);
94
95	for (int callNdx = 0; callNdx < m_callCount; callNdx++)
96		callDraw(gl);
97}
98
99} // anonymous
100
101StateChangeTests::StateChangeTests (Context& context)
102	: TestCaseGroup(context, "state_change_draw", "Test state change perfomance with draw calls.")
103{
104}
105
106StateChangeTests::~StateChangeTests (void)
107{
108}
109
110#define MACRO_BLOCK(...) __VA_ARGS__
111
112#define ADD_TESTCASE(NAME, DESC, DRAWARRAYS, INDEXBUFFER, INIT_FUNC, CHANGE_FUNC)\
113do {\
114	class StateChangeCase_ ## NAME : public StateChangeCase\
115	{\
116	public:\
117			StateChangeCase_ ## NAME (Context& context, int drawCallCount, int triangleCount, const char* name, const char* description)\
118				: StateChangeCase(context, drawCallCount, triangleCount, (DRAWARRAYS), (INDEXBUFFER), name, description)\
119			{}\
120		virtual void setupInitialState (const glw::Functions& gl)\
121		{\
122			INIT_FUNC\
123		}\
124		virtual void changeState (const glw::Functions& gl, int stateId)\
125		{\
126			CHANGE_FUNC\
127		}\
128	};\
129	manySmallCallsGroup->addChild	(new StateChangeCase_ ## NAME (m_context,1000,2,#NAME,(DESC)));\
130	fewBigCallsGroup->addChild		(new StateChangeCase_ ## NAME (m_context,10,200,#NAME,(DESC)));\
131} while (0);
132
133void StateChangeTests::init (void)
134{
135	tcu::TestCaseGroup* const	manySmallCallsGroup	= new tcu::TestCaseGroup(m_testCtx, "many_small_calls",	"1000 calls, 2 triangles in each");
136	tcu::TestCaseGroup* const	fewBigCallsGroup	= new tcu::TestCaseGroup(m_testCtx, "few_big_calls",	"10 calls, 200 triangles in each");
137
138	addChild(manySmallCallsGroup);
139	addChild(fewBigCallsGroup);
140
141	ADD_TESTCASE(blend, "Enable/Disable blending.",
142		true,
143		false,
144		MACRO_BLOCK({
145			requireCoordBuffers(1);
146			requireTextures(1);
147			requirePrograms(1);
148
149			gl.useProgram(m_programs[0]->getProgram());
150			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
151			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
152			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
153
154			gl.enableVertexAttribArray(coordLoc);
155			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
156			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
157			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
158			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
159			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
160
161			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
162			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
163
164			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
165			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
166
167			gl.uniform1i(samplerLoc, 0);
168			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
169
170			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
171			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
172		}),
173		MACRO_BLOCK({
174			if (stateId == 0)
175				gl.enable(GL_BLEND);
176			else if (stateId == 1)
177				gl.disable(GL_BLEND);
178			else
179				DE_ASSERT(false);
180		})
181	)
182
183	ADD_TESTCASE(depth_test, "Enable/Disable depth test.",
184		true,
185		false,
186		MACRO_BLOCK({
187			requireCoordBuffers(1);
188			requireTextures(1);
189			requirePrograms(1);
190
191			gl.useProgram(m_programs[0]->getProgram());
192			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
193
194			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
195			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
196
197			gl.enableVertexAttribArray(coordLoc);
198			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
199
200			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
201			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
202			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
203			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
204
205			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
206			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
207
208			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
209			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
210
211			gl.uniform1i(samplerLoc, 0);
212			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
213
214			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
215			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
216
217			gl.depthFunc(GL_LEQUAL);
218			GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthFunc()");
219		}),
220		MACRO_BLOCK({
221			if (stateId == 0)
222				gl.enable(GL_DEPTH_TEST);
223			else if (stateId == 1)
224				gl.disable(GL_DEPTH_TEST);
225			else
226				DE_ASSERT(false);
227		})
228	)
229
230	ADD_TESTCASE(stencil_test, "Enable/Disable stencil test.",
231		true,
232		false,
233		MACRO_BLOCK({
234			requireCoordBuffers(1);
235			requireTextures(1);
236			requirePrograms(1);
237
238			gl.useProgram(m_programs[0]->getProgram());
239			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
240			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
241			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
242
243			gl.enableVertexAttribArray(coordLoc);
244			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
245			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
246			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
247			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
248			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
249
250			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
251			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
252
253			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
254			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
255
256			gl.uniform1i(samplerLoc, 0);
257			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
258
259			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
260			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
261
262			gl.stencilFunc(GL_LEQUAL, 0, 0);
263			GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilFunc()");
264
265			gl.stencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
266			GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilOp()");
267
268			gl.clearStencil(0);
269			GLU_EXPECT_NO_ERROR(gl.getError(), "glClearStencil()");
270			gl.clear(GL_STENCIL_BUFFER_BIT);
271
272			GLU_EXPECT_NO_ERROR(gl.getError(), "glClear()");
273		}),
274		MACRO_BLOCK({
275			if (stateId == 0)
276				gl.enable(GL_STENCIL_TEST);
277			else if (stateId == 1)
278				gl.disable(GL_STENCIL_TEST);
279			else
280				DE_ASSERT(false);
281		})
282	)
283
284	ADD_TESTCASE(scissor_test, "Enable/Disable scissor test.",
285		true,
286		false,
287		MACRO_BLOCK({
288			requireCoordBuffers(1);
289			requireTextures(1);
290			requirePrograms(1);
291
292			gl.useProgram(m_programs[0]->getProgram());
293			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
294			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
295			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
296
297			gl.enableVertexAttribArray(coordLoc);
298			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
299			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
300			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
301			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
302			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
303
304			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
305			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
306
307			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
308			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
309
310			gl.uniform1i(samplerLoc, 0);
311			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
312
313			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
314			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
315
316			gl.scissor(2, 3, 12, 13);
317			GLU_EXPECT_NO_ERROR(gl.getError(), "glScissor()");
318		}),
319		MACRO_BLOCK({
320			if (stateId == 0)
321				gl.enable(GL_SCISSOR_TEST);
322			else if (stateId == 1)
323				gl.disable(GL_SCISSOR_TEST);
324			else
325				DE_ASSERT(false);
326		})
327	)
328
329	ADD_TESTCASE(dither, "Enable/Disable dithering.",
330		true,
331		false,
332		MACRO_BLOCK({
333			requireCoordBuffers(1);
334			requireTextures(1);
335			requirePrograms(1);
336
337			gl.useProgram(m_programs[0]->getProgram());
338			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
339			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
340			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
341
342			gl.enableVertexAttribArray(coordLoc);
343			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
344			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
345			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
346			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
347			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
348
349			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
350			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
351
352			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
353			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
354
355			gl.uniform1i(samplerLoc, 0);
356			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
357
358			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
359			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
360		}),
361		MACRO_BLOCK({
362			if (stateId == 0)
363				gl.enable(GL_DITHER);
364			else if (stateId == 1)
365				gl.disable(GL_DITHER);
366			else
367				DE_ASSERT(false);
368		})
369	)
370
371	ADD_TESTCASE(culling, "Enable/Disable culling.",
372		true,
373		false,
374		MACRO_BLOCK({
375			requireCoordBuffers(1);
376			requireTextures(1);
377			requirePrograms(1);
378
379			gl.useProgram(m_programs[0]->getProgram());
380			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
381			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
382			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
383
384			gl.enableVertexAttribArray(coordLoc);
385			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
386			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
387			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
388			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
389			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
390
391			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
392			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
393
394			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
395			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
396
397			gl.uniform1i(samplerLoc, 0);
398			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
399
400			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
401			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
402
403			gl.frontFace(GL_CW);
404			GLU_EXPECT_NO_ERROR(gl.getError(), "glFrontFace()");
405
406			gl.cullFace(GL_FRONT);
407			GLU_EXPECT_NO_ERROR(gl.getError(), "glCullFace()");
408		}),
409		MACRO_BLOCK({
410			if (stateId == 0)
411				gl.enable(GL_CULL_FACE);
412			else if (stateId == 1)
413				gl.disable(GL_CULL_FACE);
414			else
415				DE_ASSERT(false);
416		})
417	)
418
419	ADD_TESTCASE(depth_func, "Change depth func.",
420		true,
421		false,
422		MACRO_BLOCK({
423			requireCoordBuffers(1);
424			requireTextures(1);
425			requirePrograms(1);
426
427			gl.useProgram(m_programs[0]->getProgram());
428			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
429			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
430			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
431
432			gl.enableVertexAttribArray(coordLoc);
433			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
434			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
435			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
436			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
437			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
438
439			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
440			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
441
442			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
443			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
444
445			gl.uniform1i(samplerLoc, 0);
446			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
447
448			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
449			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
450
451			gl.enable(GL_DEPTH_TEST);
452			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
453		}),
454		MACRO_BLOCK({
455			if (stateId == 0)
456				gl.depthFunc(GL_GEQUAL);
457			else if (stateId == 1)
458				gl.depthFunc(GL_LEQUAL);
459			else
460				DE_ASSERT(false);
461		})
462	)
463
464
465	ADD_TESTCASE(depth_mask, "Toggle depth mask.",
466		true,
467		false,
468		MACRO_BLOCK({
469			requireCoordBuffers(1);
470			requireTextures(1);
471			requirePrograms(1);
472
473			gl.useProgram(m_programs[0]->getProgram());
474			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
475			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
476			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
477
478			gl.enableVertexAttribArray(coordLoc);
479			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
480			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
481			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
482			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
483			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
484
485			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
486			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
487
488			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
489			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
490
491			gl.uniform1i(samplerLoc, 0);
492			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
493
494			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
495			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
496
497			gl.enable(GL_DEPTH_TEST);
498			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
499
500			gl.depthFunc(GL_LEQUAL);
501			GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthFunc()");
502		}),
503		MACRO_BLOCK({
504			if (stateId == 0)
505				gl.depthMask(GL_FALSE);
506			else if (stateId == 1)
507				gl.depthMask(GL_TRUE);
508			else
509				DE_ASSERT(false);
510		})
511	)
512
513	ADD_TESTCASE(depth_rangef, "Change depth range.",
514		true,
515		false,
516		MACRO_BLOCK({
517			requireCoordBuffers(1);
518			requireTextures(1);
519			requirePrograms(1);
520
521			gl.useProgram(m_programs[0]->getProgram());
522			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
523			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
524			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
525
526			gl.enableVertexAttribArray(coordLoc);
527			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
528			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
529			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
530			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
531			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
532
533			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
534			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
535
536			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
537			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
538
539			gl.uniform1i(samplerLoc, 0);
540			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
541
542			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
543			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
544		}),
545		MACRO_BLOCK({
546			if (stateId == 0)
547				gl.depthRangef(0.0f, 1.0f);
548			else if (stateId == 1)
549				gl.depthRangef(0.25f, 0.75f);
550			else
551				DE_ASSERT(false);
552		})
553	)
554
555	ADD_TESTCASE(blend_equation, "Change blend equation.",
556		true,
557		false,
558		MACRO_BLOCK({
559			requireCoordBuffers(1);
560			requireTextures(1);
561			requirePrograms(1);
562
563			gl.useProgram(m_programs[0]->getProgram());
564			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
565			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
566			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
567
568			gl.enableVertexAttribArray(coordLoc);
569			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
570			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
571			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
572			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
573			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
574
575			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
576			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
577
578			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
579			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
580
581			gl.uniform1i(samplerLoc, 0);
582			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
583
584			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
585			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
586
587			gl.enable(GL_BLEND);
588			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
589		}),
590		MACRO_BLOCK({
591			if (stateId == 0)
592				gl.blendEquation(GL_FUNC_SUBTRACT);
593			else if (stateId == 1)
594				gl.blendEquation(GL_FUNC_ADD);
595			else
596				DE_ASSERT(false);
597		})
598	)
599
600	ADD_TESTCASE(blend_func, "Change blend function.",
601		true,
602		false,
603		MACRO_BLOCK({
604			requireCoordBuffers(1);
605			requireTextures(1);
606			requirePrograms(1);
607
608			gl.useProgram(m_programs[0]->getProgram());
609			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
610			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
611			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
612
613			gl.enableVertexAttribArray(coordLoc);
614			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
615			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
616			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
617			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
618			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
619
620			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
621			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
622
623			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
624			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
625
626			gl.uniform1i(samplerLoc, 0);
627			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
628
629			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
630			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
631
632			gl.enable(GL_BLEND);
633			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
634		}),
635		MACRO_BLOCK({
636			if (stateId == 0)
637				gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
638			else if (stateId == 1)
639				gl.blendFunc(GL_ONE, GL_ONE);
640			else
641				DE_ASSERT(false);
642		})
643	)
644
645	ADD_TESTCASE(polygon_offset, "Change polygon offset.",
646		true,
647		false,
648		MACRO_BLOCK({
649			requireCoordBuffers(1);
650			requireTextures(1);
651			requirePrograms(1);
652
653			gl.useProgram(m_programs[0]->getProgram());
654			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
655			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
656			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
657
658			gl.enableVertexAttribArray(coordLoc);
659			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
660			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
661			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
662			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
663			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
664
665			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
666			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
667
668			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
669			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
670
671			gl.uniform1i(samplerLoc, 0);
672			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
673
674			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
675			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
676
677			gl.enable(GL_POLYGON_OFFSET_FILL);
678			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
679		}),
680		MACRO_BLOCK({
681			if (stateId == 0)
682				gl.polygonOffset(0.0f, 0.0f);
683			else if (stateId == 1)
684				gl.polygonOffset(0.1f, 0.1f);
685			else
686				DE_ASSERT(false);
687		})
688	)
689
690	ADD_TESTCASE(sample_coverage, "Sample coverage.",
691		true,
692		false,
693		MACRO_BLOCK({
694			requireCoordBuffers(1);
695			requireTextures(1);
696			requirePrograms(1);
697
698			gl.useProgram(m_programs[0]->getProgram());
699			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
700			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
701			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
702
703			gl.enableVertexAttribArray(coordLoc);
704			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
705			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
706			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
707			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
708			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
709
710			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
711			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
712
713			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
714			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
715
716			gl.uniform1i(samplerLoc, 0);
717			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
718
719			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
720			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
721		}),
722		MACRO_BLOCK({
723			if (stateId == 0)
724				gl.sampleCoverage(0.25f, GL_TRUE);
725			else if (stateId == 1)
726				gl.sampleCoverage(0.75f, GL_FALSE);
727			else
728				DE_ASSERT(false);
729		})
730	)
731
732	ADD_TESTCASE(viewport, "Change viewport.",
733		true,
734		false,
735		MACRO_BLOCK({
736			requireCoordBuffers(1);
737			requireTextures(1);
738			requirePrograms(1);
739
740			gl.useProgram(m_programs[0]->getProgram());
741			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
742			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
743			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
744
745			gl.enableVertexAttribArray(coordLoc);
746			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
747			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
748			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
749			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
750			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
751
752			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
753			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
754
755			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
756			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
757
758			gl.uniform1i(samplerLoc, 0);
759			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
760
761			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
762			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
763		}),
764		MACRO_BLOCK({
765			if (stateId == 0)
766				gl.viewport(10, 11, 5, 6);
767			else if (stateId == 1)
768				gl.viewport(2, 3, 17, 14);
769			else
770				DE_ASSERT(false);
771		})
772	)
773
774	ADD_TESTCASE(scissor, "Change scissor box.",
775		true,
776		false,
777		MACRO_BLOCK({
778			requireCoordBuffers(1);
779			requireTextures(1);
780			requirePrograms(1);
781
782			gl.useProgram(m_programs[0]->getProgram());
783			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
784			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
785			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
786
787			gl.enableVertexAttribArray(coordLoc);
788			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
789			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
790			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
791			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
792			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
793
794			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
795			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
796
797			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
798			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
799
800			gl.uniform1i(samplerLoc, 0);
801			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
802
803			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
804			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
805
806			gl.enable(GL_SCISSOR_TEST);
807			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
808		}),
809		MACRO_BLOCK({
810			if (stateId == 0)
811				gl.scissor(17, 13, 5, 8);
812			else if (stateId == 1)
813				gl.scissor(7, 3, 13, 13);
814			else
815				DE_ASSERT(false);
816		})
817	)
818
819	ADD_TESTCASE(color_mask, "Change color mask.",
820		true,
821		false,
822		MACRO_BLOCK({
823			requireCoordBuffers(1);
824			requireTextures(1);
825			requirePrograms(1);
826
827			gl.useProgram(m_programs[0]->getProgram());
828			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
829			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
830			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
831
832			gl.enableVertexAttribArray(coordLoc);
833			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
834			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
835			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
836			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
837			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
838
839			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
840			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
841
842			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
843			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
844
845			gl.uniform1i(samplerLoc, 0);
846			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
847
848			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
849			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
850		}),
851		MACRO_BLOCK({
852			if (stateId == 0)
853				gl.colorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_FALSE);
854			else if (stateId == 1)
855				gl.colorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
856			else
857				DE_ASSERT(false);
858		})
859	)
860
861	ADD_TESTCASE(cull_face, "Change culling mode.",
862		true,
863		false,
864		MACRO_BLOCK({
865			requireCoordBuffers(1);
866			requireTextures(1);
867			requirePrograms(1);
868
869			gl.useProgram(m_programs[0]->getProgram());
870			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
871			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
872			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
873
874			gl.enableVertexAttribArray(coordLoc);
875			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
876			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
877			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
878			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
879			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
880
881			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
882			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
883
884			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
885			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
886
887			gl.uniform1i(samplerLoc, 0);
888			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
889
890			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
891			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
892
893			gl.enable(GL_CULL_FACE);
894			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
895		}),
896		MACRO_BLOCK({
897			if (stateId == 0)
898				gl.cullFace(GL_FRONT);
899			else if (stateId == 1)
900				gl.cullFace(GL_BACK);
901			else
902				DE_ASSERT(false);
903		})
904	)
905
906	ADD_TESTCASE(front_face, "Change front face.",
907		true,
908		false,
909		MACRO_BLOCK({
910			requireCoordBuffers(1);
911			requireTextures(1);
912			requirePrograms(1);
913
914			gl.useProgram(m_programs[0]->getProgram());
915			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
916			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
917			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
918
919			gl.enableVertexAttribArray(coordLoc);
920			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
921			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
922			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
923			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
924			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
925
926			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
927			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
928
929			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
930			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
931
932			gl.uniform1i(samplerLoc, 0);
933			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
934
935			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
936			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
937
938			gl.enable(GL_CULL_FACE);
939			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
940		}),
941		MACRO_BLOCK({
942			if (stateId == 0)
943				gl.frontFace(GL_CCW);
944			else if (stateId == 1)
945				gl.frontFace(GL_CW);
946			else
947				DE_ASSERT(false);
948		})
949	)
950
951	ADD_TESTCASE(stencil_mask, "Change stencil mask.",
952		true,
953		false,
954		MACRO_BLOCK({
955			requireCoordBuffers(1);
956			requireTextures(1);
957			requirePrograms(1);
958
959			gl.useProgram(m_programs[0]->getProgram());
960			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
961			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
962			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
963
964			gl.enableVertexAttribArray(coordLoc);
965			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
966			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
967			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
968			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
969			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
970
971			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
972			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
973
974			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
975			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
976
977			gl.uniform1i(samplerLoc, 0);
978			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
979
980			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
981			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
982
983			gl.enable(GL_STENCIL_TEST);
984			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
985
986			gl.stencilFunc(GL_LEQUAL, 0, 0);
987			GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilFunc()");
988
989			gl.stencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
990			GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilOp()");
991
992			gl.clearStencil(0);
993			GLU_EXPECT_NO_ERROR(gl.getError(), "glClearStencil()");
994			gl.clear(GL_STENCIL_BUFFER_BIT);
995			GLU_EXPECT_NO_ERROR(gl.getError(), "glClear()");
996		}),
997		MACRO_BLOCK({
998			if (stateId == 0)
999				gl.stencilMask(0xDD);
1000			else if (stateId == 1)
1001				gl.stencilMask(~0xDD);
1002			else
1003				DE_ASSERT(false);
1004		})
1005	)
1006
1007	ADD_TESTCASE(stencil_func, "Change stencil func.",
1008		true,
1009		false,
1010		MACRO_BLOCK({
1011			requireCoordBuffers(1);
1012			requireTextures(1);
1013			requirePrograms(1);
1014
1015			gl.useProgram(m_programs[0]->getProgram());
1016			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
1017			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
1018			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
1019
1020			gl.enableVertexAttribArray(coordLoc);
1021			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
1022			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
1023			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
1024			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1025			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
1026
1027			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
1028			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
1029
1030			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
1031			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
1032
1033			gl.uniform1i(samplerLoc, 0);
1034			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
1035
1036			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1037			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
1038
1039			gl.enable(GL_STENCIL_TEST);
1040			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
1041
1042			gl.stencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
1043			GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilOp()");
1044			gl.clearStencil(0);
1045			GLU_EXPECT_NO_ERROR(gl.getError(), "glClearStencil()");
1046			gl.clear(GL_STENCIL_BUFFER_BIT);
1047			GLU_EXPECT_NO_ERROR(gl.getError(), "glClear()");
1048		}),
1049		MACRO_BLOCK({
1050			if (stateId == 0)
1051				gl.stencilFunc(GL_LEQUAL, 0, 0xFF);
1052			else if (stateId == 1)
1053				gl.stencilFunc(GL_GEQUAL, 0, 0x00);
1054			else
1055				DE_ASSERT(false);
1056		})
1057	)
1058
1059	ADD_TESTCASE(stencil_op, "Change stencil op.",
1060		true,
1061		false,
1062		MACRO_BLOCK({
1063			requireCoordBuffers(1);
1064			requireTextures(1);
1065			requirePrograms(1);
1066
1067			gl.useProgram(m_programs[0]->getProgram());
1068			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
1069			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
1070			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
1071
1072			gl.enableVertexAttribArray(coordLoc);
1073			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
1074			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
1075			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
1076			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1077			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
1078
1079			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
1080			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
1081
1082			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
1083			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
1084
1085			gl.uniform1i(samplerLoc, 0);
1086			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
1087
1088			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1089			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
1090
1091			gl.enable(GL_STENCIL_TEST);
1092			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
1093
1094			gl.stencilFunc(GL_LEQUAL, 0, 0);
1095			GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilFunc()");
1096
1097			gl.clearStencil(0);
1098			GLU_EXPECT_NO_ERROR(gl.getError(), "glClearStencil()");
1099
1100			gl.clear(GL_STENCIL_BUFFER_BIT);
1101			GLU_EXPECT_NO_ERROR(gl.getError(), "glClear()");
1102		}),
1103		MACRO_BLOCK({
1104			if (stateId == 0)
1105				gl.stencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
1106			else if (stateId == 1)
1107				gl.stencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
1108			else
1109				DE_ASSERT(false);
1110		})
1111	)
1112
1113	ADD_TESTCASE(bind_array_buffer, "Change array buffer and refresh vertex attrib pointer.",
1114		true,
1115		false,
1116		MACRO_BLOCK({
1117			requireCoordBuffers(2);
1118			requireTextures(1);
1119			requirePrograms(1);
1120
1121			gl.bindAttribLocation(m_programs[0]->getProgram(), 0, "a_coord");
1122			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindAttribLocation()");
1123			gl.linkProgram(m_programs[0]->getProgram());
1124			GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram()");
1125
1126			gl.useProgram(m_programs[0]->getProgram());
1127			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
1128
1129			gl.enableVertexAttribArray(0);
1130			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
1131			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
1132			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
1133			gl.vertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1134			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
1135
1136			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
1137			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
1138
1139			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
1140			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
1141
1142			gl.uniform1i(samplerLoc, 0);
1143			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
1144
1145			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1146			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
1147		}),
1148		MACRO_BLOCK({
1149			if (stateId == 0)
1150			{
1151				gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
1152				gl.vertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1153			}
1154			else if (stateId == 1)
1155			{
1156				gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[1]);
1157				gl.vertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1158			}
1159			else
1160				DE_ASSERT(false);
1161		})
1162	)
1163
1164	ADD_TESTCASE(element_array_buffer, "Change element array buffer.",
1165		false,
1166		true,
1167		MACRO_BLOCK({
1168			requireCoordBuffers(1);
1169			requireIndexBuffers(2);
1170			requireTextures(1);
1171			requirePrograms(1);
1172
1173			gl.useProgram(m_programs[0]->getProgram());
1174			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
1175			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
1176			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
1177
1178			gl.enableVertexAttribArray(coordLoc);
1179			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
1180			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
1181			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
1182			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1183			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
1184
1185			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
1186			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
1187
1188			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
1189			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
1190
1191			gl.uniform1i(samplerLoc, 0);
1192			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
1193
1194			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1195			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
1196
1197			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[0]);
1198			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
1199		}),
1200		MACRO_BLOCK({
1201			if (stateId == 0)
1202				gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[0]);
1203			else if (stateId == 1)
1204				gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[1]);
1205			else
1206				DE_ASSERT(false);
1207		})
1208	)
1209
1210	ADD_TESTCASE(bind_texture, "Change texture binding.",
1211		true,
1212		false,
1213		MACRO_BLOCK({
1214			requireCoordBuffers(1);
1215			requireTextures(2);
1216			requirePrograms(1);
1217
1218			gl.useProgram(m_programs[0]->getProgram());
1219			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
1220			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
1221			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
1222
1223			gl.enableVertexAttribArray(coordLoc);
1224			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
1225			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
1226			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
1227			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1228			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
1229
1230			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
1231			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
1232
1233			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
1234			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
1235
1236			gl.uniform1i(samplerLoc, 0);
1237			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
1238
1239			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1240			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
1241		}),
1242		MACRO_BLOCK({
1243			if (stateId == 0)
1244				gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
1245			else if (stateId == 1)
1246				gl.bindTexture(GL_TEXTURE_2D, m_textures[1]);
1247			else
1248				DE_ASSERT(false);
1249		})
1250	)
1251
1252	ADD_TESTCASE(use_program, "Change used program.",
1253		true,
1254		false,
1255		MACRO_BLOCK({
1256			requireCoordBuffers(1);
1257			requireTextures(1);
1258			requirePrograms(2);
1259
1260			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
1261			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
1262
1263			gl.enableVertexAttribArray(coordLoc);
1264			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
1265			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
1266			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
1267			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1268			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
1269
1270			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
1271			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
1272
1273			{
1274				GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
1275				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
1276				gl.useProgram(m_programs[0]->getProgram());
1277				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
1278				gl.uniform1i(samplerLoc, 0);
1279				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
1280			}
1281
1282			{
1283				GLint samplerLoc = gl.getUniformLocation(m_programs[1]->getProgram(), "u_sampler");
1284				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
1285				gl.useProgram(m_programs[1]->getProgram());
1286				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
1287				gl.uniform1i(samplerLoc, 0);
1288				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
1289			}
1290
1291			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1292			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
1293		}),
1294		MACRO_BLOCK({
1295			if (stateId == 0)
1296				gl.useProgram(m_programs[0]->getProgram());
1297			else if (stateId == 1)
1298				gl.useProgram(m_programs[1]->getProgram());
1299			else
1300				DE_ASSERT(false);
1301		})
1302	)
1303
1304	ADD_TESTCASE(tex_parameter_min_filter, "Change texture parameter min filter.",
1305		true,
1306		false,
1307		MACRO_BLOCK({
1308			requireCoordBuffers(1);
1309			requireTextures(1);
1310			requirePrograms(1);
1311
1312			gl.useProgram(m_programs[0]->getProgram());
1313			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
1314			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
1315			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
1316
1317			gl.enableVertexAttribArray(coordLoc);
1318			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
1319			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
1320			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
1321			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1322			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
1323
1324			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
1325			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
1326
1327			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
1328			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
1329
1330			gl.uniform1i(samplerLoc, 0);
1331			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
1332
1333			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1334			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
1335		}),
1336		MACRO_BLOCK({
1337			if (stateId == 0)
1338				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1339			else if (stateId == 1)
1340				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1341			else
1342				DE_ASSERT(false);
1343		})
1344	)
1345
1346	ADD_TESTCASE(tex_parameter_mag_filter, "Change texture parameter mag filter.",
1347		true,
1348		false,
1349		MACRO_BLOCK({
1350			requireCoordBuffers(1);
1351			requireTextures(1);
1352			requirePrograms(1);
1353
1354			gl.useProgram(m_programs[0]->getProgram());
1355			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
1356			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
1357			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
1358
1359			gl.enableVertexAttribArray(coordLoc);
1360			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
1361			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
1362			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
1363			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1364			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
1365
1366			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
1367			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
1368
1369			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
1370			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
1371
1372			gl.uniform1i(samplerLoc, 0);
1373			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
1374
1375			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1376			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
1377		}),
1378		MACRO_BLOCK({
1379			if (stateId == 0)
1380				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1381			else if (stateId == 1)
1382				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1383			else
1384				DE_ASSERT(false);
1385		})
1386	)
1387
1388	ADD_TESTCASE(tex_parameter_wrap, "Change texture parameter wrap filter.",
1389		true,
1390		false,
1391		MACRO_BLOCK({
1392			requireCoordBuffers(1);
1393			requireTextures(1);
1394			requirePrograms(1);
1395
1396			gl.useProgram(m_programs[0]->getProgram());
1397			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
1398			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
1399			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
1400
1401			gl.enableVertexAttribArray(coordLoc);
1402			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
1403			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
1404			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
1405			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1406			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
1407
1408			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
1409			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
1410
1411			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
1412			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
1413
1414			gl.uniform1i(samplerLoc, 0);
1415			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
1416
1417			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1418			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
1419		}),
1420		MACRO_BLOCK({
1421			if (stateId == 0)
1422				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1423			else if (stateId == 1)
1424				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1425			else
1426				DE_ASSERT(false);
1427		})
1428	)
1429
1430	ADD_TESTCASE(bind_framebuffer, "Change framebuffer.",
1431		true,
1432		false,
1433		MACRO_BLOCK({
1434			requireCoordBuffers(1);
1435			requireTextures(1);
1436			requireFramebuffers(2);
1437			requirePrograms(1);
1438
1439			gl.useProgram(m_programs[0]->getProgram());
1440			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
1441			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
1442			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
1443
1444			gl.enableVertexAttribArray(coordLoc);
1445			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
1446			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
1447			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
1448			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1449			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
1450
1451			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
1452			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
1453
1454			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
1455			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
1456
1457			gl.uniform1i(samplerLoc, 0);
1458			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
1459
1460			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1461			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
1462
1463			gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[0]);
1464			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer()");
1465		}),
1466		MACRO_BLOCK({
1467			if (stateId == 0)
1468				gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[0]);
1469			else if (stateId == 1)
1470				gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[1]);
1471			else
1472				DE_ASSERT(false);
1473		})
1474	)
1475
1476	ADD_TESTCASE(blend_color, "Change blend color.",
1477		true,
1478		false,
1479		MACRO_BLOCK({
1480			requireCoordBuffers(1);
1481			requireTextures(1);
1482			requirePrograms(1);
1483
1484			gl.useProgram(m_programs[0]->getProgram());
1485			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
1486			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
1487			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
1488
1489			gl.enableVertexAttribArray(coordLoc);
1490			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
1491			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
1492			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
1493			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
1494			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
1495
1496			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
1497			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
1498
1499			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
1500			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
1501
1502			gl.uniform1i(samplerLoc, 0);
1503			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
1504
1505			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1506			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
1507
1508			gl.enable(GL_BLEND);
1509			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
1510
1511			gl.blendFunc(GL_CONSTANT_COLOR, GL_CONSTANT_COLOR);
1512			GLU_EXPECT_NO_ERROR(gl.getError(), "glBlendFunc()");
1513		}),
1514		MACRO_BLOCK({
1515			if (stateId == 0)
1516				gl.blendColor(0.25f, 0.25f, 0.25f, 0.25f);
1517			else if (stateId == 1)
1518				gl.blendColor(0.75f, 0.75f, 0.75f, 0.75f);
1519			else
1520				DE_ASSERT(false);
1521		})
1522	)
1523}
1524
1525} // Performance
1526} // gles2
1527} // deqp
1528