Home | History | Annotate | Download | only in performance
      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 
     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 
     69 RedundantStateChangeCase::~RedundantStateChangeCase (void)
     70 {
     71 }
     72 
     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 
     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 
     92 RedundantStateChangeTests::RedundantStateChangeTests (Context& context)
     93 	: TestCaseGroup(context, "redundant_state_change_draw", "Test performance with redundant sate changes between rendering.")
     94 {
     95 }
     96 
     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 
    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