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
30namespace deqp
31{
32namespace gles3
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 RedundantStateChangeCase : public gls::StateChangePerformanceCase
49{
50public:
51					RedundantStateChangeCase	(Context& context, int drawCallCount, int triangleCount, bool drawArrays, bool useIndexBuffer, const char* name, const char* description);
52					~RedundantStateChangeCase	(void);
53
54protected:
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
60RedundantStateChangeCase::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
69RedundantStateChangeCase::~RedundantStateChangeCase (void)
70{
71}
72
73void 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
82void 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
92RedundantStateChangeTests::RedundantStateChangeTests (Context& context)
93	: TestCaseGroup(context, "redundant_state_change_draw", "Test performance with redundant sate changes between rendering.")
94{
95}
96
97RedundantStateChangeTests::~RedundantStateChangeTests (void)
98{
99}
100
101#define MACRO_BLOCK(...) __VA_ARGS__
102
103#define ADD_TESTCASE(NAME, DESC, DRAWARRAYS, INDEXBUFFER, INIT_FUNC, CHANGE_FUNC)\
104do {\
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
124void 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