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