Home | History | Annotate | Download | only in performance
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 2.0 Module
      3  * -------------------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief State change performance tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es2pStateChangeTests.hpp"
     25 #include "glsStateChangePerfTestCases.hpp"
     26 #include "gluShaderProgram.hpp"
     27 #include "glwFunctions.hpp"
     28 #include "glwEnums.hpp"
     29 
     30 namespace deqp
     31 {
     32 namespace gles2
     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(depth_func, "Change depth func.",
    420 		true,
    421 		false,
    422 		MACRO_BLOCK({
    423 			requireCoordBuffers(1);
    424 			requireTextures(1);
    425 			requirePrograms(1);
    426 
    427 			gl.useProgram(m_programs[0]->getProgram());
    428 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
    429 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
    430 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
    431 
    432 			gl.enableVertexAttribArray(coordLoc);
    433 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
    434 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
    435 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
    436 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    437 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
    438 
    439 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
    440 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
    441 
    442 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
    443 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
    444 
    445 			gl.uniform1i(samplerLoc, 0);
    446 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
    447 
    448 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    449 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
    450 
    451 			gl.enable(GL_DEPTH_TEST);
    452 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
    453 		}),
    454 		MACRO_BLOCK({
    455 			if (stateId == 0)
    456 				gl.depthFunc(GL_GEQUAL);
    457 			else if (stateId == 1)
    458 				gl.depthFunc(GL_LEQUAL);
    459 			else
    460 				DE_ASSERT(false);
    461 		})
    462 	)
    463 
    464 
    465 	ADD_TESTCASE(depth_mask, "Toggle depth mask.",
    466 		true,
    467 		false,
    468 		MACRO_BLOCK({
    469 			requireCoordBuffers(1);
    470 			requireTextures(1);
    471 			requirePrograms(1);
    472 
    473 			gl.useProgram(m_programs[0]->getProgram());
    474 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
    475 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
    476 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
    477 
    478 			gl.enableVertexAttribArray(coordLoc);
    479 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
    480 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
    481 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
    482 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    483 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
    484 
    485 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
    486 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
    487 
    488 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
    489 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
    490 
    491 			gl.uniform1i(samplerLoc, 0);
    492 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
    493 
    494 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    495 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
    496 
    497 			gl.enable(GL_DEPTH_TEST);
    498 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
    499 
    500 			gl.depthFunc(GL_LEQUAL);
    501 			GLU_EXPECT_NO_ERROR(gl.getError(), "glDepthFunc()");
    502 		}),
    503 		MACRO_BLOCK({
    504 			if (stateId == 0)
    505 				gl.depthMask(GL_FALSE);
    506 			else if (stateId == 1)
    507 				gl.depthMask(GL_TRUE);
    508 			else
    509 				DE_ASSERT(false);
    510 		})
    511 	)
    512 
    513 	ADD_TESTCASE(depth_rangef, "Change depth range.",
    514 		true,
    515 		false,
    516 		MACRO_BLOCK({
    517 			requireCoordBuffers(1);
    518 			requireTextures(1);
    519 			requirePrograms(1);
    520 
    521 			gl.useProgram(m_programs[0]->getProgram());
    522 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
    523 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
    524 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
    525 
    526 			gl.enableVertexAttribArray(coordLoc);
    527 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
    528 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
    529 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
    530 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    531 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
    532 
    533 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
    534 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
    535 
    536 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
    537 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
    538 
    539 			gl.uniform1i(samplerLoc, 0);
    540 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
    541 
    542 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    543 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
    544 		}),
    545 		MACRO_BLOCK({
    546 			if (stateId == 0)
    547 				gl.depthRangef(0.0f, 1.0f);
    548 			else if (stateId == 1)
    549 				gl.depthRangef(0.25f, 0.75f);
    550 			else
    551 				DE_ASSERT(false);
    552 		})
    553 	)
    554 
    555 	ADD_TESTCASE(blend_equation, "Change blend equation.",
    556 		true,
    557 		false,
    558 		MACRO_BLOCK({
    559 			requireCoordBuffers(1);
    560 			requireTextures(1);
    561 			requirePrograms(1);
    562 
    563 			gl.useProgram(m_programs[0]->getProgram());
    564 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
    565 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
    566 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
    567 
    568 			gl.enableVertexAttribArray(coordLoc);
    569 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
    570 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
    571 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
    572 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    573 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
    574 
    575 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
    576 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
    577 
    578 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
    579 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
    580 
    581 			gl.uniform1i(samplerLoc, 0);
    582 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
    583 
    584 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    585 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
    586 
    587 			gl.enable(GL_BLEND);
    588 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
    589 		}),
    590 		MACRO_BLOCK({
    591 			if (stateId == 0)
    592 				gl.blendEquation(GL_FUNC_SUBTRACT);
    593 			else if (stateId == 1)
    594 				gl.blendEquation(GL_FUNC_ADD);
    595 			else
    596 				DE_ASSERT(false);
    597 		})
    598 	)
    599 
    600 	ADD_TESTCASE(blend_func, "Change blend function.",
    601 		true,
    602 		false,
    603 		MACRO_BLOCK({
    604 			requireCoordBuffers(1);
    605 			requireTextures(1);
    606 			requirePrograms(1);
    607 
    608 			gl.useProgram(m_programs[0]->getProgram());
    609 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
    610 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
    611 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
    612 
    613 			gl.enableVertexAttribArray(coordLoc);
    614 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
    615 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
    616 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
    617 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    618 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
    619 
    620 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
    621 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
    622 
    623 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
    624 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
    625 
    626 			gl.uniform1i(samplerLoc, 0);
    627 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
    628 
    629 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    630 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
    631 
    632 			gl.enable(GL_BLEND);
    633 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
    634 		}),
    635 		MACRO_BLOCK({
    636 			if (stateId == 0)
    637 				gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    638 			else if (stateId == 1)
    639 				gl.blendFunc(GL_ONE, GL_ONE);
    640 			else
    641 				DE_ASSERT(false);
    642 		})
    643 	)
    644 
    645 	ADD_TESTCASE(polygon_offset, "Change polygon offset.",
    646 		true,
    647 		false,
    648 		MACRO_BLOCK({
    649 			requireCoordBuffers(1);
    650 			requireTextures(1);
    651 			requirePrograms(1);
    652 
    653 			gl.useProgram(m_programs[0]->getProgram());
    654 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
    655 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
    656 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
    657 
    658 			gl.enableVertexAttribArray(coordLoc);
    659 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
    660 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
    661 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
    662 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    663 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
    664 
    665 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
    666 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
    667 
    668 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
    669 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
    670 
    671 			gl.uniform1i(samplerLoc, 0);
    672 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
    673 
    674 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    675 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
    676 
    677 			gl.enable(GL_POLYGON_OFFSET_FILL);
    678 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
    679 		}),
    680 		MACRO_BLOCK({
    681 			if (stateId == 0)
    682 				gl.polygonOffset(0.0f, 0.0f);
    683 			else if (stateId == 1)
    684 				gl.polygonOffset(0.1f, 0.1f);
    685 			else
    686 				DE_ASSERT(false);
    687 		})
    688 	)
    689 
    690 	ADD_TESTCASE(sample_coverage, "Sample coverage.",
    691 		true,
    692 		false,
    693 		MACRO_BLOCK({
    694 			requireCoordBuffers(1);
    695 			requireTextures(1);
    696 			requirePrograms(1);
    697 
    698 			gl.useProgram(m_programs[0]->getProgram());
    699 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
    700 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
    701 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
    702 
    703 			gl.enableVertexAttribArray(coordLoc);
    704 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
    705 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
    706 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
    707 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    708 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
    709 
    710 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
    711 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
    712 
    713 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
    714 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
    715 
    716 			gl.uniform1i(samplerLoc, 0);
    717 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
    718 
    719 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    720 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
    721 		}),
    722 		MACRO_BLOCK({
    723 			if (stateId == 0)
    724 				gl.sampleCoverage(0.25f, GL_TRUE);
    725 			else if (stateId == 1)
    726 				gl.sampleCoverage(0.75f, GL_FALSE);
    727 			else
    728 				DE_ASSERT(false);
    729 		})
    730 	)
    731 
    732 	ADD_TESTCASE(viewport, "Change viewport.",
    733 		true,
    734 		false,
    735 		MACRO_BLOCK({
    736 			requireCoordBuffers(1);
    737 			requireTextures(1);
    738 			requirePrograms(1);
    739 
    740 			gl.useProgram(m_programs[0]->getProgram());
    741 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
    742 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
    743 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
    744 
    745 			gl.enableVertexAttribArray(coordLoc);
    746 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
    747 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
    748 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
    749 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    750 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
    751 
    752 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
    753 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
    754 
    755 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
    756 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
    757 
    758 			gl.uniform1i(samplerLoc, 0);
    759 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
    760 
    761 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    762 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
    763 		}),
    764 		MACRO_BLOCK({
    765 			if (stateId == 0)
    766 				gl.viewport(10, 11, 5, 6);
    767 			else if (stateId == 1)
    768 				gl.viewport(2, 3, 17, 14);
    769 			else
    770 				DE_ASSERT(false);
    771 		})
    772 	)
    773 
    774 	ADD_TESTCASE(scissor, "Change scissor box.",
    775 		true,
    776 		false,
    777 		MACRO_BLOCK({
    778 			requireCoordBuffers(1);
    779 			requireTextures(1);
    780 			requirePrograms(1);
    781 
    782 			gl.useProgram(m_programs[0]->getProgram());
    783 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
    784 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
    785 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
    786 
    787 			gl.enableVertexAttribArray(coordLoc);
    788 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
    789 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
    790 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
    791 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    792 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
    793 
    794 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
    795 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
    796 
    797 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
    798 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
    799 
    800 			gl.uniform1i(samplerLoc, 0);
    801 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
    802 
    803 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    804 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
    805 
    806 			gl.enable(GL_SCISSOR_TEST);
    807 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
    808 		}),
    809 		MACRO_BLOCK({
    810 			if (stateId == 0)
    811 				gl.scissor(17, 13, 5, 8);
    812 			else if (stateId == 1)
    813 				gl.scissor(7, 3, 13, 13);
    814 			else
    815 				DE_ASSERT(false);
    816 		})
    817 	)
    818 
    819 	ADD_TESTCASE(color_mask, "Change color mask.",
    820 		true,
    821 		false,
    822 		MACRO_BLOCK({
    823 			requireCoordBuffers(1);
    824 			requireTextures(1);
    825 			requirePrograms(1);
    826 
    827 			gl.useProgram(m_programs[0]->getProgram());
    828 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
    829 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
    830 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
    831 
    832 			gl.enableVertexAttribArray(coordLoc);
    833 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
    834 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
    835 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
    836 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    837 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
    838 
    839 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
    840 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
    841 
    842 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
    843 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
    844 
    845 			gl.uniform1i(samplerLoc, 0);
    846 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
    847 
    848 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    849 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
    850 		}),
    851 		MACRO_BLOCK({
    852 			if (stateId == 0)
    853 				gl.colorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_FALSE);
    854 			else if (stateId == 1)
    855 				gl.colorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
    856 			else
    857 				DE_ASSERT(false);
    858 		})
    859 	)
    860 
    861 	ADD_TESTCASE(cull_face, "Change culling mode.",
    862 		true,
    863 		false,
    864 		MACRO_BLOCK({
    865 			requireCoordBuffers(1);
    866 			requireTextures(1);
    867 			requirePrograms(1);
    868 
    869 			gl.useProgram(m_programs[0]->getProgram());
    870 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
    871 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
    872 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
    873 
    874 			gl.enableVertexAttribArray(coordLoc);
    875 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
    876 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
    877 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
    878 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    879 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
    880 
    881 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
    882 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
    883 
    884 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
    885 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
    886 
    887 			gl.uniform1i(samplerLoc, 0);
    888 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
    889 
    890 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    891 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
    892 
    893 			gl.enable(GL_CULL_FACE);
    894 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
    895 		}),
    896 		MACRO_BLOCK({
    897 			if (stateId == 0)
    898 				gl.cullFace(GL_FRONT);
    899 			else if (stateId == 1)
    900 				gl.cullFace(GL_BACK);
    901 			else
    902 				DE_ASSERT(false);
    903 		})
    904 	)
    905 
    906 	ADD_TESTCASE(front_face, "Change front face.",
    907 		true,
    908 		false,
    909 		MACRO_BLOCK({
    910 			requireCoordBuffers(1);
    911 			requireTextures(1);
    912 			requirePrograms(1);
    913 
    914 			gl.useProgram(m_programs[0]->getProgram());
    915 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
    916 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
    917 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
    918 
    919 			gl.enableVertexAttribArray(coordLoc);
    920 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
    921 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
    922 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
    923 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    924 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
    925 
    926 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
    927 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
    928 
    929 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
    930 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
    931 
    932 			gl.uniform1i(samplerLoc, 0);
    933 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
    934 
    935 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    936 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
    937 
    938 			gl.enable(GL_CULL_FACE);
    939 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
    940 		}),
    941 		MACRO_BLOCK({
    942 			if (stateId == 0)
    943 				gl.frontFace(GL_CCW);
    944 			else if (stateId == 1)
    945 				gl.frontFace(GL_CW);
    946 			else
    947 				DE_ASSERT(false);
    948 		})
    949 	)
    950 
    951 	ADD_TESTCASE(stencil_mask, "Change stencil mask.",
    952 		true,
    953 		false,
    954 		MACRO_BLOCK({
    955 			requireCoordBuffers(1);
    956 			requireTextures(1);
    957 			requirePrograms(1);
    958 
    959 			gl.useProgram(m_programs[0]->getProgram());
    960 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
    961 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
    962 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
    963 
    964 			gl.enableVertexAttribArray(coordLoc);
    965 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
    966 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
    967 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
    968 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    969 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
    970 
    971 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
    972 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
    973 
    974 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
    975 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
    976 
    977 			gl.uniform1i(samplerLoc, 0);
    978 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
    979 
    980 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    981 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
    982 
    983 			gl.enable(GL_STENCIL_TEST);
    984 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
    985 
    986 			gl.stencilFunc(GL_LEQUAL, 0, 0);
    987 			GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilFunc()");
    988 
    989 			gl.stencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
    990 			GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilOp()");
    991 
    992 			gl.clearStencil(0);
    993 			GLU_EXPECT_NO_ERROR(gl.getError(), "glClearStencil()");
    994 			gl.clear(GL_STENCIL_BUFFER_BIT);
    995 			GLU_EXPECT_NO_ERROR(gl.getError(), "glClear()");
    996 		}),
    997 		MACRO_BLOCK({
    998 			if (stateId == 0)
    999 				gl.stencilMask(0xDD);
   1000 			else if (stateId == 1)
   1001 				gl.stencilMask(~0xDD);
   1002 			else
   1003 				DE_ASSERT(false);
   1004 		})
   1005 	)
   1006 
   1007 	ADD_TESTCASE(stencil_func, "Change stencil func.",
   1008 		true,
   1009 		false,
   1010 		MACRO_BLOCK({
   1011 			requireCoordBuffers(1);
   1012 			requireTextures(1);
   1013 			requirePrograms(1);
   1014 
   1015 			gl.useProgram(m_programs[0]->getProgram());
   1016 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
   1017 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
   1018 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
   1019 
   1020 			gl.enableVertexAttribArray(coordLoc);
   1021 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
   1022 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
   1023 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
   1024 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
   1025 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
   1026 
   1027 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
   1028 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
   1029 
   1030 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
   1031 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
   1032 
   1033 			gl.uniform1i(samplerLoc, 0);
   1034 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
   1035 
   1036 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1037 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
   1038 
   1039 			gl.enable(GL_STENCIL_TEST);
   1040 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
   1041 
   1042 			gl.stencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
   1043 			GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilOp()");
   1044 			gl.clearStencil(0);
   1045 			GLU_EXPECT_NO_ERROR(gl.getError(), "glClearStencil()");
   1046 			gl.clear(GL_STENCIL_BUFFER_BIT);
   1047 			GLU_EXPECT_NO_ERROR(gl.getError(), "glClear()");
   1048 		}),
   1049 		MACRO_BLOCK({
   1050 			if (stateId == 0)
   1051 				gl.stencilFunc(GL_LEQUAL, 0, 0xFF);
   1052 			else if (stateId == 1)
   1053 				gl.stencilFunc(GL_GEQUAL, 0, 0x00);
   1054 			else
   1055 				DE_ASSERT(false);
   1056 		})
   1057 	)
   1058 
   1059 	ADD_TESTCASE(stencil_op, "Change stencil op.",
   1060 		true,
   1061 		false,
   1062 		MACRO_BLOCK({
   1063 			requireCoordBuffers(1);
   1064 			requireTextures(1);
   1065 			requirePrograms(1);
   1066 
   1067 			gl.useProgram(m_programs[0]->getProgram());
   1068 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
   1069 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
   1070 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
   1071 
   1072 			gl.enableVertexAttribArray(coordLoc);
   1073 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
   1074 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
   1075 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
   1076 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
   1077 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
   1078 
   1079 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
   1080 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
   1081 
   1082 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
   1083 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
   1084 
   1085 			gl.uniform1i(samplerLoc, 0);
   1086 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
   1087 
   1088 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1089 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
   1090 
   1091 			gl.enable(GL_STENCIL_TEST);
   1092 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
   1093 
   1094 			gl.stencilFunc(GL_LEQUAL, 0, 0);
   1095 			GLU_EXPECT_NO_ERROR(gl.getError(), "glStencilFunc()");
   1096 
   1097 			gl.clearStencil(0);
   1098 			GLU_EXPECT_NO_ERROR(gl.getError(), "glClearStencil()");
   1099 
   1100 			gl.clear(GL_STENCIL_BUFFER_BIT);
   1101 			GLU_EXPECT_NO_ERROR(gl.getError(), "glClear()");
   1102 		}),
   1103 		MACRO_BLOCK({
   1104 			if (stateId == 0)
   1105 				gl.stencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE);
   1106 			else if (stateId == 1)
   1107 				gl.stencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);
   1108 			else
   1109 				DE_ASSERT(false);
   1110 		})
   1111 	)
   1112 
   1113 	ADD_TESTCASE(bind_array_buffer, "Change array buffer and refresh vertex attrib pointer.",
   1114 		true,
   1115 		false,
   1116 		MACRO_BLOCK({
   1117 			requireCoordBuffers(2);
   1118 			requireTextures(1);
   1119 			requirePrograms(1);
   1120 
   1121 			gl.bindAttribLocation(m_programs[0]->getProgram(), 0, "a_coord");
   1122 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindAttribLocation()");
   1123 			gl.linkProgram(m_programs[0]->getProgram());
   1124 			GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram()");
   1125 
   1126 			gl.useProgram(m_programs[0]->getProgram());
   1127 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
   1128 
   1129 			gl.enableVertexAttribArray(0);
   1130 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
   1131 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
   1132 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
   1133 			gl.vertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
   1134 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
   1135 
   1136 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
   1137 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
   1138 
   1139 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
   1140 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
   1141 
   1142 			gl.uniform1i(samplerLoc, 0);
   1143 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
   1144 
   1145 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1146 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
   1147 		}),
   1148 		MACRO_BLOCK({
   1149 			if (stateId == 0)
   1150 			{
   1151 				gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
   1152 				gl.vertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
   1153 			}
   1154 			else if (stateId == 1)
   1155 			{
   1156 				gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[1]);
   1157 				gl.vertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
   1158 			}
   1159 			else
   1160 				DE_ASSERT(false);
   1161 		})
   1162 	)
   1163 
   1164 	ADD_TESTCASE(element_array_buffer, "Change element array buffer.",
   1165 		false,
   1166 		true,
   1167 		MACRO_BLOCK({
   1168 			requireCoordBuffers(1);
   1169 			requireIndexBuffers(2);
   1170 			requireTextures(1);
   1171 			requirePrograms(1);
   1172 
   1173 			gl.useProgram(m_programs[0]->getProgram());
   1174 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
   1175 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
   1176 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
   1177 
   1178 			gl.enableVertexAttribArray(coordLoc);
   1179 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
   1180 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
   1181 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
   1182 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
   1183 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
   1184 
   1185 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
   1186 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
   1187 
   1188 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
   1189 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
   1190 
   1191 			gl.uniform1i(samplerLoc, 0);
   1192 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
   1193 
   1194 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1195 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
   1196 
   1197 			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[0]);
   1198 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
   1199 		}),
   1200 		MACRO_BLOCK({
   1201 			if (stateId == 0)
   1202 				gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[0]);
   1203 			else if (stateId == 1)
   1204 				gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffers[1]);
   1205 			else
   1206 				DE_ASSERT(false);
   1207 		})
   1208 	)
   1209 
   1210 	ADD_TESTCASE(bind_texture, "Change texture binding.",
   1211 		true,
   1212 		false,
   1213 		MACRO_BLOCK({
   1214 			requireCoordBuffers(1);
   1215 			requireTextures(2);
   1216 			requirePrograms(1);
   1217 
   1218 			gl.useProgram(m_programs[0]->getProgram());
   1219 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
   1220 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
   1221 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
   1222 
   1223 			gl.enableVertexAttribArray(coordLoc);
   1224 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
   1225 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
   1226 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
   1227 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
   1228 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
   1229 
   1230 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
   1231 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
   1232 
   1233 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
   1234 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
   1235 
   1236 			gl.uniform1i(samplerLoc, 0);
   1237 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
   1238 
   1239 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1240 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
   1241 		}),
   1242 		MACRO_BLOCK({
   1243 			if (stateId == 0)
   1244 				gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
   1245 			else if (stateId == 1)
   1246 				gl.bindTexture(GL_TEXTURE_2D, m_textures[1]);
   1247 			else
   1248 				DE_ASSERT(false);
   1249 		})
   1250 	)
   1251 
   1252 	ADD_TESTCASE(use_program, "Change used program.",
   1253 		true,
   1254 		false,
   1255 		MACRO_BLOCK({
   1256 			requireCoordBuffers(1);
   1257 			requireTextures(1);
   1258 			requirePrograms(2);
   1259 
   1260 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
   1261 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
   1262 
   1263 			gl.enableVertexAttribArray(coordLoc);
   1264 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
   1265 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
   1266 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
   1267 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
   1268 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
   1269 
   1270 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
   1271 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
   1272 
   1273 			{
   1274 				GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
   1275 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
   1276 				gl.useProgram(m_programs[0]->getProgram());
   1277 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
   1278 				gl.uniform1i(samplerLoc, 0);
   1279 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
   1280 			}
   1281 
   1282 			{
   1283 				GLint samplerLoc = gl.getUniformLocation(m_programs[1]->getProgram(), "u_sampler");
   1284 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
   1285 				gl.useProgram(m_programs[1]->getProgram());
   1286 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
   1287 				gl.uniform1i(samplerLoc, 0);
   1288 				GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
   1289 			}
   1290 
   1291 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1292 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
   1293 		}),
   1294 		MACRO_BLOCK({
   1295 			if (stateId == 0)
   1296 				gl.useProgram(m_programs[0]->getProgram());
   1297 			else if (stateId == 1)
   1298 				gl.useProgram(m_programs[1]->getProgram());
   1299 			else
   1300 				DE_ASSERT(false);
   1301 		})
   1302 	)
   1303 
   1304 	ADD_TESTCASE(tex_parameter_min_filter, "Change texture parameter min filter.",
   1305 		true,
   1306 		false,
   1307 		MACRO_BLOCK({
   1308 			requireCoordBuffers(1);
   1309 			requireTextures(1);
   1310 			requirePrograms(1);
   1311 
   1312 			gl.useProgram(m_programs[0]->getProgram());
   1313 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
   1314 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
   1315 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
   1316 
   1317 			gl.enableVertexAttribArray(coordLoc);
   1318 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
   1319 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
   1320 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
   1321 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
   1322 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
   1323 
   1324 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
   1325 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
   1326 
   1327 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
   1328 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
   1329 
   1330 			gl.uniform1i(samplerLoc, 0);
   1331 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
   1332 
   1333 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1334 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
   1335 		}),
   1336 		MACRO_BLOCK({
   1337 			if (stateId == 0)
   1338 				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   1339 			else if (stateId == 1)
   1340 				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   1341 			else
   1342 				DE_ASSERT(false);
   1343 		})
   1344 	)
   1345 
   1346 	ADD_TESTCASE(tex_parameter_mag_filter, "Change texture parameter mag filter.",
   1347 		true,
   1348 		false,
   1349 		MACRO_BLOCK({
   1350 			requireCoordBuffers(1);
   1351 			requireTextures(1);
   1352 			requirePrograms(1);
   1353 
   1354 			gl.useProgram(m_programs[0]->getProgram());
   1355 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
   1356 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
   1357 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
   1358 
   1359 			gl.enableVertexAttribArray(coordLoc);
   1360 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
   1361 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
   1362 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
   1363 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
   1364 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
   1365 
   1366 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
   1367 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
   1368 
   1369 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
   1370 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
   1371 
   1372 			gl.uniform1i(samplerLoc, 0);
   1373 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
   1374 
   1375 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1376 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
   1377 		}),
   1378 		MACRO_BLOCK({
   1379 			if (stateId == 0)
   1380 				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   1381 			else if (stateId == 1)
   1382 				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   1383 			else
   1384 				DE_ASSERT(false);
   1385 		})
   1386 	)
   1387 
   1388 	ADD_TESTCASE(tex_parameter_wrap, "Change texture parameter wrap filter.",
   1389 		true,
   1390 		false,
   1391 		MACRO_BLOCK({
   1392 			requireCoordBuffers(1);
   1393 			requireTextures(1);
   1394 			requirePrograms(1);
   1395 
   1396 			gl.useProgram(m_programs[0]->getProgram());
   1397 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
   1398 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
   1399 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
   1400 
   1401 			gl.enableVertexAttribArray(coordLoc);
   1402 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
   1403 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
   1404 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
   1405 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
   1406 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
   1407 
   1408 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
   1409 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
   1410 
   1411 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
   1412 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
   1413 
   1414 			gl.uniform1i(samplerLoc, 0);
   1415 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
   1416 
   1417 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1418 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
   1419 		}),
   1420 		MACRO_BLOCK({
   1421 			if (stateId == 0)
   1422 				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
   1423 			else if (stateId == 1)
   1424 				gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   1425 			else
   1426 				DE_ASSERT(false);
   1427 		})
   1428 	)
   1429 
   1430 	ADD_TESTCASE(bind_framebuffer, "Change framebuffer.",
   1431 		true,
   1432 		false,
   1433 		MACRO_BLOCK({
   1434 			requireCoordBuffers(1);
   1435 			requireTextures(1);
   1436 			requireFramebuffers(2);
   1437 			requirePrograms(1);
   1438 
   1439 			gl.useProgram(m_programs[0]->getProgram());
   1440 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
   1441 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
   1442 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
   1443 
   1444 			gl.enableVertexAttribArray(coordLoc);
   1445 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
   1446 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
   1447 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
   1448 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
   1449 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
   1450 
   1451 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
   1452 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
   1453 
   1454 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
   1455 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
   1456 
   1457 			gl.uniform1i(samplerLoc, 0);
   1458 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
   1459 
   1460 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1461 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
   1462 
   1463 			gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[0]);
   1464 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer()");
   1465 		}),
   1466 		MACRO_BLOCK({
   1467 			if (stateId == 0)
   1468 				gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[0]);
   1469 			else if (stateId == 1)
   1470 				gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[1]);
   1471 			else
   1472 				DE_ASSERT(false);
   1473 		})
   1474 	)
   1475 
   1476 	ADD_TESTCASE(blend_color, "Change blend color.",
   1477 		true,
   1478 		false,
   1479 		MACRO_BLOCK({
   1480 			requireCoordBuffers(1);
   1481 			requireTextures(1);
   1482 			requirePrograms(1);
   1483 
   1484 			gl.useProgram(m_programs[0]->getProgram());
   1485 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram()");
   1486 			GLint coordLoc = gl.getAttribLocation(m_programs[0]->getProgram(), "a_coord");
   1487 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetAttribLocation()");
   1488 
   1489 			gl.enableVertexAttribArray(coordLoc);
   1490 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray()");
   1491 			gl.bindBuffer(GL_ARRAY_BUFFER, m_coordBuffers[0]);
   1492 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer()");
   1493 			gl.vertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, NULL);
   1494 			GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer()");
   1495 
   1496 			GLint samplerLoc = gl.getUniformLocation(m_programs[0]->getProgram(), "u_sampler");
   1497 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
   1498 
   1499 			gl.bindTexture(GL_TEXTURE_2D, m_textures[0]);
   1500 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture()");
   1501 
   1502 			gl.uniform1i(samplerLoc, 0);
   1503 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i()");
   1504 
   1505 			gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1506 			GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport()");
   1507 
   1508 			gl.enable(GL_BLEND);
   1509 			GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable()");
   1510 
   1511 			gl.blendFunc(GL_CONSTANT_COLOR, GL_CONSTANT_COLOR);
   1512 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBlendFunc()");
   1513 		}),
   1514 		MACRO_BLOCK({
   1515 			if (stateId == 0)
   1516 				gl.blendColor(0.25f, 0.25f, 0.25f, 0.25f);
   1517 			else if (stateId == 1)
   1518 				gl.blendColor(0.75f, 0.75f, 0.75f, 0.75f);
   1519 			else
   1520 				DE_ASSERT(false);
   1521 		})
   1522 	)
   1523 }
   1524 
   1525 } // Performance
   1526 } // gles2
   1527 } // deqp
   1528