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