Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 3.0 Module
      3  * -------------------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief FBO invalidate tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es3fFboInvalidateTests.hpp"
     25 #include "es3fFboTestCase.hpp"
     26 #include "es3fFboTestUtil.hpp"
     27 #include "gluTextureUtil.hpp"
     28 #include "tcuImageCompare.hpp"
     29 #include "tcuTextureUtil.hpp"
     30 #include "sglrContextUtil.hpp"
     31 
     32 #include "glwEnums.hpp"
     33 
     34 #include <algorithm>
     35 
     36 namespace deqp
     37 {
     38 namespace gles3
     39 {
     40 namespace Functional
     41 {
     42 
     43 using std::string;
     44 using std::vector;
     45 using tcu::Vec2;
     46 using tcu::Vec3;
     47 using tcu::Vec4;
     48 using tcu::IVec2;
     49 using tcu::IVec3;
     50 using tcu::IVec4;
     51 using tcu::UVec4;
     52 using namespace FboTestUtil;
     53 
     54 static std::vector<deUint32> getDefaultFBDiscardAttachments (deUint32 discardBufferBits)
     55 {
     56 	vector<deUint32> attachments;
     57 
     58 	if (discardBufferBits & GL_COLOR_BUFFER_BIT)
     59 		attachments.push_back(GL_COLOR);
     60 
     61 	if (discardBufferBits & GL_DEPTH_BUFFER_BIT)
     62 		attachments.push_back(GL_DEPTH);
     63 
     64 	if (discardBufferBits & GL_STENCIL_BUFFER_BIT)
     65 		attachments.push_back(GL_STENCIL);
     66 
     67 	return attachments;
     68 }
     69 
     70 static std::vector<deUint32> getFBODiscardAttachments (deUint32 discardBufferBits)
     71 {
     72 	vector<deUint32> attachments;
     73 
     74 	if (discardBufferBits & GL_COLOR_BUFFER_BIT)
     75 		attachments.push_back(GL_COLOR_ATTACHMENT0);
     76 
     77 	// \note DEPTH_STENCIL_ATTACHMENT is allowed when discarding FBO, but not with default FB
     78 	if ((discardBufferBits & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) == (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT))
     79 		attachments.push_back(GL_DEPTH_STENCIL_ATTACHMENT);
     80 	else if (discardBufferBits & GL_DEPTH_BUFFER_BIT)
     81 		attachments.push_back(GL_DEPTH_ATTACHMENT);
     82 	else if (discardBufferBits & GL_STENCIL_BUFFER_BIT)
     83 		attachments.push_back(GL_STENCIL_ATTACHMENT);
     84 
     85 	return attachments;
     86 }
     87 
     88 static inline bool hasAttachment (const std::vector<deUint32>& attachmentList, deUint32 attachment)
     89 {
     90 	return std::find(attachmentList.begin(), attachmentList.end(), attachment) != attachmentList.end();
     91 }
     92 
     93 static deUint32 getCompatibleColorFormat (const tcu::RenderTarget& renderTargetInfo)
     94 {
     95 	const tcu::PixelFormat& pxFmt = renderTargetInfo.getPixelFormat();
     96 	DE_ASSERT(de::inBounds(pxFmt.redBits,	0, 0xff) &&
     97 			  de::inBounds(pxFmt.greenBits,	0, 0xff) &&
     98 			  de::inBounds(pxFmt.blueBits,	0, 0xff) &&
     99 			  de::inBounds(pxFmt.alphaBits,	0, 0xff));
    100 
    101 #define PACK_FMT(R, G, B, A) (((R) << 24) | ((G) << 16) | ((B) << 8) | (A))
    102 
    103 	// \note [pyry] This may not hold true on some implementations - best effort guess only.
    104 	switch (PACK_FMT(pxFmt.redBits, pxFmt.greenBits, pxFmt.blueBits, pxFmt.alphaBits))
    105 	{
    106 		case PACK_FMT(8,8,8,8):		return GL_RGBA8;
    107 		case PACK_FMT(8,8,8,0):		return GL_RGB8;
    108 		case PACK_FMT(4,4,4,4):		return GL_RGBA4;
    109 		case PACK_FMT(5,5,5,1):		return GL_RGB5_A1;
    110 		case PACK_FMT(5,6,5,0):		return GL_RGB565;
    111 		default:					return GL_NONE;
    112 	}
    113 
    114 #undef PACK_FMT
    115 }
    116 
    117 static deUint32 getCompatibleDepthStencilFormat (const tcu::RenderTarget& renderTargetInfo)
    118 {
    119 	const int	depthBits		= renderTargetInfo.getDepthBits();
    120 	const int	stencilBits		= renderTargetInfo.getStencilBits();
    121 	const bool	hasDepth		= depthBits > 0;
    122 	const bool	hasStencil		= stencilBits > 0;
    123 
    124 	if (!hasDepth || !hasStencil || (stencilBits != 8))
    125 		return GL_NONE;
    126 
    127 	if (depthBits == 32)
    128 		return GL_DEPTH32F_STENCIL8;
    129 	else if (depthBits == 24)
    130 		return GL_DEPTH24_STENCIL8;
    131 	else
    132 		return GL_NONE;
    133 }
    134 
    135 class InvalidateDefaultFramebufferRenderCase : public FboTestCase
    136 {
    137 public:
    138 	InvalidateDefaultFramebufferRenderCase (Context& context, const char* name, const char* description, deUint32 buffers, deUint32 fboTarget = GL_FRAMEBUFFER)
    139 		: FboTestCase	(context, name, description)
    140 		, m_buffers		(buffers)
    141 		, m_fboTarget	(fboTarget)
    142 	{
    143 	}
    144 
    145 	void render (tcu::Surface& dst)
    146 	{
    147 		FlatColorShader		flatShader	(glu::TYPE_FLOAT_VEC4);
    148 		vector<deUint32>	attachments	= getDefaultFBDiscardAttachments(m_buffers);
    149 		deUint32			flatShaderID= getCurrentContext()->createProgram(&flatShader);
    150 
    151 		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
    152 		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    153 
    154 		glEnable		(GL_DEPTH_TEST);
    155 		glEnable		(GL_STENCIL_TEST);
    156 		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
    157 		glStencilFunc	(GL_ALWAYS, 1, 0xff);
    158 
    159 		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
    160 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
    161 
    162 		glInvalidateFramebuffer(m_fboTarget, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0]);
    163 
    164 		if ((m_buffers & GL_COLOR_BUFFER_BIT) != 0)
    165 		{
    166 			// Color was not preserved - fill with green.
    167 			glDisable(GL_DEPTH_TEST);
    168 			glDisable(GL_STENCIL_TEST);
    169 
    170 			flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
    171 			sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
    172 
    173 			glEnable(GL_DEPTH_TEST);
    174 			glEnable(GL_STENCIL_TEST);
    175 		}
    176 
    177 		if ((m_buffers & GL_DEPTH_BUFFER_BIT) != 0)
    178 		{
    179 			// Depth was not preserved.
    180 			glDepthFunc(GL_ALWAYS);
    181 		}
    182 
    183 		if ((m_buffers & GL_STENCIL_BUFFER_BIT) == 0)
    184 		{
    185 			// Stencil was preserved.
    186 			glStencilFunc(GL_EQUAL, 1, 0xff);
    187 		}
    188 
    189 		glEnable		(GL_BLEND);
    190 		glBlendFunc		(GL_ONE, GL_ONE);
    191 		glBlendEquation	(GL_FUNC_ADD);
    192 
    193 		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f));
    194 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
    195 
    196 		readPixels(dst, 0, 0, getWidth(), getHeight());
    197 	}
    198 
    199 private:
    200 	deUint32 m_buffers;
    201 	deUint32 m_fboTarget;
    202 };
    203 
    204 class InvalidateDefaultFramebufferBindCase : public FboTestCase
    205 {
    206 public:
    207 	InvalidateDefaultFramebufferBindCase (Context& context, const char* name, const char* description, deUint32 buffers)
    208 		: FboTestCase	(context, name, description)
    209 		, m_buffers		(buffers)
    210 	{
    211 	}
    212 
    213 	void render (tcu::Surface& dst)
    214 	{
    215 		deUint32			fbo			= 0;
    216 		deUint32			tex			= 0;
    217 		FlatColorShader		flatShader	(glu::TYPE_FLOAT_VEC4);
    218 		Texture2DShader		texShader	(DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
    219 		GradientShader		gradShader	(glu::TYPE_FLOAT_VEC4);
    220 		vector<deUint32>	attachments	= getDefaultFBDiscardAttachments(m_buffers);
    221 		deUint32			flatShaderID= getCurrentContext()->createProgram(&flatShader);
    222 		deUint32			texShaderID = getCurrentContext()->createProgram(&texShader);
    223 		deUint32			gradShaderID= getCurrentContext()->createProgram(&gradShader);
    224 
    225 		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
    226 		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    227 
    228 		// Create fbo.
    229 		glGenFramebuffers		(1, &fbo);
    230 		glGenTextures			(1, &tex);
    231 		glBindTexture			(GL_TEXTURE_2D, tex);
    232 		glTexImage2D			(GL_TEXTURE_2D, 0, GL_RGBA8, getWidth(), getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
    233 		glTexParameteri			(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    234 		glBindFramebuffer		(GL_FRAMEBUFFER, fbo);
    235 		glFramebufferTexture2D	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
    236 		glBindTexture			(GL_TEXTURE_2D, 0);
    237 		checkFramebufferStatus	(GL_FRAMEBUFFER);
    238 
    239 		glBindFramebuffer		(GL_FRAMEBUFFER, 0);
    240 
    241 		glEnable		(GL_DEPTH_TEST);
    242 		glEnable		(GL_STENCIL_TEST);
    243 		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
    244 		glStencilFunc	(GL_ALWAYS, 1, 0xff);
    245 
    246 		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
    247 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
    248 
    249 		glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0]);
    250 
    251 		// Switch to fbo and render gradient into it.
    252 		glDisable			(GL_DEPTH_TEST);
    253 		glDisable			(GL_STENCIL_TEST);
    254 		glBindFramebuffer	(GL_FRAMEBUFFER, fbo);
    255 
    256 		gradShader.setGradient(*getCurrentContext(), gradShaderID, Vec4(0.0f), Vec4(1.0f));
    257 		sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
    258 
    259 		// Restore default fbo.
    260 		glBindFramebuffer	(GL_FRAMEBUFFER, 0);
    261 
    262 		if ((m_buffers & GL_COLOR_BUFFER_BIT) != 0)
    263 		{
    264 			// Color was not preserved - fill with green.
    265 			flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
    266 			sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
    267 		}
    268 
    269 		if ((m_buffers & GL_DEPTH_BUFFER_BIT) != 0)
    270 		{
    271 			// Depth was not preserved.
    272 			glDepthFunc(GL_ALWAYS);
    273 		}
    274 
    275 		if ((m_buffers & GL_STENCIL_BUFFER_BIT) == 0)
    276 		{
    277 			// Stencil was preserved.
    278 			glStencilFunc(GL_EQUAL, 1, 0xff);
    279 		}
    280 
    281 		glEnable		(GL_DEPTH_TEST);
    282 		glEnable		(GL_STENCIL_TEST);
    283 		glEnable		(GL_BLEND);
    284 		glBlendFunc		(GL_ONE, GL_ONE);
    285 		glBlendEquation	(GL_FUNC_ADD);
    286 		glBindTexture	(GL_TEXTURE_2D, tex);
    287 
    288 		texShader.setUniforms(*getCurrentContext(), texShaderID);
    289 		sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
    290 
    291 		readPixels(dst, 0, 0, getWidth(), getHeight());
    292 	}
    293 
    294 private:
    295 	deUint32 m_buffers;
    296 };
    297 
    298 class InvalidateDefaultSubFramebufferRenderCase : public FboTestCase
    299 {
    300 public:
    301 	InvalidateDefaultSubFramebufferRenderCase (Context& context, const char* name, const char* description, deUint32 buffers)
    302 		: FboTestCase	(context, name, description)
    303 		, m_buffers		(buffers)
    304 	{
    305 	}
    306 
    307 	void render (tcu::Surface& dst)
    308 	{
    309 		int					invalidateX		= getWidth()	/ 4;
    310 		int					invalidateY		= getHeight()	/ 4;
    311 		int					invalidateW		= getWidth()	/ 2;
    312 		int					invalidateH		= getHeight()	/ 2;
    313 		FlatColorShader		flatShader		(glu::TYPE_FLOAT_VEC4);
    314 		vector<deUint32>	attachments		= getDefaultFBDiscardAttachments(m_buffers);
    315 		deUint32			flatShaderID	= getCurrentContext()->createProgram(&flatShader);
    316 
    317 		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
    318 		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    319 
    320 		glEnable		(GL_DEPTH_TEST);
    321 		glEnable		(GL_STENCIL_TEST);
    322 		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
    323 		glStencilFunc	(GL_ALWAYS, 1, 0xff);
    324 
    325 		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
    326 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
    327 
    328 		glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH);
    329 
    330 		// Clear invalidated buffers.
    331 		glClearColor	(0.0f, 1.0f, 0.0f, 1.0f);
    332 		glClearStencil	(1);
    333 		glScissor		(invalidateX, invalidateY, invalidateW, invalidateH);
    334 		glEnable		(GL_SCISSOR_TEST);
    335 		glClear			(m_buffers);
    336 		glDisable		(GL_SCISSOR_TEST);
    337 
    338 		glEnable		(GL_BLEND);
    339 		glBlendFunc		(GL_ONE, GL_ONE);
    340 		glBlendEquation	(GL_FUNC_ADD);
    341 
    342 		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f));
    343 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
    344 
    345 		readPixels(dst, 0, 0, getWidth(), getHeight());
    346 	}
    347 
    348 private:
    349 	deUint32 m_buffers;
    350 };
    351 
    352 class InvalidateDefaultSubFramebufferBindCase : public FboTestCase
    353 {
    354 public:
    355 	InvalidateDefaultSubFramebufferBindCase (Context& context, const char* name, const char* description, deUint32 buffers)
    356 		: FboTestCase	(context, name, description)
    357 		, m_buffers		(buffers)
    358 	{
    359 	}
    360 
    361 	void render (tcu::Surface& dst)
    362 	{
    363 		deUint32			fbo				= 0;
    364 		deUint32			tex				= 0;
    365 		FlatColorShader		flatShader		(glu::TYPE_FLOAT_VEC4);
    366 		Texture2DShader		texShader		(DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4);
    367 		GradientShader		gradShader		(glu::TYPE_FLOAT_VEC4);
    368 		vector<deUint32>	attachments		= getDefaultFBDiscardAttachments(m_buffers);
    369 		deUint32			flatShaderID	= getCurrentContext()->createProgram(&flatShader);
    370 		deUint32			texShaderID		= getCurrentContext()->createProgram(&texShader);
    371 		deUint32			gradShaderID	= getCurrentContext()->createProgram(&gradShader);
    372 
    373 		int				invalidateX		= getWidth()	/ 4;
    374 		int				invalidateY		= getHeight()	/ 4;
    375 		int				invalidateW		= getWidth()	/ 2;
    376 		int				invalidateH		= getHeight()	/ 2;
    377 
    378 
    379 		flatShader.setColor   (*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
    380 		texShader.setUniforms (*getCurrentContext(), texShaderID);
    381 		gradShader.setGradient(*getCurrentContext(), gradShaderID, Vec4(0.0f), Vec4(1.0f));
    382 
    383 		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
    384 		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    385 
    386 		// Create fbo.
    387 		glGenFramebuffers		(1, &fbo);
    388 		glGenTextures			(1, &tex);
    389 		glBindTexture			(GL_TEXTURE_2D, tex);
    390 		glTexImage2D			(GL_TEXTURE_2D, 0, GL_RGBA8, getWidth(), getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL);
    391 		glTexParameteri			(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    392 		glBindFramebuffer		(GL_FRAMEBUFFER, fbo);
    393 		glFramebufferTexture2D	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
    394 		glBindTexture			(GL_TEXTURE_2D, 0);
    395 		checkFramebufferStatus	(GL_FRAMEBUFFER);
    396 
    397 		glBindFramebuffer		(GL_FRAMEBUFFER, 0);
    398 
    399 		glEnable		(GL_DEPTH_TEST);
    400 		glEnable		(GL_STENCIL_TEST);
    401 		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
    402 		glStencilFunc	(GL_ALWAYS, 1, 0xff);
    403 
    404 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
    405 
    406 		glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH);
    407 
    408 		// Switch to fbo and render gradient into it.
    409 		glDisable			(GL_DEPTH_TEST);
    410 		glDisable			(GL_STENCIL_TEST);
    411 		glBindFramebuffer	(GL_FRAMEBUFFER, fbo);
    412 
    413 		sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
    414 
    415 		// Restore default fbo.
    416 		glBindFramebuffer	(GL_FRAMEBUFFER, 0);
    417 
    418 		// Clear invalidated buffers.
    419 		glClearColor	(0.0f, 1.0f, 0.0f, 1.0f);
    420 		glClearStencil	(1);
    421 		glScissor		(invalidateX, invalidateY, invalidateW, invalidateH);
    422 		glEnable		(GL_SCISSOR_TEST);
    423 		glClear			(m_buffers);
    424 		glDisable		(GL_SCISSOR_TEST);
    425 
    426 		glEnable		(GL_DEPTH_TEST);
    427 		glEnable		(GL_STENCIL_TEST);
    428 		glEnable		(GL_BLEND);
    429 		glBlendFunc		(GL_ONE, GL_ONE);
    430 		glBlendEquation	(GL_FUNC_ADD);
    431 		glBindTexture	(GL_TEXTURE_2D, tex);
    432 
    433 		sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
    434 
    435 		readPixels(dst, 0, 0, getWidth(), getHeight());
    436 	}
    437 
    438 private:
    439 	deUint32 m_buffers;
    440 };
    441 
    442 class InvalidateFboRenderCase : public FboTestCase
    443 {
    444 public:
    445 	InvalidateFboRenderCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers)
    446 		: FboTestCase			(context, name, description)
    447 		, m_colorFmt			(colorFmt)
    448 		, m_depthStencilFmt		(depthStencilFmt)
    449 		, m_invalidateBuffers	(invalidateBuffers)
    450 	{
    451 	}
    452 
    453 protected:
    454 	void preCheck (void)
    455 	{
    456 		if (m_colorFmt != GL_NONE)			checkFormatSupport(m_colorFmt);
    457 		if (m_depthStencilFmt != GL_NONE)	checkFormatSupport(m_depthStencilFmt);
    458 	}
    459 
    460 	void render (tcu::Surface& dst)
    461 	{
    462 		tcu::TextureFormat		colorFmt				= glu::mapGLInternalFormat(m_colorFmt);
    463 		tcu::TextureFormat		depthStencilFmt			= m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
    464 		tcu::TextureFormatInfo	colorFmtInfo			= tcu::getTextureFormatInfo(colorFmt);
    465 		bool					depth					= depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
    466 		bool					stencil					= depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
    467 		const tcu::Vec4&		cBias					= colorFmtInfo.valueMin;
    468 		tcu::Vec4				cScale					= colorFmtInfo.valueMax-colorFmtInfo.valueMin;
    469 		deUint32				fbo						= 0;
    470 		deUint32				colorRbo				= 0;
    471 		deUint32				depthStencilRbo			= 0;
    472 		FlatColorShader			flatShader				(glu::TYPE_FLOAT_VEC4);
    473 		vector<deUint32>		attachments				= getFBODiscardAttachments(m_invalidateBuffers);
    474 		deUint32				flatShaderID			= getCurrentContext()->createProgram(&flatShader);
    475 
    476 		// Create fbo.
    477 		glGenRenderbuffers		(1, &colorRbo);
    478 		glBindRenderbuffer		(GL_RENDERBUFFER, colorRbo);
    479 		glRenderbufferStorage	(GL_RENDERBUFFER, m_colorFmt, getWidth(), getHeight());
    480 
    481 		if (m_depthStencilFmt != GL_NONE)
    482 		{
    483 			glGenRenderbuffers		(1, &depthStencilRbo);
    484 			glBindRenderbuffer		(GL_RENDERBUFFER, depthStencilRbo);
    485 			glRenderbufferStorage	(GL_RENDERBUFFER, m_depthStencilFmt, getWidth(), getHeight());
    486 		}
    487 
    488 		glGenFramebuffers			(1, &fbo);
    489 		glBindFramebuffer			(GL_FRAMEBUFFER, fbo);
    490 		glFramebufferRenderbuffer	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
    491 
    492 		if (depth)
    493 			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
    494 
    495 		if (stencil)
    496 			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
    497 
    498 		checkFramebufferStatus		(GL_FRAMEBUFFER);
    499 
    500 		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
    501 		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    502 
    503 		glEnable		(GL_DEPTH_TEST);
    504 		glEnable		(GL_STENCIL_TEST);
    505 		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
    506 		glStencilFunc	(GL_ALWAYS, 1, 0xff);
    507 
    508 		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias);
    509 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
    510 
    511 		glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0]);
    512 
    513 		if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0)
    514 		{
    515 			// Color was not preserved - fill with green.
    516 			glDisable(GL_DEPTH_TEST);
    517 			glDisable(GL_STENCIL_TEST);
    518 
    519 			flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias);
    520 			sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
    521 
    522 			glEnable(GL_DEPTH_TEST);
    523 			glEnable(GL_STENCIL_TEST);
    524 		}
    525 
    526 		if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0)
    527 		{
    528 			// Depth was not preserved.
    529 			glDepthFunc(GL_ALWAYS);
    530 		}
    531 
    532 		if ((m_invalidateBuffers & GL_STENCIL_BUFFER_BIT) == 0)
    533 		{
    534 			// Stencil was preserved.
    535 			glStencilFunc(GL_EQUAL, 1, 0xff);
    536 		}
    537 
    538 		glEnable		(GL_BLEND);
    539 		glBlendFunc		(GL_ONE, GL_ONE);
    540 		glBlendEquation	(GL_FUNC_ADD);
    541 
    542 		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)*cScale + cBias);
    543 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
    544 
    545 		readPixels(dst, 0, 0, getWidth(), getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
    546 	}
    547 
    548 private:
    549 	deUint32	m_colorFmt;
    550 	deUint32	m_depthStencilFmt;
    551 	deUint32	m_invalidateBuffers;
    552 };
    553 
    554 class InvalidateFboUnbindReadCase : public FboTestCase
    555 {
    556 public:
    557 	InvalidateFboUnbindReadCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers)
    558 		: FboTestCase			(context, name, description)
    559 		, m_colorFmt			(colorFmt)
    560 		, m_depthStencilFmt		(depthStencilFmt)
    561 		, m_invalidateBuffers	(invalidateBuffers)
    562 	{
    563 		DE_ASSERT((m_invalidateBuffers & (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)) != (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT));
    564 	}
    565 
    566 protected:
    567 	void preCheck (void)
    568 	{
    569 		if (m_colorFmt != GL_NONE)			checkFormatSupport(m_colorFmt);
    570 		if (m_depthStencilFmt != GL_NONE)	checkFormatSupport(m_depthStencilFmt);
    571 	}
    572 
    573 	void render (tcu::Surface& dst)
    574 	{
    575 		tcu::TextureFormat		colorFmt				= glu::mapGLInternalFormat(m_colorFmt);
    576 		tcu::TextureFormat		depthStencilFmt			= m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
    577 		tcu::TextureFormatInfo	colorFmtInfo			= tcu::getTextureFormatInfo(colorFmt);
    578 		bool					depth					= depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
    579 		bool					stencil					= depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
    580 		deUint32				fbo						= 0;
    581 		deUint32				colorTex				= 0;
    582 		deUint32				depthStencilTex			= 0;
    583 		GradientShader			gradShader				(getFragmentOutputType(colorFmt));
    584 		vector<deUint32>		attachments				= getFBODiscardAttachments(m_invalidateBuffers);
    585 		deUint32				gradShaderID			= getCurrentContext()->createProgram(&gradShader);
    586 
    587 		// Create fbo.
    588 		{
    589 			glu::TransferFormat transferFmt = glu::getTransferFormat(colorFmt);
    590 
    591 			glGenTextures	(1, &colorTex);
    592 			glBindTexture	(GL_TEXTURE_2D, colorTex);
    593 			glTexImage2D	(GL_TEXTURE_2D, 0, m_colorFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
    594 			glTexParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    595 		}
    596 
    597 		if (m_depthStencilFmt != GL_NONE)
    598 		{
    599 			glu::TransferFormat transferFmt = glu::getTransferFormat(depthStencilFmt);
    600 
    601 			glGenTextures	(1, &depthStencilTex);
    602 			glBindTexture	(GL_TEXTURE_2D, depthStencilTex);
    603 			glTexImage2D	(GL_TEXTURE_2D, 0, m_depthStencilFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
    604 			glTexParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    605 			glTexParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    606 		}
    607 
    608 		glGenFramebuffers		(1, &fbo);
    609 		glBindFramebuffer		(GL_FRAMEBUFFER, fbo);
    610 		glFramebufferTexture2D	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
    611 
    612 		if (depth)
    613 			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0);
    614 
    615 		if (stencil)
    616 			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0);
    617 
    618 		checkFramebufferStatus		(GL_FRAMEBUFFER);
    619 
    620 		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
    621 		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    622 
    623 		glEnable		(GL_DEPTH_TEST);
    624 		glEnable		(GL_STENCIL_TEST);
    625 		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
    626 		glStencilFunc	(GL_ALWAYS, 1, 0xff);
    627 
    628 		gradShader.setGradient(*getCurrentContext(), gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
    629 		sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
    630 
    631 		glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0]);
    632 
    633 		glBindFramebuffer	(GL_FRAMEBUFFER, 0);
    634 		glDisable			(GL_DEPTH_TEST);
    635 		glDisable			(GL_STENCIL_TEST);
    636 
    637 		if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0)
    638 		{
    639 			// Render color.
    640 			Texture2DShader texShader(DataTypes() << glu::getSampler2DType(colorFmt), glu::TYPE_FLOAT_VEC4);
    641 			deUint32		texShaderID = getCurrentContext()->createProgram(&texShader);
    642 
    643 			texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
    644 			texShader.setUniforms(*getCurrentContext(), texShaderID);
    645 
    646 			glBindTexture(GL_TEXTURE_2D, colorTex);
    647 			sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
    648 		}
    649 		else
    650 		{
    651 			// Render depth.
    652 			Texture2DShader texShader(DataTypes() << glu::getSampler2DType(depthStencilFmt), glu::TYPE_FLOAT_VEC4);
    653 			deUint32		texShaderID = getCurrentContext()->createProgram(&texShader);
    654 
    655 			texShader.setUniforms(*getCurrentContext(), texShaderID);
    656 
    657 			glBindTexture(GL_TEXTURE_2D, depthStencilTex);
    658 			sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
    659 		}
    660 
    661 		readPixels(dst, 0, 0, getWidth(), getHeight());
    662 	}
    663 
    664 private:
    665 	deUint32	m_colorFmt;
    666 	deUint32	m_depthStencilFmt;
    667 	deUint32	m_invalidateBuffers;
    668 };
    669 
    670 class InvalidateFboUnbindBlitCase : public FboTestCase
    671 {
    672 public:
    673 	InvalidateFboUnbindBlitCase (Context& context, const char* name, const char* description, int numSamples, deUint32 invalidateBuffers)
    674 		: FboTestCase			(context, name, description, numSamples > 0)	// \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its
    675 																				//		 behing-the-scenes viewport position randomization, because with glBlitFramebuffer,
    676 																				//		 source and destination rectangles must match when multisampling.
    677 		, m_colorFmt			(0)
    678 		, m_depthStencilFmt		(0)
    679 		, m_numSamples			(numSamples)
    680 		, m_invalidateBuffers	(invalidateBuffers)
    681 	{
    682 		// Figure out formats that are compatible with default framebuffer.
    683 		m_colorFmt			= getCompatibleColorFormat(m_context.getRenderTarget());
    684 		m_depthStencilFmt	= getCompatibleDepthStencilFormat(m_context.getRenderTarget());
    685 	}
    686 
    687 protected:
    688 	void preCheck (void)
    689 	{
    690 		if (m_context.getRenderTarget().getNumSamples() > 0)
    691 			throw tcu::NotSupportedError("Not supported in MSAA config");
    692 
    693 		if (m_colorFmt == GL_NONE)
    694 			throw tcu::NotSupportedError("Unsupported color format");
    695 
    696 		if (m_depthStencilFmt == GL_NONE)
    697 			throw tcu::NotSupportedError("Unsupported depth/stencil format");
    698 
    699 		checkFormatSupport(m_colorFmt);
    700 		checkFormatSupport(m_depthStencilFmt);
    701 	}
    702 
    703 	void render (tcu::Surface& dst)
    704 	{
    705 		// \note When using fullscreen viewport (when m_numSamples > 0), still only use a 128x128 pixel quad at most.
    706 		IVec2					quadSizePixels			(m_numSamples == 0 ? getWidth() : de::min(128, getWidth()),
    707 														 m_numSamples == 0 ? getHeight() : de::min(128, getHeight()));
    708 		Vec2					quadNDCLeftBottomXY		(-1.0f, -1.0f);
    709 		Vec2					quadNDCSize				(2.0f*quadSizePixels.x()/getWidth(), 2.0f*quadSizePixels.y()/getHeight());
    710 		Vec2					quadNDCRightTopXY		= quadNDCLeftBottomXY + quadNDCSize;
    711 		tcu::TextureFormat		depthStencilFmt			= m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
    712 		bool					depth					= depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
    713 		bool					stencil					= depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
    714 		deUint32				fbo						= 0;
    715 		deUint32				colorRbo				= 0;
    716 		deUint32				depthStencilRbo			= 0;
    717 		FlatColorShader			flatShader				(glu::TYPE_FLOAT_VEC4);
    718 		vector<deUint32>		attachments				= getFBODiscardAttachments(m_invalidateBuffers);
    719 		deUint32				flatShaderID			= getCurrentContext()->createProgram(&flatShader);
    720 
    721 		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
    722 		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    723 
    724 		// Create fbo.
    725 		glGenRenderbuffers					(1, &colorRbo);
    726 		glBindRenderbuffer					(GL_RENDERBUFFER, colorRbo);
    727 		glRenderbufferStorageMultisample	(GL_RENDERBUFFER, m_numSamples, m_colorFmt, quadSizePixels.x(), quadSizePixels.y());
    728 
    729 		if (m_depthStencilFmt != GL_NONE)
    730 		{
    731 			glGenRenderbuffers					(1, &depthStencilRbo);
    732 			glBindRenderbuffer					(GL_RENDERBUFFER, depthStencilRbo);
    733 			glRenderbufferStorageMultisample	(GL_RENDERBUFFER, m_numSamples, m_depthStencilFmt, quadSizePixels.x(), quadSizePixels.y());
    734 		}
    735 
    736 		glGenFramebuffers			(1, &fbo);
    737 		glBindFramebuffer			(GL_FRAMEBUFFER, fbo);
    738 		glFramebufferRenderbuffer	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
    739 
    740 		if (depth)
    741 			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
    742 
    743 		if (stencil)
    744 			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
    745 
    746 		checkFramebufferStatus		(GL_FRAMEBUFFER);
    747 
    748 		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    749 
    750 		glEnable		(GL_DEPTH_TEST);
    751 		glEnable		(GL_STENCIL_TEST);
    752 		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
    753 		glStencilFunc	(GL_ALWAYS, 1, 0xff);
    754 
    755 		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
    756 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), -1.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 1.0f));
    757 
    758 		glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0]);
    759 
    760 		// Set default framebuffer as draw framebuffer and blit preserved buffers.
    761 		glBindFramebuffer	(GL_DRAW_FRAMEBUFFER, 0);
    762 		glBlitFramebuffer	(0, 0, quadSizePixels.x(), quadSizePixels.y(),
    763 							 0, 0, quadSizePixels.x(), quadSizePixels.y(),
    764 							 (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) & ~m_invalidateBuffers, GL_NEAREST);
    765 		glBindFramebuffer	(GL_READ_FRAMEBUFFER, 0);
    766 
    767 		if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0)
    768 		{
    769 			// Color was not preserved - fill with green.
    770 			glDisable(GL_DEPTH_TEST);
    771 			glDisable(GL_STENCIL_TEST);
    772 
    773 			flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
    774 			sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f));
    775 
    776 			glEnable(GL_DEPTH_TEST);
    777 			glEnable(GL_STENCIL_TEST);
    778 		}
    779 
    780 		if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0)
    781 		{
    782 			// Depth was not preserved.
    783 			glDepthFunc(GL_ALWAYS);
    784 		}
    785 
    786 		if ((m_invalidateBuffers & GL_STENCIL_BUFFER_BIT) == 0)
    787 		{
    788 			// Stencil was preserved.
    789 			glStencilFunc(GL_EQUAL, 1, 0xff);
    790 		}
    791 
    792 		glEnable		(GL_BLEND);
    793 		glBlendFunc		(GL_ONE, GL_ONE);
    794 		glBlendEquation	(GL_FUNC_ADD);
    795 
    796 		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f));
    797 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f));
    798 
    799 		readPixels(dst, 0, 0, quadSizePixels.x(), quadSizePixels.y());
    800 	}
    801 
    802 private:
    803 	deUint32	m_colorFmt;
    804 	deUint32	m_depthStencilFmt;
    805 	int			m_numSamples;
    806 	deUint32	m_invalidateBuffers;
    807 };
    808 
    809 class InvalidateSubFboRenderCase : public FboTestCase
    810 {
    811 public:
    812 	InvalidateSubFboRenderCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers)
    813 		: FboTestCase			(context, name, description)
    814 		, m_colorFmt			(colorFmt)
    815 		, m_depthStencilFmt		(depthStencilFmt)
    816 		, m_invalidateBuffers	(invalidateBuffers)
    817 	{
    818 	}
    819 
    820 protected:
    821 	void preCheck (void)
    822 	{
    823 		if (m_colorFmt != GL_NONE)			checkFormatSupport(m_colorFmt);
    824 		if (m_depthStencilFmt != GL_NONE)	checkFormatSupport(m_depthStencilFmt);
    825 	}
    826 
    827 	void render (tcu::Surface& dst)
    828 	{
    829 		tcu::TextureFormat		colorFmt				= glu::mapGLInternalFormat(m_colorFmt);
    830 		tcu::TextureFormat		depthStencilFmt			= m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
    831 		tcu::TextureFormatInfo	colorFmtInfo			= tcu::getTextureFormatInfo(colorFmt);
    832 		bool					depth					= depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
    833 		bool					stencil					= depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
    834 		const tcu::Vec4&		cBias					= colorFmtInfo.valueMin;
    835 		tcu::Vec4				cScale					= colorFmtInfo.valueMax-colorFmtInfo.valueMin;
    836 		deUint32				fbo						= 0;
    837 		deUint32				colorRbo				= 0;
    838 		deUint32				depthStencilRbo			= 0;
    839 		int						invalidateX				= getWidth()	/ 4;
    840 		int						invalidateY				= getHeight()	/ 4;
    841 		int						invalidateW				= getWidth()	/ 2;
    842 		int						invalidateH				= getHeight()	/ 2;
    843 		FlatColorShader			flatShader				(glu::TYPE_FLOAT_VEC4);
    844 		vector<deUint32>		attachments				= getFBODiscardAttachments(m_invalidateBuffers);
    845 		deUint32				flatShaderID			= getCurrentContext()->createProgram(&flatShader);
    846 
    847 		// Create fbo.
    848 		glGenRenderbuffers		(1, &colorRbo);
    849 		glBindRenderbuffer		(GL_RENDERBUFFER, colorRbo);
    850 		glRenderbufferStorage	(GL_RENDERBUFFER, m_colorFmt, getWidth(), getHeight());
    851 
    852 		if (m_depthStencilFmt != GL_NONE)
    853 		{
    854 			glGenRenderbuffers		(1, &depthStencilRbo);
    855 			glBindRenderbuffer		(GL_RENDERBUFFER, depthStencilRbo);
    856 			glRenderbufferStorage	(GL_RENDERBUFFER, m_depthStencilFmt, getWidth(), getHeight());
    857 		}
    858 
    859 		glGenFramebuffers			(1, &fbo);
    860 		glBindFramebuffer			(GL_FRAMEBUFFER, fbo);
    861 		glFramebufferRenderbuffer	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
    862 
    863 		if (depth)
    864 			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
    865 
    866 		if (stencil)
    867 			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
    868 
    869 		checkFramebufferStatus		(GL_FRAMEBUFFER);
    870 
    871 		glClearBufferfv	(GL_COLOR, 0, (Vec4(0.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias).getPtr());
    872 		glClearBufferfi	(GL_DEPTH_STENCIL, 0, 1.0f, 0);
    873 
    874 		glEnable		(GL_DEPTH_TEST);
    875 		glEnable		(GL_STENCIL_TEST);
    876 		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
    877 		glStencilFunc	(GL_ALWAYS, 1, 0xff);
    878 
    879 		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias);
    880 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
    881 
    882 		glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH);
    883 
    884 		// Clear invalidated buffers.
    885 		glScissor	(invalidateX, invalidateY, invalidateW, invalidateH);
    886 		glEnable	(GL_SCISSOR_TEST);
    887 
    888 		if (m_invalidateBuffers & GL_COLOR_BUFFER_BIT)
    889 			glClearBufferfv(GL_COLOR, 0, (Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias).getPtr());
    890 
    891 		glClear		(m_invalidateBuffers & ~GL_COLOR_BUFFER_BIT);
    892 		glDisable	(GL_SCISSOR_TEST);
    893 
    894 		glEnable		(GL_BLEND);
    895 		glBlendFunc		(GL_ONE, GL_ONE);
    896 		glBlendEquation	(GL_FUNC_ADD);
    897 
    898 		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)*cScale + cBias);
    899 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
    900 
    901 		readPixels(dst, 0, 0, getWidth(), getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
    902 	}
    903 
    904 private:
    905 	deUint32	m_colorFmt;
    906 	deUint32	m_depthStencilFmt;
    907 	deUint32	m_invalidateBuffers;
    908 };
    909 
    910 class InvalidateSubFboUnbindReadCase : public FboTestCase
    911 {
    912 public:
    913 	InvalidateSubFboUnbindReadCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers)
    914 		: FboTestCase			(context, name, description)
    915 		, m_colorFmt			(colorFmt)
    916 		, m_depthStencilFmt		(depthStencilFmt)
    917 		, m_invalidateBuffers	(invalidateBuffers)
    918 	{
    919 		DE_ASSERT((m_invalidateBuffers & (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)) != (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT));
    920 	}
    921 
    922 protected:
    923 	void preCheck (void)
    924 	{
    925 		if (m_colorFmt != GL_NONE)			checkFormatSupport(m_colorFmt);
    926 		if (m_depthStencilFmt != GL_NONE)	checkFormatSupport(m_depthStencilFmt);
    927 	}
    928 
    929 	void render (tcu::Surface& dst)
    930 	{
    931 		tcu::TextureFormat		colorFmt				= glu::mapGLInternalFormat(m_colorFmt);
    932 		tcu::TextureFormat		depthStencilFmt			= m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
    933 		tcu::TextureFormatInfo	colorFmtInfo			= tcu::getTextureFormatInfo(colorFmt);
    934 		bool					depth					= depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
    935 		bool					stencil					= depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
    936 		deUint32				fbo						= 0;
    937 		deUint32				colorTex				= 0;
    938 		deUint32				depthStencilTex			= 0;
    939 		int						invalidateX				= 0;
    940 		int						invalidateY				= 0;
    941 		int						invalidateW				= getWidth()/2;
    942 		int						invalidateH				= getHeight();
    943 		int						readX					= invalidateW;
    944 		int						readY					= 0;
    945 		int						readW					= getWidth()/2;
    946 		int						readH					= getHeight();
    947 		GradientShader			gradShader				(getFragmentOutputType(colorFmt));
    948 		vector<deUint32>		attachments				= getFBODiscardAttachments(m_invalidateBuffers);
    949 		deUint32				gradShaderID			= getCurrentContext()->createProgram(&gradShader);
    950 
    951 		// Create fbo.
    952 		{
    953 			glu::TransferFormat transferFmt = glu::getTransferFormat(colorFmt);
    954 
    955 			glGenTextures	(1, &colorTex);
    956 			glBindTexture	(GL_TEXTURE_2D, colorTex);
    957 			glTexImage2D	(GL_TEXTURE_2D, 0, m_colorFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
    958 			glTexParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    959 			glTexParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    960 		}
    961 
    962 		if (m_depthStencilFmt != GL_NONE)
    963 		{
    964 			glu::TransferFormat transferFmt = glu::getTransferFormat(depthStencilFmt);
    965 
    966 			glGenTextures	(1, &depthStencilTex);
    967 			glBindTexture	(GL_TEXTURE_2D, depthStencilTex);
    968 			glTexImage2D	(GL_TEXTURE_2D, 0, m_depthStencilFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL);
    969 			glTexParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    970 			glTexParameteri	(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    971 		}
    972 
    973 		glGenFramebuffers		(1, &fbo);
    974 		glBindFramebuffer		(GL_FRAMEBUFFER, fbo);
    975 		glFramebufferTexture2D	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
    976 
    977 		if (depth)
    978 			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0);
    979 
    980 		if (stencil)
    981 			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0);
    982 
    983 		checkFramebufferStatus		(GL_FRAMEBUFFER);
    984 
    985 		clearColorBuffer(colorFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
    986 		glClear			(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    987 
    988 		glEnable		(GL_DEPTH_TEST);
    989 		glEnable		(GL_STENCIL_TEST);
    990 		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
    991 		glStencilFunc	(GL_ALWAYS, 1, 0xff);
    992 
    993 		gradShader.setGradient(*getCurrentContext(), gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
    994 		sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
    995 
    996 		glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH);
    997 
    998 		glBindFramebuffer	(GL_FRAMEBUFFER, 0);
    999 		glDisable			(GL_DEPTH_TEST);
   1000 		glDisable			(GL_STENCIL_TEST);
   1001 
   1002 		glClearColor		(0.25f, 0.5f, 0.75f, 1.0f);
   1003 		glClear				(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
   1004 
   1005 		// Limit read area using scissor.
   1006 		glScissor			(readX, readY, readW, readH);
   1007 		glEnable			(GL_SCISSOR_TEST);
   1008 
   1009 		if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0)
   1010 		{
   1011 			// Render color.
   1012 			Texture2DShader texShader(DataTypes() << glu::getSampler2DType(colorFmt), glu::TYPE_FLOAT_VEC4);
   1013 			deUint32		texShaderID = getCurrentContext()->createProgram(&texShader);
   1014 
   1015 			texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
   1016 			texShader.setUniforms(*getCurrentContext(), texShaderID);
   1017 
   1018 			glBindTexture(GL_TEXTURE_2D, colorTex);
   1019 			sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
   1020 		}
   1021 		else
   1022 		{
   1023 			// Render depth.
   1024 			Texture2DShader texShader(DataTypes() << glu::getSampler2DType(depthStencilFmt), glu::TYPE_FLOAT_VEC4);
   1025 			deUint32		texShaderID = getCurrentContext()->createProgram(&texShader);
   1026 
   1027 			texShader.setUniforms(*getCurrentContext(), texShaderID);
   1028 
   1029 			glBindTexture(GL_TEXTURE_2D, depthStencilTex);
   1030 			sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
   1031 		}
   1032 
   1033 		readPixels(dst, 0, 0, getWidth(), getHeight());
   1034 	}
   1035 
   1036 	bool compare (const tcu::Surface& reference, const tcu::Surface& result)
   1037 	{
   1038 		const tcu::RGBA threshold (tcu::max(getFormatThreshold(m_colorFmt), tcu::RGBA(12, 12, 12, 12)));
   1039 
   1040 		return tcu::bilinearCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference.getAccess(), result.getAccess(), threshold, tcu::COMPARE_LOG_RESULT);
   1041 	}
   1042 
   1043 private:
   1044 	deUint32	m_colorFmt;
   1045 	deUint32	m_depthStencilFmt;
   1046 	deUint32	m_invalidateBuffers;
   1047 };
   1048 
   1049 class InvalidateSubFboUnbindBlitCase : public FboTestCase
   1050 {
   1051 public:
   1052 	InvalidateSubFboUnbindBlitCase (Context& context, const char* name, const char* description, int numSamples, deUint32 invalidateBuffers)
   1053 		: FboTestCase			(context, name, description, numSamples > 0)	// \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its
   1054 																				//		 behing-the-scenes viewport position randomization, because with glBlitFramebuffer,
   1055 																				//		 source and destination rectangles must match when multisampling.
   1056 		, m_colorFmt			(0)
   1057 		, m_depthStencilFmt		(0)
   1058 		, m_numSamples			(numSamples)
   1059 		, m_invalidateBuffers	(invalidateBuffers)
   1060 	{
   1061 		// Figure out formats that are compatible with default framebuffer.
   1062 		m_colorFmt			= getCompatibleColorFormat(m_context.getRenderTarget());
   1063 		m_depthStencilFmt	= getCompatibleDepthStencilFormat(m_context.getRenderTarget());
   1064 	}
   1065 
   1066 protected:
   1067 	void preCheck (void)
   1068 	{
   1069 		if (m_context.getRenderTarget().getNumSamples() > 0)
   1070 			throw tcu::NotSupportedError("Not supported in MSAA config");
   1071 
   1072 		if (m_colorFmt == GL_NONE)
   1073 			throw tcu::NotSupportedError("Unsupported color format");
   1074 
   1075 		if (m_depthStencilFmt == GL_NONE)
   1076 			throw tcu::NotSupportedError("Unsupported depth/stencil format");
   1077 
   1078 		checkFormatSupport(m_colorFmt);
   1079 		checkFormatSupport(m_depthStencilFmt);
   1080 	}
   1081 
   1082 	void render (tcu::Surface& dst)
   1083 	{
   1084 		// \note When using fullscreen viewport (when m_numSamples > 0), still only use a 128x128 pixel quad at most.
   1085 		IVec2					quadSizePixels			(m_numSamples == 0 ? getWidth() : de::min(128, getWidth()),
   1086 														 m_numSamples == 0 ? getHeight() : de::min(128, getHeight()));
   1087 		Vec2					quadNDCLeftBottomXY		(-1.0f, -1.0f);
   1088 		Vec2					quadNDCSize				(2.0f*quadSizePixels.x()/getWidth(), 2.0f*quadSizePixels.y()/getHeight());
   1089 		Vec2					quadNDCRightTopXY		= quadNDCLeftBottomXY + quadNDCSize;
   1090 		tcu::TextureFormat		depthStencilFmt			= m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat();
   1091 		bool					depth					= depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS;
   1092 		bool					stencil					= depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS;
   1093 		deUint32				fbo						= 0;
   1094 		deUint32				colorRbo				= 0;
   1095 		deUint32				depthStencilRbo			= 0;
   1096 		int						invalidateX				= 0;
   1097 		int						invalidateY				= 0;
   1098 		int						invalidateW				= quadSizePixels.x()/2;
   1099 		int						invalidateH				= quadSizePixels.y();
   1100 		int						blitX0					= invalidateW;
   1101 		int						blitY0					= 0;
   1102 		int						blitX1					= blitX0 + quadSizePixels.x()/2;
   1103 		int						blitY1					= blitY0 + quadSizePixels.y();
   1104 		FlatColorShader			flatShader				(glu::TYPE_FLOAT_VEC4);
   1105 		vector<deUint32>		attachments				= getFBODiscardAttachments(m_invalidateBuffers);
   1106 		deUint32				flatShaderID			= getCurrentContext()->createProgram(&flatShader);
   1107 
   1108 		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
   1109 		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
   1110 
   1111 		// Create fbo.
   1112 		glGenRenderbuffers					(1, &colorRbo);
   1113 		glBindRenderbuffer					(GL_RENDERBUFFER, colorRbo);
   1114 		glRenderbufferStorageMultisample	(GL_RENDERBUFFER, m_numSamples, m_colorFmt, quadSizePixels.x(), quadSizePixels.y());
   1115 
   1116 		if (m_depthStencilFmt != GL_NONE)
   1117 		{
   1118 			glGenRenderbuffers					(1, &depthStencilRbo);
   1119 			glBindRenderbuffer					(GL_RENDERBUFFER, depthStencilRbo);
   1120 			glRenderbufferStorageMultisample	(GL_RENDERBUFFER, m_numSamples, m_depthStencilFmt, quadSizePixels.x(), quadSizePixels.y());
   1121 		}
   1122 
   1123 		glGenFramebuffers			(1, &fbo);
   1124 		glBindFramebuffer			(GL_FRAMEBUFFER, fbo);
   1125 		glFramebufferRenderbuffer	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
   1126 
   1127 		if (depth)
   1128 			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
   1129 
   1130 		if (stencil)
   1131 			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
   1132 
   1133 		checkFramebufferStatus		(GL_FRAMEBUFFER);
   1134 
   1135 		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
   1136 
   1137 		glEnable		(GL_DEPTH_TEST);
   1138 		glEnable		(GL_STENCIL_TEST);
   1139 		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
   1140 		glStencilFunc	(GL_ALWAYS, 1, 0xff);
   1141 
   1142 		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
   1143 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), -1.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 1.0f));
   1144 
   1145 		glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH);
   1146 
   1147 		// Set default framebuffer as draw framebuffer and blit preserved buffers.
   1148 		glBindFramebuffer	(GL_DRAW_FRAMEBUFFER, 0);
   1149 		glBlitFramebuffer	(blitX0, blitY0, blitX1, blitY1, blitX0, blitY0, blitX1, blitY1, (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) & ~m_invalidateBuffers, GL_NEAREST);
   1150 		glBindFramebuffer	(GL_READ_FRAMEBUFFER, 0);
   1151 
   1152 		if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0)
   1153 		{
   1154 			// Color was not preserved - fill with green.
   1155 			glDisable(GL_DEPTH_TEST);
   1156 			glDisable(GL_STENCIL_TEST);
   1157 
   1158 			flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
   1159 			sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f));
   1160 
   1161 			glEnable(GL_DEPTH_TEST);
   1162 			glEnable(GL_STENCIL_TEST);
   1163 		}
   1164 
   1165 		if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0)
   1166 		{
   1167 			// Depth was not preserved.
   1168 			glDepthFunc(GL_ALWAYS);
   1169 		}
   1170 
   1171 		if ((m_invalidateBuffers & GL_STENCIL_BUFFER_BIT) == 0)
   1172 		{
   1173 			// Stencil was preserved.
   1174 			glStencilFunc(GL_EQUAL, 1, 0xff);
   1175 		}
   1176 
   1177 		glEnable		(GL_BLEND);
   1178 		glBlendFunc		(GL_ONE, GL_ONE);
   1179 		glBlendEquation	(GL_FUNC_ADD);
   1180 
   1181 		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f));
   1182 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f));
   1183 
   1184 		readPixels(dst, 0, 0, quadSizePixels.x(), quadSizePixels.y());
   1185 	}
   1186 
   1187 private:
   1188 	deUint32	m_colorFmt;
   1189 	deUint32	m_depthStencilFmt;
   1190 	int			m_numSamples;
   1191 	deUint32	m_invalidateBuffers;
   1192 };
   1193 
   1194 class InvalidateFboTargetCase : public FboTestCase
   1195 {
   1196 public:
   1197 	InvalidateFboTargetCase (Context& context, const char* name, const char* description, deUint32 boundTarget, deUint32 invalidateTarget, const deUint32* invalidateAttachments, int numAttachments)
   1198 		: FboTestCase				(context, name, description)
   1199 		, m_boundTarget				(boundTarget)
   1200 		, m_invalidateTarget		(invalidateTarget)
   1201 		, m_invalidateAttachments	(invalidateAttachments, invalidateAttachments+numAttachments)
   1202 	{
   1203 	}
   1204 
   1205 protected:
   1206 	void render (tcu::Surface& dst)
   1207 	{
   1208 		const deUint32					colorFormat				= GL_RGBA8;
   1209 		const deUint32					depthStencilFormat		= GL_DEPTH24_STENCIL8;
   1210 		const tcu::TextureFormat		colorFmt				= glu::mapGLInternalFormat(colorFormat);
   1211 		const tcu::TextureFormatInfo	colorFmtInfo			= tcu::getTextureFormatInfo(colorFmt);
   1212 		const tcu::Vec4&				cBias					= colorFmtInfo.valueMin;
   1213 		const tcu::Vec4					cScale					= colorFmtInfo.valueMax-colorFmtInfo.valueMin;
   1214 		const bool						isDiscarded				= (m_boundTarget == GL_FRAMEBUFFER) ||
   1215 																  (m_invalidateTarget == GL_FRAMEBUFFER && m_boundTarget == GL_DRAW_FRAMEBUFFER) ||
   1216 																  (m_invalidateTarget == m_boundTarget);
   1217 		const bool						isColorDiscarded		= isDiscarded && hasAttachment(m_invalidateAttachments, GL_COLOR_ATTACHMENT0);
   1218 		const bool						isDepthDiscarded		= isDiscarded && (hasAttachment(m_invalidateAttachments, GL_DEPTH_ATTACHMENT) || hasAttachment(m_invalidateAttachments, GL_DEPTH_STENCIL_ATTACHMENT));
   1219 		const bool						isStencilDiscarded		= isDiscarded && (hasAttachment(m_invalidateAttachments, GL_STENCIL_ATTACHMENT) || hasAttachment(m_invalidateAttachments, GL_DEPTH_STENCIL_ATTACHMENT));
   1220 
   1221 		deUint32						fbo						= 0;
   1222 		deUint32						colorRbo				= 0;
   1223 		deUint32						depthStencilRbo			= 0;
   1224 		FlatColorShader					flatShader				(glu::TYPE_FLOAT_VEC4);
   1225 		deUint32						flatShaderID			= getCurrentContext()->createProgram(&flatShader);
   1226 
   1227 		// Create fbo.
   1228 		glGenRenderbuffers		(1, &colorRbo);
   1229 		glBindRenderbuffer		(GL_RENDERBUFFER, colorRbo);
   1230 		glRenderbufferStorage	(GL_RENDERBUFFER, colorFormat, getWidth(), getHeight());
   1231 
   1232 		glGenRenderbuffers		(1, &depthStencilRbo);
   1233 		glBindRenderbuffer		(GL_RENDERBUFFER, depthStencilRbo);
   1234 		glRenderbufferStorage	(GL_RENDERBUFFER, depthStencilFormat, getWidth(), getHeight());
   1235 
   1236 		glGenFramebuffers			(1, &fbo);
   1237 		glBindFramebuffer			(GL_FRAMEBUFFER, fbo);
   1238 		glFramebufferRenderbuffer	(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
   1239 		glFramebufferRenderbuffer	(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
   1240 		glFramebufferRenderbuffer	(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
   1241 
   1242 		checkFramebufferStatus		(GL_FRAMEBUFFER);
   1243 
   1244 		glClearColor	(0.0f, 0.0f, 0.0f, 1.0f);
   1245 		glClear			(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
   1246 
   1247 		glEnable		(GL_DEPTH_TEST);
   1248 		glEnable		(GL_STENCIL_TEST);
   1249 		glStencilOp		(GL_KEEP, GL_KEEP, GL_REPLACE);
   1250 		glStencilFunc	(GL_ALWAYS, 1, 0xff);
   1251 
   1252 		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias);
   1253 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f));
   1254 
   1255 		// Bound FBO to test target and default to other
   1256 		if (m_boundTarget != GL_FRAMEBUFFER)
   1257 		{
   1258 			// Dummy fbo is used as complemeting target (read when discarding draw for example).
   1259 			// \note Framework takes care of deleting objects at the end of test case.
   1260 			const deUint32	dummyTarget		= m_boundTarget == GL_DRAW_FRAMEBUFFER ?  GL_READ_FRAMEBUFFER : GL_DRAW_FRAMEBUFFER;
   1261 			deUint32		dummyFbo		= 0;
   1262 			deUint32		dummyColorRbo	= 0;
   1263 
   1264 			glGenRenderbuffers			(1, &dummyColorRbo);
   1265 			glBindRenderbuffer			(GL_RENDERBUFFER, dummyColorRbo);
   1266 			glRenderbufferStorage		(GL_RENDERBUFFER, GL_RGBA8, 64, 64);
   1267 			glGenFramebuffers			(1, &dummyFbo);
   1268 			glBindFramebuffer			(dummyTarget, dummyFbo);
   1269 			glFramebufferRenderbuffer	(dummyTarget, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, dummyColorRbo);
   1270 
   1271 			glBindFramebuffer			(m_boundTarget, fbo);
   1272 		}
   1273 
   1274 		glInvalidateFramebuffer(m_invalidateTarget, (int)m_invalidateAttachments.size(), m_invalidateAttachments.empty() ? DE_NULL : &m_invalidateAttachments[0]);
   1275 
   1276 		if (m_boundTarget != GL_FRAMEBUFFER)
   1277 			glBindFramebuffer(GL_FRAMEBUFFER, fbo);
   1278 
   1279 		if (isColorDiscarded)
   1280 		{
   1281 			// Color was not preserved - fill with green.
   1282 			glDisable(GL_DEPTH_TEST);
   1283 			glDisable(GL_STENCIL_TEST);
   1284 
   1285 			flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias);
   1286 			sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
   1287 
   1288 			glEnable(GL_DEPTH_TEST);
   1289 			glEnable(GL_STENCIL_TEST);
   1290 		}
   1291 
   1292 		if (isDepthDiscarded)
   1293 		{
   1294 			// Depth was not preserved.
   1295 			glDepthFunc(GL_ALWAYS);
   1296 		}
   1297 
   1298 		if (!isStencilDiscarded)
   1299 		{
   1300 			// Stencil was preserved.
   1301 			glStencilFunc(GL_EQUAL, 1, 0xff);
   1302 		}
   1303 
   1304 		glEnable		(GL_BLEND);
   1305 		glBlendFunc		(GL_ONE, GL_ONE);
   1306 		glBlendEquation	(GL_FUNC_ADD);
   1307 
   1308 		flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)*cScale + cBias);
   1309 		sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
   1310 
   1311 		readPixels(dst, 0, 0, getWidth(), getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
   1312 	}
   1313 
   1314 private:
   1315 	deUint32				m_boundTarget;
   1316 	deUint32				m_invalidateTarget;
   1317 	std::vector<deUint32>	m_invalidateAttachments;
   1318 };
   1319 
   1320 FboInvalidateTests::FboInvalidateTests (Context& context)
   1321 	: TestCaseGroup(context, "invalidate", "Framebuffer invalidate tests")
   1322 {
   1323 }
   1324 
   1325 FboInvalidateTests::~FboInvalidateTests (void)
   1326 {
   1327 }
   1328 
   1329 void FboInvalidateTests::init (void)
   1330 {
   1331 	// invalidate.default.
   1332 	{
   1333 		tcu::TestCaseGroup* defaultFbGroup = new tcu::TestCaseGroup(m_testCtx, "default", "Default framebuffer invalidate tests");
   1334 		addChild(defaultFbGroup);
   1335 
   1336 		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"render_none",				"Invalidating no framebuffers (ref)",						0));
   1337 		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"render_color",				"Rendering after invalidating colorbuffer",					GL_COLOR_BUFFER_BIT));
   1338 		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"render_depth",				"Rendering after invalidating depthbuffer",					GL_DEPTH_BUFFER_BIT));
   1339 		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"render_stencil",			"Rendering after invalidating stencilbuffer",				GL_STENCIL_BUFFER_BIT));
   1340 		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"render_depth_stencil",		"Rendering after invalidating depth- and stencilbuffers",	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1341 		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"render_all",				"Rendering after invalidating all buffers",					GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1342 
   1343 		defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase		(m_context,	"bind_color",				"Binding fbo after invalidating colorbuffer",				GL_COLOR_BUFFER_BIT));
   1344 		defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase		(m_context,	"bind_depth",				"Binding fbo after invalidating depthbuffer",				GL_DEPTH_BUFFER_BIT));
   1345 		defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase		(m_context,	"bind_stencil",				"Binding fbo after invalidating stencilbuffer",				GL_STENCIL_BUFFER_BIT));
   1346 		defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase		(m_context,	"bind_depth_stencil",		"Binding fbo after invalidating depth- and stencilbuffers",	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1347 		defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase		(m_context,	"bind_all",					"Binding fbo after invalidating all buffers",				GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1348 
   1349 		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase	(m_context,	"sub_render_color",			"Rendering after invalidating colorbuffer",					GL_COLOR_BUFFER_BIT));
   1350 		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase	(m_context,	"sub_render_depth",			"Rendering after invalidating depthbuffer",					GL_DEPTH_BUFFER_BIT));
   1351 		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase	(m_context,	"sub_render_stencil",		"Rendering after invalidating stencilbuffer",				GL_STENCIL_BUFFER_BIT));
   1352 		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase	(m_context,	"sub_render_depth_stencil",	"Rendering after invalidating depth- and stencilbuffers",	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1353 		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase	(m_context,	"sub_render_all",			"Rendering after invalidating all buffers",					GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1354 
   1355 		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase	(m_context,	"sub_bind_color",			"Binding fbo after invalidating colorbuffer",				GL_COLOR_BUFFER_BIT));
   1356 		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase	(m_context,	"sub_bind_depth",			"Binding fbo after invalidating depthbuffer",				GL_DEPTH_BUFFER_BIT));
   1357 		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase	(m_context,	"sub_bind_stencil",			"Binding fbo after invalidating stencilbuffer",				GL_STENCIL_BUFFER_BIT));
   1358 		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase	(m_context,	"sub_bind_depth_stencil",	"Binding fbo after invalidating depth- and stencilbuffers",	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1359 		defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase	(m_context,	"sub_bind_all",				"Binding fbo after invalidating all buffers",				GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1360 
   1361 		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"draw_framebuffer_color",	"Invalidating GL_COLOR in GL_DRAW_FRAMEBUFFER",				GL_COLOR_BUFFER_BIT,											GL_DRAW_FRAMEBUFFER));
   1362 		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"draw_framebuffer_all",		"Invalidating all in GL_DRAW_FRAMEBUFFER",					GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT,	GL_DRAW_FRAMEBUFFER));
   1363 		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"read_framebuffer_color",	"Invalidating GL_COLOR in GL_READ_FRAMEBUFFER",				GL_COLOR_BUFFER_BIT,											GL_READ_FRAMEBUFFER));
   1364 		defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase		(m_context,	"read_framebuffer_all",		"Invalidating all in GL_READ_FRAMEBUFFER",					GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT,	GL_READ_FRAMEBUFFER));
   1365 	}
   1366 
   1367 	// invalidate.whole.
   1368 	{
   1369 		tcu::TestCaseGroup* wholeFboGroup = new tcu::TestCaseGroup(m_testCtx, "whole", "Invalidating whole framebuffer object");
   1370 		addChild(wholeFboGroup);
   1371 
   1372 		wholeFboGroup->addChild(new InvalidateFboRenderCase		(m_context, "render_none",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	0));
   1373 		wholeFboGroup->addChild(new InvalidateFboRenderCase		(m_context, "render_color",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT));
   1374 		wholeFboGroup->addChild(new InvalidateFboRenderCase		(m_context, "render_depth",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT));
   1375 		wholeFboGroup->addChild(new InvalidateFboRenderCase		(m_context, "render_stencil",					"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_STENCIL_BUFFER_BIT));
   1376 		wholeFboGroup->addChild(new InvalidateFboRenderCase		(m_context, "render_depth_stencil",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1377 		wholeFboGroup->addChild(new InvalidateFboRenderCase		(m_context, "render_all",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1378 
   1379 		wholeFboGroup->addChild(new InvalidateFboUnbindReadCase	(m_context, "unbind_read_color",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT));
   1380 		wholeFboGroup->addChild(new InvalidateFboUnbindReadCase	(m_context, "unbind_read_depth",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT));
   1381 		wholeFboGroup->addChild(new InvalidateFboUnbindReadCase	(m_context, "unbind_read_stencil",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_STENCIL_BUFFER_BIT));
   1382 		wholeFboGroup->addChild(new InvalidateFboUnbindReadCase	(m_context, "unbind_read_depth_stencil",		"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1383 		wholeFboGroup->addChild(new InvalidateFboUnbindReadCase	(m_context, "unbind_read_color_stencil",		"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1384 
   1385 		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_color",				"",		0,	GL_COLOR_BUFFER_BIT));
   1386 		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_depth",				"",		0,	GL_DEPTH_BUFFER_BIT));
   1387 		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_stencil",				"",		0,	GL_STENCIL_BUFFER_BIT));
   1388 		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_depth_stencil",		"",		0,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1389 
   1390 		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_msaa_color",			"",		4,	GL_COLOR_BUFFER_BIT));
   1391 		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_msaa_depth",			"",		4,	GL_DEPTH_BUFFER_BIT));
   1392 		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_msaa_stencil",			"",		4,	GL_STENCIL_BUFFER_BIT));
   1393 		wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase	(m_context, "unbind_blit_msaa_depth_stencil",	"",		4,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1394 	}
   1395 
   1396 	// invalidate.sub.
   1397 	{
   1398 		tcu::TestCaseGroup* subFboGroup = new tcu::TestCaseGroup(m_testCtx, "sub", "Invalidating subsection of framebuffer object");
   1399 		addChild(subFboGroup);
   1400 
   1401 		subFboGroup->addChild(new InvalidateSubFboRenderCase	(m_context, "render_none",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	0));
   1402 		subFboGroup->addChild(new InvalidateSubFboRenderCase	(m_context, "render_color",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT));
   1403 		subFboGroup->addChild(new InvalidateSubFboRenderCase	(m_context, "render_depth",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT));
   1404 		subFboGroup->addChild(new InvalidateSubFboRenderCase	(m_context, "render_stencil",					"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_STENCIL_BUFFER_BIT));
   1405 		subFboGroup->addChild(new InvalidateSubFboRenderCase	(m_context, "render_depth_stencil",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1406 		subFboGroup->addChild(new InvalidateSubFboRenderCase	(m_context, "render_all",						"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1407 
   1408 		subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_color",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT));
   1409 		subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_depth",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT));
   1410 		subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_stencil",				"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_STENCIL_BUFFER_BIT));
   1411 		subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_depth_stencil",		"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1412 		subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_color_stencil",		"",		GL_RGBA8,		GL_DEPTH24_STENCIL8,	GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1413 
   1414 		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_color",				"",		0,	GL_COLOR_BUFFER_BIT));
   1415 		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_depth",				"",		0,	GL_DEPTH_BUFFER_BIT));
   1416 		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_stencil",				"",		0,	GL_STENCIL_BUFFER_BIT));
   1417 		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_depth_stencil",		"",		0,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1418 
   1419 		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_color",			"",		4,	GL_COLOR_BUFFER_BIT));
   1420 		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_depth",			"",		4,	GL_DEPTH_BUFFER_BIT));
   1421 		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_stencil",			"",		4,	GL_STENCIL_BUFFER_BIT));
   1422 		subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_depth_stencil",	"",		4,	GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1423 	}
   1424 
   1425 	// invalidate.format.
   1426 	{
   1427 		tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "Invalidating framebuffers with selected formats");
   1428 		addChild(formatGroup);
   1429 
   1430 		// Color buffer formats.
   1431 		static const deUint32 colorFormats[] =
   1432 		{
   1433 			// RGBA formats
   1434 			GL_RGBA32I,
   1435 			GL_RGBA32UI,
   1436 			GL_RGBA16I,
   1437 			GL_RGBA16UI,
   1438 			GL_RGBA8,
   1439 			GL_RGBA8I,
   1440 			GL_RGBA8UI,
   1441 			GL_SRGB8_ALPHA8,
   1442 			GL_RGB10_A2,
   1443 			GL_RGB10_A2UI,
   1444 			GL_RGBA4,
   1445 			GL_RGB5_A1,
   1446 
   1447 			// RGB formats
   1448 			GL_RGB8,
   1449 			GL_RGB565,
   1450 
   1451 			// RG formats
   1452 			GL_RG32I,
   1453 			GL_RG32UI,
   1454 			GL_RG16I,
   1455 			GL_RG16UI,
   1456 			GL_RG8,
   1457 			GL_RG8I,
   1458 			GL_RG8UI,
   1459 
   1460 			// R formats
   1461 			GL_R32I,
   1462 			GL_R32UI,
   1463 			GL_R16I,
   1464 			GL_R16UI,
   1465 			GL_R8,
   1466 			GL_R8I,
   1467 			GL_R8UI,
   1468 
   1469 			// GL_EXT_color_buffer_float
   1470 			GL_RGBA32F,
   1471 			GL_RGBA16F,
   1472 			GL_R11F_G11F_B10F,
   1473 			GL_RG32F,
   1474 			GL_RG16F,
   1475 			GL_R32F,
   1476 			GL_R16F
   1477 		};
   1478 
   1479 		// Depth/stencilbuffer formats.
   1480 		static const deUint32 depthStencilFormats[] =
   1481 		{
   1482 			GL_DEPTH_COMPONENT32F,
   1483 			GL_DEPTH_COMPONENT24,
   1484 			GL_DEPTH_COMPONENT16,
   1485 			GL_DEPTH32F_STENCIL8,
   1486 			GL_DEPTH24_STENCIL8,
   1487 			GL_STENCIL_INDEX8
   1488 		};
   1489 
   1490 		// Colorbuffer tests use invalidate, unbind, read test.
   1491 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
   1492 			formatGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, getFormatName(colorFormats[ndx]), "", colorFormats[ndx], GL_NONE, GL_COLOR_BUFFER_BIT));
   1493 
   1494 		// Depth/stencilbuffer tests use invalidate, render test.
   1495 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
   1496 			formatGroup->addChild(new InvalidateSubFboRenderCase(m_context, getFormatName(depthStencilFormats[ndx]), "", GL_RGBA8, depthStencilFormats[ndx], GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT));
   1497 	}
   1498 
   1499 	// invalidate.target
   1500 	{
   1501 		tcu::TestCaseGroup* targetGroup = new tcu::TestCaseGroup(m_testCtx, "target", "Invalidate target");
   1502 		addChild(targetGroup);
   1503 
   1504 		static const struct
   1505 		{
   1506 			const char*		name;
   1507 			deUint32		invalidateTarget;
   1508 			deUint32		boundTarget;
   1509 		} s_targetCases[] =
   1510 		{
   1511 			{ "framebuffer_framebuffer",			GL_FRAMEBUFFER,			GL_FRAMEBUFFER		},
   1512 			{ "framebuffer_read_framebuffer",		GL_FRAMEBUFFER,			GL_READ_FRAMEBUFFER },
   1513 			{ "framebuffer_draw_framebuffer",		GL_FRAMEBUFFER,			GL_DRAW_FRAMEBUFFER },
   1514 			{ "read_framebuffer_framebuffer",		GL_READ_FRAMEBUFFER,	GL_FRAMEBUFFER		},
   1515 			{ "read_framebuffer_read_framebuffer",	GL_READ_FRAMEBUFFER,	GL_READ_FRAMEBUFFER },
   1516 			{ "read_framebuffer_draw_framebuffer",	GL_READ_FRAMEBUFFER,	GL_DRAW_FRAMEBUFFER },
   1517 			{ "draw_framebuffer_framebuffer",		GL_DRAW_FRAMEBUFFER,	GL_FRAMEBUFFER		},
   1518 			{ "draw_framebuffer_read_framebuffer",	GL_DRAW_FRAMEBUFFER,	GL_READ_FRAMEBUFFER },
   1519 			{ "draw_framebuffer_draw_framebuffer",	GL_DRAW_FRAMEBUFFER,	GL_DRAW_FRAMEBUFFER },
   1520 		};
   1521 
   1522 		static const deUint32 colorAttachment[]			= { GL_COLOR_ATTACHMENT0 };
   1523 		static const deUint32 depthStencilAttachment[]	= { GL_DEPTH_STENCIL_ATTACHMENT };
   1524 		static const deUint32 allAttachments[]			= { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT };
   1525 
   1526 		for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_targetCases); caseNdx++)
   1527 		{
   1528 			const std::string	baseName		= s_targetCases[caseNdx].name;
   1529 			const deUint32		invalidateT		= s_targetCases[caseNdx].invalidateTarget;
   1530 			const deUint32		boundT			= s_targetCases[caseNdx].boundTarget;
   1531 
   1532 			targetGroup->addChild(new InvalidateFboTargetCase(m_context, (baseName + "_color").c_str(),			"",	boundT, invalidateT, &colorAttachment[0],			DE_LENGTH_OF_ARRAY(colorAttachment)));
   1533 			targetGroup->addChild(new InvalidateFboTargetCase(m_context, (baseName + "_depth_stencil").c_str(),	"",	boundT, invalidateT, &depthStencilAttachment[0],	DE_LENGTH_OF_ARRAY(depthStencilAttachment)));
   1534 			targetGroup->addChild(new InvalidateFboTargetCase(m_context, (baseName + "_all").c_str(),			"",	boundT, invalidateT, &allAttachments[0],			DE_LENGTH_OF_ARRAY(allAttachments)));
   1535 		}
   1536 	}
   1537 }
   1538 
   1539 } // Functional
   1540 } // gles3
   1541 } // deqp
   1542