13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES Utilities
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief OpenGL ES context wrapper that uses FBO as default framebuffer.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluFboRenderContext.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluContextFactory.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderConfig.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCommandLine.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTextureUtil.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream>
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace glu
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
385d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulosstatic int getNumDepthBits (const tcu::TextureFormat& format)
395d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos{
405d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos	if (format.order == tcu::TextureFormat::DS)
415d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos	{
425d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos		const tcu::TextureFormat	depthOnlyFormat		= tcu::getEffectiveDepthStencilTextureFormat(format, tcu::Sampler::MODE_DEPTH);
435d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos		return tcu::getTextureFormatBitDepth(depthOnlyFormat).x();
445d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos	}
455d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos	else if (format.order == tcu::TextureFormat::D)
465d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos		return tcu::getTextureFormatBitDepth(format).x();
475d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos	else
485d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos		return 0;
495d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos}
505d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos
515d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulosstatic int getNumStencilBits (const tcu::TextureFormat& format)
525d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos{
535d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos	if (format.order == tcu::TextureFormat::DS)
545d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos	{
555d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos		const tcu::TextureFormat	stencilOnlyFormat		= tcu::getEffectiveDepthStencilTextureFormat(format, tcu::Sampler::MODE_STENCIL);
565d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos		return tcu::getTextureFormatBitDepth(stencilOnlyFormat).x();
575d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos	}
585d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos	else if (format.order == tcu::TextureFormat::S)
595d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos		return tcu::getTextureFormatBitDepth(format).x();
605d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos	else
615d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos		return 0;
625d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos}
635d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic tcu::PixelFormat getPixelFormat (deUint32 colorFormat)
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::IVec4 bits = tcu::getTextureFormatBitDepth(glu::mapGLInternalFormat(colorFormat));
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::PixelFormat(bits[0], bits[1], bits[2], bits[3]);
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void getDepthStencilBits (deUint32 depthStencilFormat, int* depthBits, int* stencilBits)
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
725d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos	const tcu::TextureFormat	combinedFormat	= glu::mapGLInternalFormat(depthStencilFormat);
735d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos
745d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos	*depthBits		= getNumDepthBits(combinedFormat);
755d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos	*stencilBits	= getNumStencilBits(combinedFormat);
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
783c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 chooseColorFormat (const glu::RenderConfig& config)
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 s_formats[] =
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_RGBA8,
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_RGB8,
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_RG8,
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_R8,
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_RGBA4,
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_RGB5_A1,
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_RGB565,
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_RGB5
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(s_formats); fmtNdx++)
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const deUint32		format	= s_formats[fmtNdx];
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::IVec4	bits	= tcu::getTextureFormatBitDepth(glu::mapGLInternalFormat(format));
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (config.redBits != glu::RenderConfig::DONT_CARE &&
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			config.redBits != bits[0])
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (config.greenBits != glu::RenderConfig::DONT_CARE &&
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			config.greenBits != bits[1])
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (config.blueBits != glu::RenderConfig::DONT_CARE &&
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			config.blueBits != bits[2])
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (config.alphaBits != glu::RenderConfig::DONT_CARE &&
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			config.alphaBits != bits[3])
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return format;
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return 0;
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1193c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 chooseDepthStencilFormat (const glu::RenderConfig& config)
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 s_formats[] =
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_DEPTH32F_STENCIL8,
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_DEPTH24_STENCIL8,
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_DEPTH_COMPONENT32F,
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_DEPTH_COMPONENT24,
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_DEPTH_COMPONENT16,
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_STENCIL_INDEX8
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(s_formats); fmtNdx++)
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1335d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos		const deUint32				format			= s_formats[fmtNdx];
1345d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos		const tcu::TextureFormat	combinedFormat	= glu::mapGLInternalFormat(format);
1355d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos		const int					depthBits		= getNumDepthBits(combinedFormat);
1365d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos		const int					stencilBits		= getNumStencilBits(combinedFormat);
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (config.depthBits != glu::RenderConfig::DONT_CARE &&
1395d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos			config.depthBits != depthBits)
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (config.stencilBits != glu::RenderConfig::DONT_CARE &&
1435d1cffaa20d05bef05c3d7bbb7f0068313d433f7Pyry Haulos			config.stencilBits != stencilBits)
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return format;
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return 0;
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1523c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFboRenderContext::FboRenderContext (RenderContext* context, const RenderConfig& config)
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_context				(context)
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_framebuffer			(0)
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_colorBuffer			(0)
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depthStencilBuffer	(0)
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderTarget		()
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		createFramebuffer(config);
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		destroyFramebuffer();
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFboRenderContext::FboRenderContext (const ContextFactory& factory, const RenderConfig& config, const tcu::CommandLine& cmdLine)
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_context				(DE_NULL)
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_framebuffer			(0)
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_colorBuffer			(0)
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depthStencilBuffer	(0)
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderTarget		()
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RenderConfig nativeRenderConfig;
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		nativeRenderConfig.type				= config.type;
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		nativeRenderConfig.windowVisibility	= config.windowVisibility;
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note All other properties are defaults, mostly DONT_CARE
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_context = factory.createContext(nativeRenderConfig, cmdLine);
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		createFramebuffer(config);
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (...)
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_context;
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1933c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFboRenderContext::~FboRenderContext (void)
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2013-04-08 pyry] Do we want to destry FBO before destroying context?
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_context;
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FboRenderContext::postIterate (void)
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2012-11-27 pyry] Blit to default framebuffer in ES3?
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_context->getFunctions().finish();
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FboRenderContext::createFramebuffer (const RenderConfig& config)
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_framebuffer == 0 && m_colorBuffer == 0 && m_depthStencilBuffer == 0);
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl					= m_context->getFunctions();
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			colorFormat			= chooseColorFormat(config);
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32			depthStencilFormat	= chooseDepthStencilFormat(config);
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						width				= config.width;
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						height				= config.height;
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::PixelFormat		pixelFormat;
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						depthBits			= 0;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						stencilBits			= 0;
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (config.numSamples > 0 && !gl.renderbufferStorageMultisample)
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Multisample FBO is not supported");
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (colorFormat == 0)
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Unsupported color attachment format");
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (width == glu::RenderConfig::DONT_CARE || height == glu::RenderConfig::DONT_CARE)
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int maxSize = 0;
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getIntegerv(GL_MAX_RENDERBUFFER_SIZE, &maxSize);
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		width	= (width	== glu::RenderConfig::DONT_CARE) ? maxSize : width;
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		height	= (height	== glu::RenderConfig::DONT_CARE) ? maxSize : height;
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		pixelFormat = getPixelFormat(colorFormat);
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genRenderbuffers(1, &m_colorBuffer);
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindRenderbuffer(GL_RENDERBUFFER, m_colorBuffer);
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (config.numSamples > 0)
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.renderbufferStorageMultisample(GL_RENDERBUFFER, config.numSamples, colorFormat, width, height);
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.renderbufferStorage(GL_RENDERBUFFER, colorFormat, width, height);
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Creating color renderbuffer");
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (depthStencilFormat != GL_NONE)
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		getDepthStencilBits(depthStencilFormat, &depthBits, &stencilBits);
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.genRenderbuffers(1, &m_depthStencilBuffer);
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer);
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (config.numSamples > 0)
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.renderbufferStorageMultisample(GL_RENDERBUFFER, config.numSamples, depthStencilFormat, width, height);
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.renderbufferStorage(GL_RENDERBUFFER, depthStencilFormat, width, height);
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLU_EXPECT_NO_ERROR(gl.getError(), "Creating depth / stencil renderbuffer");
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.genFramebuffers(1, &m_framebuffer);
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_colorBuffer)
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorBuffer);
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_depthStencilBuffer)
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (depthBits > 0)
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuffer);
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (stencilBits > 0)
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilBuffer);
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), "Creating framebuffer");
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("Framebuffer is not complete");
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Set up correct viewport for first test case.
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(0, 0, width, height);
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderTarget = tcu::RenderTarget(width, height, pixelFormat, depthBits, stencilBits, config.numSamples);
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid FboRenderContext::destroyFramebuffer (void)
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context->getFunctions();
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_framebuffer)
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.deleteFramebuffers(1, &m_framebuffer);
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_framebuffer = 0;
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_depthStencilBuffer)
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.deleteRenderbuffers(1, &m_depthStencilBuffer);
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_depthStencilBuffer = 0;
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_colorBuffer)
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.deleteRenderbuffers(1, &m_colorBuffer);
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_colorBuffer = 0;
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // glu
314