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