/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES Utilities
 * ------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Reference Rendering Context.
 *//*--------------------------------------------------------------------*/

#include "sglrReferenceContext.hpp"
#include "sglrReferenceUtils.hpp"
#include "sglrShaderProgram.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuMatrix.hpp"
#include "tcuMatrixUtil.hpp"
#include "tcuVectorUtil.hpp"
#include "gluDefs.hpp"
#include "gluTextureUtil.hpp"
#include "gluContextInfo.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"
#include "deMemory.h"
#include "rrFragmentOperations.hpp"
#include "rrRenderer.hpp"

#include <cstdint>

namespace sglr
{

using std::vector;
using std::map;

using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;
using tcu::IVec2;
using tcu::IVec4;
using tcu::RGBA;

// Reference context implementation
using namespace rc;

using tcu::TextureFormat;
using tcu::PixelBufferAccess;
using tcu::ConstPixelBufferAccess;

// Utilities for ReferenceContext
#define RC_RET_VOID

#define RC_ERROR_RET(ERR, RET)			\
do {									\
	setError(ERR);						\
	return RET;							\
} while (deGetFalse())

#define RC_IF_ERROR(COND, ERR, RET)		\
do {									\
	if (COND)							\
		RC_ERROR_RET(ERR, RET);			\
} while (deGetFalse())

static inline tcu::PixelBufferAccess nullAccess (void)
{
	return tcu::PixelBufferAccess(TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT8), 0, 0, 0, DE_NULL);
}

static inline bool isEmpty (const tcu::ConstPixelBufferAccess& access)
{
	return access.getWidth() == 0 || access.getHeight() == 0 || access.getDepth() == 0;
}

static inline bool isEmpty (const rr::MultisampleConstPixelBufferAccess& access)
{
	return access.raw().getWidth() == 0 || access.raw().getHeight() == 0 || access.raw().getDepth() == 0;
}

static inline bool isEmpty (const IVec4& rect)
{
	return rect.z() == 0 || rect.w() == 0;
}

inline int getNumMipLevels1D (int size)
{
	return deLog2Floor32(size)+1;
}

inline int getNumMipLevels2D (int width, int height)
{
	return deLog2Floor32(de::max(width, height))+1;
}

inline int getNumMipLevels3D (int width, int height, int depth)
{
	return deLog2Floor32(de::max(width, de::max(height, depth)))+1;
}

inline int getMipLevelSize (int baseLevelSize, int levelNdx)
{
	return de::max(baseLevelSize >> levelNdx, 1);
}

inline bool isMipmapFilter (const tcu::Sampler::FilterMode mode)
{
	return mode != tcu::Sampler::NEAREST && mode != tcu::Sampler::LINEAR;
}

static tcu::CubeFace texTargetToFace (Framebuffer::TexTarget target)
{
	switch (target)
	{
		case Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_X:	return tcu::CUBEFACE_NEGATIVE_X;
		case Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_X:	return tcu::CUBEFACE_POSITIVE_X;
		case Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Y:	return tcu::CUBEFACE_NEGATIVE_Y;
		case Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_Y:	return tcu::CUBEFACE_POSITIVE_Y;
		case Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Z:	return tcu::CUBEFACE_NEGATIVE_Z;
		case Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_Z:	return tcu::CUBEFACE_POSITIVE_Z;
		default:											return tcu::CUBEFACE_LAST;
	}
}

static Framebuffer::TexTarget texLayeredTypeToTarget (Texture::Type type)
{
	switch (type)
	{
		case Texture::TYPE_2D_ARRAY:		return Framebuffer::TEXTARGET_2D_ARRAY;
		case Texture::TYPE_3D:				return Framebuffer::TEXTARGET_3D;
		case Texture::TYPE_CUBE_MAP_ARRAY:	return Framebuffer::TEXTARGET_CUBE_MAP_ARRAY;
		default:							return Framebuffer::TEXTARGET_LAST;
	}
}

static tcu::CubeFace mapGLCubeFace (deUint32 face)
{
	switch (face)
	{
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:	return tcu::CUBEFACE_NEGATIVE_X;
		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:	return tcu::CUBEFACE_POSITIVE_X;
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:	return tcu::CUBEFACE_NEGATIVE_Y;
		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:	return tcu::CUBEFACE_POSITIVE_Y;
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:	return tcu::CUBEFACE_NEGATIVE_Z;
		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:	return tcu::CUBEFACE_POSITIVE_Z;
		default:								return tcu::CUBEFACE_LAST;
	}
}

tcu::TextureFormat toTextureFormat (const tcu::PixelFormat& pixelFmt)
{
	static const struct
	{
		tcu::PixelFormat	pixelFmt;
		tcu::TextureFormat	texFmt;
	} pixelFormatMap[] =
	{
		{ tcu::PixelFormat(8,8,8,8),	tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNORM_INT8)			},
		{ tcu::PixelFormat(8,8,8,0),	tcu::TextureFormat(tcu::TextureFormat::RGB,		tcu::TextureFormat::UNORM_INT8)			},
		{ tcu::PixelFormat(4,4,4,4),	tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNORM_SHORT_4444)	},
		{ tcu::PixelFormat(5,5,5,1),	tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNORM_SHORT_5551)	},
		{ tcu::PixelFormat(5,6,5,0),	tcu::TextureFormat(tcu::TextureFormat::RGB,		tcu::TextureFormat::UNORM_SHORT_565)	}
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pixelFormatMap); ndx++)
	{
		if (pixelFormatMap[ndx].pixelFmt == pixelFmt)
			return pixelFormatMap[ndx].texFmt;
	}

	TCU_FAIL("Can't map pixel format to texture format");
}

tcu::TextureFormat toNonSRGBFormat (const tcu::TextureFormat& fmt)
{
	switch (fmt.order)
	{
		case tcu::TextureFormat::sRGB:
			return tcu::TextureFormat(tcu::TextureFormat::RGB,	fmt.type);
		case tcu::TextureFormat::sRGBA:
			return tcu::TextureFormat(tcu::TextureFormat::RGBA,	fmt.type);
		default:
			return fmt;
	}
}

tcu::TextureFormat getDepthFormat (int depthBits)
{
	switch (depthBits)
	{
		case 8:		return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT8);
		case 16:	return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
		case 24:	return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8);
		case 32:	return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
		default:
			TCU_FAIL("Can't map depth buffer format");
	}
}

tcu::TextureFormat getStencilFormat (int stencilBits)
{
	switch (stencilBits)
	{
		case 8:		return tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
		case 16:	return tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT16);
		case 24:	return tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT_24_8);
		case 32:	return tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT32);
		default:
			TCU_FAIL("Can't map depth buffer format");
	}
}

static inline tcu::IVec4 intersect (const tcu::IVec4& a, const tcu::IVec4& b)
{
	int		x0	= de::max(a.x(), b.x());
	int		y0	= de::max(a.y(), b.y());
	int		x1	= de::min(a.x()+a.z(), b.x()+b.z());
	int		y1	= de::min(a.y()+a.w(), b.y()+b.w());
	int		w	= de::max(0, x1-x0);
	int		h	= de::max(0, y1-y0);

	return tcu::IVec4(x0, y0, w, h);
}

static inline tcu::IVec4 getBufferRect (const rr::MultisampleConstPixelBufferAccess& access)
{
	return tcu::IVec4(0, 0, access.raw().getHeight(), access.raw().getDepth());
}

ReferenceContextLimits::ReferenceContextLimits (const glu::RenderContext& renderCtx)
	: contextType				(renderCtx.getType())
	, maxTextureImageUnits		(0)
	, maxTexture2DSize			(0)
	, maxTextureCubeSize		(0)
	, maxTexture2DArrayLayers	(0)
	, maxTexture3DSize			(0)
	, maxRenderbufferSize		(0)
	, maxVertexAttribs			(0)
	, subpixelBits				(0)
{
	const glw::Functions& gl = renderCtx.getFunctions();

	// When the OpenGL ES's major version bigger than 3, and the expect context version is 3,
	// we need query the real GL context version and update the real version to reference context.
	if (glu::IsES3Compatible(gl) && isES2Context(contextType))
	{
		int majorVersion = contextType.getMajorVersion();
		int minorVersion = contextType.getMinorVersion();
		gl.getIntegerv(GL_MAJOR_VERSION, &majorVersion);
		gl.getIntegerv(GL_MINOR_VERSION, &minorVersion);
		contextType.setAPI(glu::ApiType::es(majorVersion, minorVersion));
	}

	gl.getIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,		&maxTextureImageUnits);
	gl.getIntegerv(GL_MAX_TEXTURE_SIZE,				&maxTexture2DSize);
	gl.getIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE,	&maxTextureCubeSize);
	gl.getIntegerv(GL_MAX_RENDERBUFFER_SIZE,		&maxRenderbufferSize);
	gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS,			&maxVertexAttribs);
	gl.getIntegerv(GL_SUBPIXEL_BITS,				&subpixelBits);

	if (contextSupports(contextType, glu::ApiType::es(3,0)) || glu::isContextTypeGLCore(contextType))
	{
		gl.getIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS,	&maxTexture2DArrayLayers);
		gl.getIntegerv(GL_MAX_3D_TEXTURE_SIZE,		&maxTexture3DSize);
	}

	// Limit texture sizes to supported values
	maxTexture2DSize	= de::min(maxTexture2DSize,		(int)MAX_TEXTURE_SIZE);
	maxTextureCubeSize	= de::min(maxTextureCubeSize,	(int)MAX_TEXTURE_SIZE);
	maxTexture3DSize	= de::min(maxTexture3DSize,		(int)MAX_TEXTURE_SIZE);

	GLU_EXPECT_NO_ERROR(gl.getError(), GL_NO_ERROR);

	// \todo [pyry] Figure out following things:
	// + supported fbo configurations
	// ...

	// \todo [2013-08-01 pyry] Do we want to make these conditional based on renderCtx?
	addExtension("GL_EXT_color_buffer_half_float");
	addExtension("GL_EXT_color_buffer_float");

	if (contextSupports(contextType, glu::ApiType::es(3,1)))
		addExtension("GL_EXT_texture_cube_map_array");
}

void ReferenceContextLimits::addExtension (const char* extension)
{
	extensionList.push_back(extension);

	if (!extensionStr.empty())
		extensionStr += " ";
	extensionStr += extension;
}

ReferenceContextBuffers::ReferenceContextBuffers (const tcu::PixelFormat& colorBits, int depthBits, int stencilBits, int width, int height, int samples)
{
	m_colorbuffer.setStorage(toTextureFormat(colorBits), samples, width, height);

	if (depthBits > 0)
		m_depthbuffer.setStorage(getDepthFormat(depthBits), samples, width, height);

	if (stencilBits > 0)
		m_stencilbuffer.setStorage(getStencilFormat(stencilBits), samples, width, height);
}

ReferenceContext::StencilState::StencilState (void)
	: func				(GL_ALWAYS)
	, ref				(0)
	, opMask			(~0u)
	, opStencilFail		(GL_KEEP)
	, opDepthFail		(GL_KEEP)
	, opDepthPass		(GL_KEEP)
	, writeMask			(~0u)
{
}

ReferenceContext::ReferenceContext (const ReferenceContextLimits& limits, const rr::MultisamplePixelBufferAccess& colorbuffer, const rr::MultisamplePixelBufferAccess& depthbuffer, const rr::MultisamplePixelBufferAccess& stencilbuffer)
	: Context							(limits.contextType)
	, m_limits							(limits)
	, m_defaultColorbuffer				(colorbuffer)
	, m_defaultDepthbuffer				(depthbuffer)
	, m_defaultStencilbuffer			(stencilbuffer)
	, m_clientVertexArray				(0, m_limits.maxVertexAttribs)

	, m_viewport						(0, 0, colorbuffer.raw().getHeight(), colorbuffer.raw().getDepth())

	, m_activeTexture					(0)
	, m_textureUnits					(m_limits.maxTextureImageUnits)
	, m_emptyTex1D						()
	, m_emptyTex2D						(isES2Context(limits.contextType))
	, m_emptyTexCube					(!isES2Context(limits.contextType))
	, m_emptyTex2DArray					()
	, m_emptyTex3D						()
	, m_emptyTexCubeArray				()

	, m_pixelUnpackRowLength			(0)
	, m_pixelUnpackSkipRows				(0)
	, m_pixelUnpackSkipPixels			(0)
	, m_pixelUnpackImageHeight			(0)
	, m_pixelUnpackSkipImages			(0)
	, m_pixelUnpackAlignment			(4)
	, m_pixelPackAlignment				(4)

	, m_readFramebufferBinding			(DE_NULL)
	, m_drawFramebufferBinding			(DE_NULL)
	, m_renderbufferBinding				(DE_NULL)
	, m_vertexArrayBinding				(DE_NULL)
	, m_currentProgram					(DE_NULL)

	, m_arrayBufferBinding				(DE_NULL)
	, m_pixelPackBufferBinding			(DE_NULL)
	, m_pixelUnpackBufferBinding		(DE_NULL)
	, m_transformFeedbackBufferBinding	(DE_NULL)
	, m_uniformBufferBinding			(DE_NULL)
	, m_copyReadBufferBinding			(DE_NULL)
	, m_copyWriteBufferBinding			(DE_NULL)
	, m_drawIndirectBufferBinding		(DE_NULL)

	, m_clearColor						(0.0f, 0.0f, 0.0f, 0.0f)
	, m_clearDepth						(1.0f)
	, m_clearStencil					(0)
	, m_scissorEnabled					(false)
	, m_scissorBox						(m_viewport)
	, m_stencilTestEnabled				(false)
	, m_depthTestEnabled				(false)
	, m_depthFunc						(GL_LESS)
	, m_depthRangeNear					(0.0f)
	, m_depthRangeFar					(1.0f)
	, m_polygonOffsetFactor				(0.0f)
	, m_polygonOffsetUnits				(0.0f)
	, m_polygonOffsetFillEnabled		(false)
	, m_provokingFirstVertexConvention	(false)
	, m_blendEnabled					(false)
	, m_blendModeRGB					(GL_FUNC_ADD)
	, m_blendModeAlpha					(GL_FUNC_ADD)
	, m_blendFactorSrcRGB				(GL_ONE)
	, m_blendFactorDstRGB				(GL_ZERO)
	, m_blendFactorSrcAlpha				(GL_ONE)
	, m_blendFactorDstAlpha				(GL_ZERO)
	, m_blendColor						(0.0f, 0.0f, 0.0f, 0.0f)
	, m_sRGBUpdateEnabled				(true)
	, m_depthClampEnabled				(false)
	, m_colorMask						(true, true, true, true)
	, m_depthMask						(true)
	, m_currentAttribs					(m_limits.maxVertexAttribs, rr::GenericVec4(tcu::Vec4(0, 0, 0, 1)))
	, m_lineWidth						(1.0f)
	, m_primitiveRestartFixedIndex		(false)
	, m_primitiveRestartSettableIndex	(false)
	, m_primitiveRestartIndex			(0)

	, m_lastError						(GL_NO_ERROR)
{
	// Create empty textures to be used when texture objects are incomplete.
	m_emptyTex1D.getSampler().wrapS		= tcu::Sampler::CLAMP_TO_EDGE;
	m_emptyTex1D.getSampler().wrapT		= tcu::Sampler::CLAMP_TO_EDGE;
	m_emptyTex1D.getSampler().minFilter	= tcu::Sampler::NEAREST;
	m_emptyTex1D.getSampler().magFilter	= tcu::Sampler::NEAREST;
	m_emptyTex1D.allocLevel(0, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1);
	m_emptyTex1D.getLevel(0).setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0, 0);
	m_emptyTex1D.updateView(tcu::Sampler::MODE_LAST);

	m_emptyTex2D.getSampler().wrapS		= tcu::Sampler::CLAMP_TO_EDGE;
	m_emptyTex2D.getSampler().wrapT		= tcu::Sampler::CLAMP_TO_EDGE;
	m_emptyTex2D.getSampler().minFilter	= tcu::Sampler::NEAREST;
	m_emptyTex2D.getSampler().magFilter	= tcu::Sampler::NEAREST;
	m_emptyTex2D.allocLevel(0, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1);
	m_emptyTex2D.getLevel(0).setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0, 0);
	m_emptyTex2D.updateView(tcu::Sampler::MODE_LAST);

	m_emptyTexCube.getSampler().wrapS		= tcu::Sampler::CLAMP_TO_EDGE;
	m_emptyTexCube.getSampler().wrapT		= tcu::Sampler::CLAMP_TO_EDGE;
	m_emptyTexCube.getSampler().minFilter	= tcu::Sampler::NEAREST;
	m_emptyTexCube.getSampler().magFilter	= tcu::Sampler::NEAREST;
	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
	{
		m_emptyTexCube.allocFace(0, (tcu::CubeFace)face, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1);
		m_emptyTexCube.getFace(0, (tcu::CubeFace)face).setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0, 0);
	}
	m_emptyTexCube.updateView(tcu::Sampler::MODE_LAST);

	m_emptyTex2DArray.getSampler().wrapS		= tcu::Sampler::CLAMP_TO_EDGE;
	m_emptyTex2DArray.getSampler().wrapT		= tcu::Sampler::CLAMP_TO_EDGE;
	m_emptyTex2DArray.getSampler().minFilter	= tcu::Sampler::NEAREST;
	m_emptyTex2DArray.getSampler().magFilter	= tcu::Sampler::NEAREST;
	m_emptyTex2DArray.allocLevel(0, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1, 1);
	m_emptyTex2DArray.getLevel(0).setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0, 0);
	m_emptyTex2DArray.updateView(tcu::Sampler::MODE_LAST);

	m_emptyTex3D.getSampler().wrapS		= tcu::Sampler::CLAMP_TO_EDGE;
	m_emptyTex3D.getSampler().wrapT		= tcu::Sampler::CLAMP_TO_EDGE;
	m_emptyTex3D.getSampler().wrapR		= tcu::Sampler::CLAMP_TO_EDGE;
	m_emptyTex3D.getSampler().minFilter	= tcu::Sampler::NEAREST;
	m_emptyTex3D.getSampler().magFilter	= tcu::Sampler::NEAREST;
	m_emptyTex3D.allocLevel(0, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1, 1);
	m_emptyTex3D.getLevel(0).setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0, 0);
	m_emptyTex3D.updateView(tcu::Sampler::MODE_LAST);

	m_emptyTexCubeArray.getSampler().wrapS		= tcu::Sampler::CLAMP_TO_EDGE;
	m_emptyTexCubeArray.getSampler().wrapT		= tcu::Sampler::CLAMP_TO_EDGE;
	m_emptyTexCubeArray.getSampler().minFilter	= tcu::Sampler::NEAREST;
	m_emptyTexCubeArray.getSampler().magFilter	= tcu::Sampler::NEAREST;
	m_emptyTexCubeArray.allocLevel(0, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1, 6);
	for (int faceNdx = 0; faceNdx < 6; faceNdx++)
		m_emptyTexCubeArray.getLevel(0).setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0, 0, faceNdx);
	m_emptyTexCubeArray.updateView(tcu::Sampler::MODE_LAST);

	for (int unitNdx = 0; unitNdx < m_limits.maxTextureImageUnits; unitNdx++)
		m_textureUnits[unitNdx].defaultCubeTex.getSampler().seamlessCubeMap = !isES2Context(limits.contextType);

	if (glu::isContextTypeGLCore(getType()))
		m_sRGBUpdateEnabled = false;
}

ReferenceContext::~ReferenceContext (void)
{
	// Destroy all objects -- verifies that ref counting works
	{
		vector<VertexArray*> vertexArrays;
		m_vertexArrays.getAll(vertexArrays);
		for (vector<VertexArray*>::iterator i = vertexArrays.begin(); i != vertexArrays.end(); i++)
			deleteVertexArray(*i);

		DE_ASSERT(m_clientVertexArray.getRefCount() == 1);
	}

	{
		vector<Texture*> textures;
		m_textures.getAll(textures);
		for (vector<Texture*>::iterator i = textures.begin(); i != textures.end(); i++)
			deleteTexture(*i);
	}

	{
		vector<Framebuffer*> framebuffers;
		m_framebuffers.getAll(framebuffers);
		for (vector<Framebuffer*>::iterator i = framebuffers.begin(); i != framebuffers.end(); i++)
			deleteFramebuffer(*i);
	}

	{
		vector<Renderbuffer*> renderbuffers;
		m_renderbuffers.getAll(renderbuffers);
		for (vector<Renderbuffer*>::iterator i = renderbuffers.begin(); i != renderbuffers.end(); i++)
			deleteRenderbuffer(*i);
	}

	{
		vector<DataBuffer*> buffers;
		m_buffers.getAll(buffers);
		for (vector<DataBuffer*>::iterator i = buffers.begin(); i != buffers.end(); i++)
			deleteBuffer(*i);
	}

	{
		vector<ShaderProgramObjectContainer*> programs;
		m_programs.getAll(programs);
		for (vector<ShaderProgramObjectContainer*>::iterator i = programs.begin(); i != programs.end(); i++)
			deleteProgramObject(*i);
	}
}

void ReferenceContext::activeTexture (deUint32 texture)
{
	if (deInBounds32(texture, GL_TEXTURE0, GL_TEXTURE0 + (deUint32)m_textureUnits.size()))
		m_activeTexture = texture - GL_TEXTURE0;
	else
		setError(GL_INVALID_ENUM);
}

void ReferenceContext::setTex1DBinding (int unitNdx, Texture1D* texture)
{
	if (m_textureUnits[unitNdx].tex1DBinding)
	{
		m_textures.releaseReference(m_textureUnits[unitNdx].tex1DBinding);
		m_textureUnits[unitNdx].tex1DBinding = DE_NULL;
	}

	if (texture)
	{
		m_textures.acquireReference(texture);
		m_textureUnits[unitNdx].tex1DBinding = texture;
	}
}

void ReferenceContext::setTex2DBinding (int unitNdx, Texture2D* texture)
{
	if (m_textureUnits[unitNdx].tex2DBinding)
	{
		m_textures.releaseReference(m_textureUnits[unitNdx].tex2DBinding);
		m_textureUnits[unitNdx].tex2DBinding = DE_NULL;
	}

	if (texture)
	{
		m_textures.acquireReference(texture);
		m_textureUnits[unitNdx].tex2DBinding = texture;
	}
}

void ReferenceContext::setTexCubeBinding (int unitNdx, TextureCube* texture)
{
	if (m_textureUnits[unitNdx].texCubeBinding)
	{
		m_textures.releaseReference(m_textureUnits[unitNdx].texCubeBinding);
		m_textureUnits[unitNdx].texCubeBinding = DE_NULL;
	}

	if (texture)
	{
		m_textures.acquireReference(texture);
		m_textureUnits[unitNdx].texCubeBinding = texture;
	}
}

void ReferenceContext::setTex2DArrayBinding (int unitNdx, Texture2DArray* texture)
{
	if (m_textureUnits[unitNdx].tex2DArrayBinding)
	{
		m_textures.releaseReference(m_textureUnits[unitNdx].tex2DArrayBinding);
		m_textureUnits[unitNdx].tex2DArrayBinding = DE_NULL;
	}

	if (texture)
	{
		m_textures.acquireReference(texture);
		m_textureUnits[unitNdx].tex2DArrayBinding = texture;
	}
}

void ReferenceContext::setTex3DBinding (int unitNdx, Texture3D* texture)
{
	if (m_textureUnits[unitNdx].tex3DBinding)
	{
		m_textures.releaseReference(m_textureUnits[unitNdx].tex3DBinding);
		m_textureUnits[unitNdx].tex3DBinding = DE_NULL;
	}

	if (texture)
	{
		m_textures.acquireReference(texture);
		m_textureUnits[unitNdx].tex3DBinding = texture;
	}
}

void ReferenceContext::setTexCubeArrayBinding (int unitNdx, TextureCubeArray* texture)
{
	if (m_textureUnits[unitNdx].texCubeArrayBinding)
	{
		m_textures.releaseReference(m_textureUnits[unitNdx].texCubeArrayBinding);
		m_textureUnits[unitNdx].texCubeArrayBinding = DE_NULL;
	}

	if (texture)
	{
		m_textures.acquireReference(texture);
		m_textureUnits[unitNdx].texCubeArrayBinding = texture;
	}
}

void ReferenceContext::bindTexture (deUint32 target, deUint32 texture)
{
	int unitNdx = m_activeTexture;

	RC_IF_ERROR(target != GL_TEXTURE_1D				&&
				target != GL_TEXTURE_2D				&&
				target != GL_TEXTURE_CUBE_MAP		&&
				target != GL_TEXTURE_2D_ARRAY		&&
				target != GL_TEXTURE_3D				&&
				target != GL_TEXTURE_CUBE_MAP_ARRAY,
				GL_INVALID_ENUM, RC_RET_VOID);

	RC_IF_ERROR(glu::isContextTypeES(m_limits.contextType) && (target == GL_TEXTURE_1D), GL_INVALID_ENUM, RC_RET_VOID);

	if (texture == 0)
	{
		// Clear binding.
		switch (target)
		{
			case GL_TEXTURE_1D:				setTex1DBinding			(unitNdx, DE_NULL);	break;
			case GL_TEXTURE_2D:				setTex2DBinding			(unitNdx, DE_NULL);	break;
			case GL_TEXTURE_CUBE_MAP:		setTexCubeBinding		(unitNdx, DE_NULL);	break;
			case GL_TEXTURE_2D_ARRAY:		setTex2DArrayBinding	(unitNdx, DE_NULL);	break;
			case GL_TEXTURE_3D:				setTex3DBinding			(unitNdx, DE_NULL);	break;
			case GL_TEXTURE_CUBE_MAP_ARRAY:	setTexCubeArrayBinding	(unitNdx, DE_NULL);	break;
			default:
				DE_ASSERT(false);
		}
	}
	else
	{
		Texture* texObj = m_textures.find(texture);

		if (texObj)
		{
			// Validate type.
			Texture::Type expectedType = Texture::TYPE_LAST;
			switch (target)
			{
				case GL_TEXTURE_1D:				expectedType = Texture::TYPE_1D;				break;
				case GL_TEXTURE_2D:				expectedType = Texture::TYPE_2D;				break;
				case GL_TEXTURE_CUBE_MAP:		expectedType = Texture::TYPE_CUBE_MAP;			break;
				case GL_TEXTURE_2D_ARRAY:		expectedType = Texture::TYPE_2D_ARRAY;			break;
				case GL_TEXTURE_3D:				expectedType = Texture::TYPE_3D;				break;
				case GL_TEXTURE_CUBE_MAP_ARRAY:	expectedType = Texture::TYPE_CUBE_MAP_ARRAY;	break;
				default:
					DE_ASSERT(false);
			}
			RC_IF_ERROR(texObj->getType() != expectedType, GL_INVALID_OPERATION, RC_RET_VOID);
		}
		else
		{
			// New texture object.
			bool seamlessCubeMap = !isES2Context(m_limits.contextType);
			switch (target)
			{
				case GL_TEXTURE_1D:				texObj = new Texture1D			(texture);					break;
				case GL_TEXTURE_2D:				texObj = new Texture2D			(texture);					break;
				case GL_TEXTURE_CUBE_MAP:		texObj = new TextureCube		(texture, seamlessCubeMap);	break;
				case GL_TEXTURE_2D_ARRAY:		texObj = new Texture2DArray		(texture);					break;
				case GL_TEXTURE_3D:				texObj = new Texture3D			(texture);					break;
				case GL_TEXTURE_CUBE_MAP_ARRAY:	texObj = new TextureCubeArray	(texture);					break;
				default:
					DE_ASSERT(false);
			}

			m_textures.insert(texObj);
		}

		switch (target)
		{
			case GL_TEXTURE_1D:				setTex1DBinding			(unitNdx, static_cast<Texture1D*>			(texObj));	break;
			case GL_TEXTURE_2D:				setTex2DBinding			(unitNdx, static_cast<Texture2D*>			(texObj));	break;
			case GL_TEXTURE_CUBE_MAP:		setTexCubeBinding		(unitNdx, static_cast<TextureCube*>			(texObj));	break;
			case GL_TEXTURE_2D_ARRAY:		setTex2DArrayBinding	(unitNdx, static_cast<Texture2DArray*>		(texObj));	break;
			case GL_TEXTURE_3D:				setTex3DBinding			(unitNdx, static_cast<Texture3D*>			(texObj));	break;
			case GL_TEXTURE_CUBE_MAP_ARRAY:	setTexCubeArrayBinding	(unitNdx, static_cast<TextureCubeArray*>	(texObj));	break;
			default:
				DE_ASSERT(false);
		}
	}
}

void ReferenceContext::genTextures (int numTextures, deUint32* textures)
{
	while (numTextures--)
		*textures++ = m_textures.allocateName();
}

void ReferenceContext::deleteTextures (int numTextures, const deUint32* textures)
{
	for (int i = 0; i < numTextures; i++)
	{
		deUint32	name		= textures[i];
		Texture*	texture		= name ? m_textures.find(name) : DE_NULL;

		if (texture)
			deleteTexture(texture);
	}
}

void ReferenceContext::deleteTexture (Texture* texture)
{
	// Unbind from context
	for (int unitNdx = 0; unitNdx < (int)m_textureUnits.size(); unitNdx++)
	{
		if (m_textureUnits[unitNdx].tex1DBinding				== texture)	setTex1DBinding			(unitNdx, DE_NULL);
		else if (m_textureUnits[unitNdx].tex2DBinding			== texture)	setTex2DBinding			(unitNdx, DE_NULL);
		else if (m_textureUnits[unitNdx].texCubeBinding			== texture)	setTexCubeBinding		(unitNdx, DE_NULL);
		else if (m_textureUnits[unitNdx].tex2DArrayBinding		== texture)	setTex2DArrayBinding	(unitNdx, DE_NULL);
		else if (m_textureUnits[unitNdx].tex3DBinding			== texture)	setTex3DBinding			(unitNdx, DE_NULL);
		else if (m_textureUnits[unitNdx].texCubeArrayBinding	== texture)	setTexCubeArrayBinding	(unitNdx, DE_NULL);
	}

	// Unbind from currently bound framebuffers
	for (int ndx = 0; ndx < 2; ndx++)
	{
		rc::Framebuffer* framebufferBinding = ndx ? m_drawFramebufferBinding : m_readFramebufferBinding;
		if (framebufferBinding)
		{
			int releaseRefCount = (framebufferBinding == m_drawFramebufferBinding ? 1 : 0)
								+ (framebufferBinding == m_readFramebufferBinding ? 1 : 0);

			for (int point = 0; point < Framebuffer::ATTACHMENTPOINT_LAST; point++)
			{
				Framebuffer::Attachment& attachment = framebufferBinding->getAttachment((Framebuffer::AttachmentPoint)point);
				if (attachment.name == texture->getName())
				{
					for (int refNdx = 0; refNdx < releaseRefCount; refNdx++)
						releaseFboAttachmentReference(attachment);
					attachment = Framebuffer::Attachment();
				}
			}
		}
	}

	DE_ASSERT(texture->getRefCount() == 1);
	m_textures.releaseReference(texture);
}

void ReferenceContext::bindFramebuffer (deUint32 target, deUint32 name)
{
	Framebuffer* fbo = DE_NULL;

	RC_IF_ERROR(target != GL_FRAMEBUFFER		&&
				target != GL_DRAW_FRAMEBUFFER	&&
				target != GL_READ_FRAMEBUFFER, GL_INVALID_ENUM, RC_RET_VOID);

	if (name != 0)
	{
		// Find or create framebuffer object.
		fbo = m_framebuffers.find(name);
		if (!fbo)
		{
			fbo = new Framebuffer(name);
			m_framebuffers.insert(fbo);
		}
	}

	for (int ndx = 0; ndx < 2; ndx++)
	{
		deUint32			bindingTarget	= ndx ? GL_DRAW_FRAMEBUFFER			: GL_READ_FRAMEBUFFER;
		rc::Framebuffer*&	binding			= ndx ? m_drawFramebufferBinding	: m_readFramebufferBinding;

		if (target != GL_FRAMEBUFFER && target != bindingTarget)
			continue; // Doesn't match this target.

		// Remove old references
		if (binding)
		{
			// Clear all attachment point references
			for (int point = 0; point < Framebuffer::ATTACHMENTPOINT_LAST; point++)
				releaseFboAttachmentReference(binding->getAttachment((Framebuffer::AttachmentPoint)point));

			m_framebuffers.releaseReference(binding);
		}

		// Create new references
		if (fbo)
		{
			m_framebuffers.acquireReference(fbo);

			for (int point = 0; point < Framebuffer::ATTACHMENTPOINT_LAST; point++)
				acquireFboAttachmentReference(fbo->getAttachment((Framebuffer::AttachmentPoint)point));
		}

		binding = fbo;
	}
}

void ReferenceContext::genFramebuffers (int numFramebuffers, deUint32* framebuffers)
{
	while (numFramebuffers--)
		*framebuffers++ = m_framebuffers.allocateName();
}

void ReferenceContext::deleteFramebuffer (Framebuffer* framebuffer)
{
	// Remove bindings.
	if (m_drawFramebufferBinding == framebuffer) bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
	if (m_readFramebufferBinding == framebuffer) bindFramebuffer(GL_READ_FRAMEBUFFER, 0);

	DE_ASSERT(framebuffer->getRefCount() == 1);
	m_framebuffers.releaseReference(framebuffer);
}

void ReferenceContext::deleteFramebuffers (int numFramebuffers, const deUint32* framebuffers)
{
	for (int i = 0; i < numFramebuffers; i++)
	{
		deUint32		name		= framebuffers[i];
		Framebuffer*	framebuffer	= name ? m_framebuffers.find(name) : DE_NULL;

		if (framebuffer)
			deleteFramebuffer(framebuffer);
	}
}

void ReferenceContext::bindRenderbuffer (deUint32 target, deUint32 name)
{
	Renderbuffer* rbo = DE_NULL;

	RC_IF_ERROR(target != GL_RENDERBUFFER, GL_INVALID_ENUM, RC_RET_VOID);

	if (name != 0)
	{
		rbo = m_renderbuffers.find(name);
		if (!rbo)
		{
			rbo = new Renderbuffer(name);
			m_renderbuffers.insert(rbo);
		}
	}

	// Remove old reference
	if (m_renderbufferBinding)
		m_renderbuffers.releaseReference(m_renderbufferBinding);

	// Create new reference
	if (rbo)
		m_renderbuffers.acquireReference(rbo);

	m_renderbufferBinding = rbo;
}

void ReferenceContext::genRenderbuffers (int numRenderbuffers, deUint32* renderbuffers)
{
	while (numRenderbuffers--)
		*renderbuffers++ = m_renderbuffers.allocateName();
}

void ReferenceContext::deleteRenderbuffer (Renderbuffer* renderbuffer)
{
	if (m_renderbufferBinding == renderbuffer)
		bindRenderbuffer(GL_RENDERBUFFER, 0);

	// Unbind from currently bound framebuffers
	for (int ndx = 0; ndx < 2; ndx++)
	{
		rc::Framebuffer* framebufferBinding = ndx ? m_drawFramebufferBinding : m_readFramebufferBinding;
		if (framebufferBinding)
		{
			int releaseRefCount = (framebufferBinding == m_drawFramebufferBinding ? 1 : 0)
								+ (framebufferBinding == m_readFramebufferBinding ? 1 : 0);

			for (int point = 0; point < Framebuffer::ATTACHMENTPOINT_LAST; point++)
			{
				Framebuffer::Attachment& attachment = framebufferBinding->getAttachment((Framebuffer::AttachmentPoint)point);
				if (attachment.name == renderbuffer->getName())
				{
					for (int refNdx = 0; refNdx < releaseRefCount; refNdx++)
						releaseFboAttachmentReference(attachment);
					attachment = Framebuffer::Attachment();
				}
			}
		}
	}

	DE_ASSERT(renderbuffer->getRefCount() == 1);
	m_renderbuffers.releaseReference(renderbuffer);
}

void ReferenceContext::deleteRenderbuffers (int numRenderbuffers, const deUint32* renderbuffers)
{
	for (int i = 0; i < numRenderbuffers; i++)
	{
		deUint32		name			= renderbuffers[i];
		Renderbuffer*	renderbuffer	= name ? m_renderbuffers.find(name) : DE_NULL;

		if (renderbuffer)
			deleteRenderbuffer(renderbuffer);
	}
}

void ReferenceContext::pixelStorei (deUint32 pname, int param)
{
	switch (pname)
	{
		case GL_UNPACK_ALIGNMENT:
			RC_IF_ERROR(param != 1 && param != 2 && param != 4 && param != 8, GL_INVALID_VALUE, RC_RET_VOID);
			m_pixelUnpackAlignment = param;
			break;

		case GL_PACK_ALIGNMENT:
			RC_IF_ERROR(param != 1 && param != 2 && param != 4 && param != 8, GL_INVALID_VALUE, RC_RET_VOID);
			m_pixelPackAlignment = param;
			break;

		case GL_UNPACK_ROW_LENGTH:
			RC_IF_ERROR(param < 0, GL_INVALID_VALUE, RC_RET_VOID);
			m_pixelUnpackRowLength = param;
			break;

		case GL_UNPACK_SKIP_ROWS:
			RC_IF_ERROR(param < 0, GL_INVALID_VALUE, RC_RET_VOID);
			m_pixelUnpackSkipRows = param;
			break;

		case GL_UNPACK_SKIP_PIXELS:
			RC_IF_ERROR(param < 0, GL_INVALID_VALUE, RC_RET_VOID);
			m_pixelUnpackSkipPixels = param;
			break;

		case GL_UNPACK_IMAGE_HEIGHT:
			RC_IF_ERROR(param < 0, GL_INVALID_VALUE, RC_RET_VOID);
			m_pixelUnpackImageHeight = param;
			break;

		case GL_UNPACK_SKIP_IMAGES:
			RC_IF_ERROR(param < 0, GL_INVALID_VALUE, RC_RET_VOID);
			m_pixelUnpackSkipImages = param;
			break;

		default:
			setError(GL_INVALID_ENUM);
	}
}

tcu::ConstPixelBufferAccess ReferenceContext::getUnpack2DAccess (const tcu::TextureFormat& format, int width, int height, const void* data)
{
	int				pixelSize	= format.getPixelSize();
	int				rowLen		= m_pixelUnpackRowLength > 0 ? m_pixelUnpackRowLength : width;
	int				rowPitch	= deAlign32(rowLen*pixelSize, m_pixelUnpackAlignment);
	const deUint8*	ptr			= (const deUint8*)data + m_pixelUnpackSkipRows*rowPitch + m_pixelUnpackSkipPixels*pixelSize;

	return tcu::ConstPixelBufferAccess(format, width, height, 1, rowPitch, 0, ptr);
}

tcu::ConstPixelBufferAccess ReferenceContext::getUnpack3DAccess (const tcu::TextureFormat& format, int width, int height, int depth, const void* data)
{
	int				pixelSize	= format.getPixelSize();
	int				rowLen		= m_pixelUnpackRowLength	> 0 ? m_pixelUnpackRowLength	: width;
	int				imageHeight	= m_pixelUnpackImageHeight	> 0 ? m_pixelUnpackImageHeight	: height;
	int				rowPitch	= deAlign32(rowLen*pixelSize, m_pixelUnpackAlignment);
	int				slicePitch	= imageHeight*rowPitch;
	const deUint8*	ptr			= (const deUint8*)data + m_pixelUnpackSkipImages*slicePitch + m_pixelUnpackSkipRows*rowPitch + m_pixelUnpackSkipPixels*pixelSize;

	return tcu::ConstPixelBufferAccess(format, width, height, depth, rowPitch, slicePitch, ptr);
}

static tcu::TextureFormat mapInternalFormat (deUint32 internalFormat)
{
	switch (internalFormat)
	{
		case GL_ALPHA:				return TextureFormat(TextureFormat::A,		TextureFormat::UNORM_INT8);
		case GL_LUMINANCE:			return TextureFormat(TextureFormat::L,		TextureFormat::UNORM_INT8);
		case GL_LUMINANCE_ALPHA:	return TextureFormat(TextureFormat::LA,		TextureFormat::UNORM_INT8);
		case GL_RGB:				return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_INT8);
		case GL_RGBA:				return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8);

		default:
			return glu::mapGLInternalFormat(internalFormat);
	}
}

static void depthValueFloatClampCopy (const PixelBufferAccess& dst, const ConstPixelBufferAccess& src)
{
	int width	= dst.getWidth();
	int height	= dst.getHeight();
	int depth	= dst.getDepth();

	DE_ASSERT(src.getWidth() == width && src.getHeight() == height && src.getDepth() == depth);

	// clamping copy

	if (src.getFormat().order == tcu::TextureFormat::DS && dst.getFormat().order == tcu::TextureFormat::DS)
	{
		// copy only depth and stencil
		for (int z = 0; z < depth; z++)
		for (int y = 0; y < height; y++)
		for (int x = 0; x < width; x++)
		{
			dst.setPixDepth(de::clamp(src.getPixDepth(x, y, z), 0.0f, 1.0f), x, y, z);
			dst.setPixStencil(src.getPixStencil(x, y, z), x, y, z);
		}
	}
	else
	{
		// copy only depth
		for (int z = 0; z < depth; z++)
		for (int y = 0; y < height; y++)
		for (int x = 0; x < width; x++)
			dst.setPixDepth(de::clamp(src.getPixDepth(x, y, z), 0.0f, 1.0f), x, y, z);
	}
}

void ReferenceContext::texImage1D (deUint32 target, int level, deUint32 internalFormat, int width, int border, deUint32 format, deUint32 type, const void* data)
{
	texImage2D(target, level, internalFormat, width, 1, border, format, type, data);
}

void ReferenceContext::texImage2D (deUint32 target, int level, deUint32 internalFormat, int width, int height, int border, deUint32 format, deUint32 type, const void* data)
{
	texImage3D(target, level, internalFormat, width, height, 1, border, format, type, data);
}

static void clearToTextureInitialValue (PixelBufferAccess access)
{
	const bool hasDepth		= access.getFormat().order == tcu::TextureFormat::D || access.getFormat().order == tcu::TextureFormat::DS;
	const bool hasStencil	= access.getFormat().order == tcu::TextureFormat::S || access.getFormat().order == tcu::TextureFormat::DS;
	const bool hasColor		= !hasDepth && !hasStencil;

	if (hasDepth)
		tcu::clearDepth(access, 0.0f);
	if (hasStencil)
		tcu::clearStencil(access, 0u);
	if (hasColor)
		tcu::clear(access, Vec4(0.0f, 0.0f, 0.0f, 1.0f));
}

void ReferenceContext::texImage3D (deUint32 target, int level, deUint32 internalFormat, int width, int height, int depth, int border, deUint32 format, deUint32 type, const void* data)
{
	TextureUnit&		unit					= m_textureUnits[m_activeTexture];
	const void*			unpackPtr				= getPixelUnpackPtr(data);
	const bool			isDstFloatDepthFormat	= (internalFormat == GL_DEPTH_COMPONENT32F || internalFormat == GL_DEPTH32F_STENCIL8); // depth components are limited to [0,1] range
	TextureFormat		storageFmt;
	TextureFormat		transferFmt;

	RC_IF_ERROR(border != 0, GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(width < 0 || height < 0 || depth < 0 || level < 0, GL_INVALID_VALUE, RC_RET_VOID);

	// Map storage format.
	storageFmt = mapInternalFormat(internalFormat);
	RC_IF_ERROR(storageFmt.order	== TextureFormat::CHANNELORDER_LAST ||
				storageFmt.type		== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);

	// Map transfer format.
	transferFmt = glu::mapGLTransferFormat(format, type);
	RC_IF_ERROR(transferFmt.order	== TextureFormat::CHANNELORDER_LAST ||
				transferFmt.type	== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);

	if (target == GL_TEXTURE_1D && glu::isContextTypeGLCore(m_limits.contextType))
	{
		// Validate size and level.
		RC_IF_ERROR(width > m_limits.maxTexture2DSize || height != 1 || depth != 1, GL_INVALID_VALUE, RC_RET_VOID);
		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);

		Texture1D* texture = unit.tex1DBinding ? unit.tex1DBinding : &unit.default1DTex;

		if (texture->isImmutable())
		{
			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);

			ConstPixelBufferAccess dst(texture->getLevel(level));
			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
						width		!= dst.getWidth(), GL_INVALID_OPERATION, RC_RET_VOID);
		}
		else
			texture->allocLevel(level, storageFmt, width);

		if (unpackPtr)
		{
			ConstPixelBufferAccess	src		= getUnpack2DAccess(transferFmt, width, 1, unpackPtr);
			PixelBufferAccess		dst		(texture->getLevel(level));

			if (isDstFloatDepthFormat)
				depthValueFloatClampCopy(dst, src);
			else
				tcu::copy(dst, src);
		}
		else
		{
			// No data supplied, clear to initial
			clearToTextureInitialValue(texture->getLevel(level));
		}
	}
	else if (target == GL_TEXTURE_2D)
	{
		// Validate size and level.
		RC_IF_ERROR(width > m_limits.maxTexture2DSize || height > m_limits.maxTexture2DSize || depth != 1, GL_INVALID_VALUE, RC_RET_VOID);
		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);

		Texture2D* texture = unit.tex2DBinding ? unit.tex2DBinding : &unit.default2DTex;

		if (texture->isImmutable())
		{
			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);

			ConstPixelBufferAccess dst(texture->getLevel(level));
			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
						width		!= dst.getWidth()	||
						height		!= dst.getHeight(), GL_INVALID_OPERATION, RC_RET_VOID);
		}
		else
			texture->allocLevel(level, storageFmt, width, height);

		if (unpackPtr)
		{
			ConstPixelBufferAccess	src		= getUnpack2DAccess(transferFmt, width, height, unpackPtr);
			PixelBufferAccess		dst		(texture->getLevel(level));

			if (isDstFloatDepthFormat)
				depthValueFloatClampCopy(dst, src);
			else
				tcu::copy(dst, src);
		}
		else
		{
			// No data supplied, clear to initial
			clearToTextureInitialValue(texture->getLevel(level));
		}
	}
	else if (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ||
			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z)
	{
		// Validate size and level.
		RC_IF_ERROR(width != height || width > m_limits.maxTextureCubeSize || depth != 1, GL_INVALID_VALUE, RC_RET_VOID);
		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTextureCubeSize), GL_INVALID_VALUE, RC_RET_VOID);

		TextureCube*	texture	= unit.texCubeBinding ? unit.texCubeBinding : &unit.defaultCubeTex;
		tcu::CubeFace	face	= mapGLCubeFace(target);

		if (texture->isImmutable())
		{
			RC_IF_ERROR(!texture->hasFace(level, face), GL_INVALID_OPERATION, RC_RET_VOID);

			ConstPixelBufferAccess dst(texture->getFace(level, face));
			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
						width		!= dst.getWidth()	||
						height		!= dst.getHeight(), GL_INVALID_OPERATION, RC_RET_VOID);
		}
		else
			texture->allocFace(level, face, storageFmt, width, height);

		if (unpackPtr)
		{
			ConstPixelBufferAccess	src		= getUnpack2DAccess(transferFmt, width, height, unpackPtr);
			PixelBufferAccess		dst		(texture->getFace(level, face));

			if (isDstFloatDepthFormat)
				depthValueFloatClampCopy(dst, src);
			else
				tcu::copy(dst, src);
		}
		else
		{
			// No data supplied, clear to initial
			clearToTextureInitialValue(texture->getFace(level, face));
		}
	}
	else if (target == GL_TEXTURE_2D_ARRAY)
	{
		// Validate size and level.
		RC_IF_ERROR(width	> m_limits.maxTexture2DSize ||
					height	> m_limits.maxTexture2DSize ||
					depth	> m_limits.maxTexture2DArrayLayers, GL_INVALID_VALUE, RC_RET_VOID);
		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);

		Texture2DArray* texture = unit.tex2DArrayBinding ? unit.tex2DArrayBinding : &unit.default2DArrayTex;

		if (texture->isImmutable())
		{
			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);

			ConstPixelBufferAccess dst(texture->getLevel(level));
			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
						width		!= dst.getWidth()	||
						height		!= dst.getHeight()	||
						depth		!= dst.getDepth(), GL_INVALID_OPERATION, RC_RET_VOID);
		}
		else
			texture->allocLevel(level, storageFmt, width, height, depth);

		if (unpackPtr)
		{
			ConstPixelBufferAccess	src		= getUnpack3DAccess(transferFmt, width, height, depth, unpackPtr);
			PixelBufferAccess		dst		(texture->getLevel(level));

			if (isDstFloatDepthFormat)
				depthValueFloatClampCopy(dst, src);
			else
				tcu::copy(dst, src);
		}
		else
		{
			// No data supplied, clear to initial
			clearToTextureInitialValue(texture->getLevel(level));
		}
	}
	else if (target == GL_TEXTURE_3D)
	{
		// Validate size and level.
		RC_IF_ERROR(width	> m_limits.maxTexture3DSize ||
					height	> m_limits.maxTexture3DSize ||
					depth	> m_limits.maxTexture3DSize, GL_INVALID_VALUE, RC_RET_VOID);
		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture3DSize), GL_INVALID_VALUE, RC_RET_VOID);

		Texture3D* texture = unit.tex3DBinding ? unit.tex3DBinding : &unit.default3DTex;

		if (texture->isImmutable())
		{
			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);

			ConstPixelBufferAccess dst(texture->getLevel(level));
			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
						width		!= dst.getWidth()	||
						height		!= dst.getHeight()	||
						depth		!= dst.getDepth(), GL_INVALID_OPERATION, RC_RET_VOID);
		}
		else
			texture->allocLevel(level, storageFmt, width, height, depth);

		if (unpackPtr)
		{
			ConstPixelBufferAccess	src		= getUnpack3DAccess(transferFmt, width, height, depth, unpackPtr);
			PixelBufferAccess		dst		(texture->getLevel(level));

			if (isDstFloatDepthFormat)
				depthValueFloatClampCopy(dst, src);
			else
				tcu::copy(dst, src);
		}
		else
		{
			// No data supplied, clear to initial
			clearToTextureInitialValue(texture->getLevel(level));
		}
	}
	else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
	{
		// Validate size and level.
		RC_IF_ERROR(width		!= height						||
					width		 > m_limits.maxTexture2DSize	||
					depth % 6	!= 0							||
					depth		 > m_limits.maxTexture2DArrayLayers, GL_INVALID_VALUE, RC_RET_VOID);
		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);

		TextureCubeArray* texture = unit.texCubeArrayBinding ? unit.texCubeArrayBinding : &unit.defaultCubeArrayTex;

		if (texture->isImmutable())
		{
			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);

			ConstPixelBufferAccess dst(texture->getLevel(level));
			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
						width		!= dst.getWidth()	||
						height		!= dst.getHeight()	||
						depth		!= dst.getDepth(), GL_INVALID_OPERATION, RC_RET_VOID);
		}
		else
			texture->allocLevel(level, storageFmt, width, height, depth);

		if (unpackPtr)
		{
			ConstPixelBufferAccess	src		= getUnpack3DAccess(transferFmt, width, height, depth, unpackPtr);
			PixelBufferAccess		dst		(texture->getLevel(level));

			if (isDstFloatDepthFormat)
				depthValueFloatClampCopy(dst, src);
			else
				tcu::copy(dst, src);
		}
		else
		{
			// No data supplied, clear to initial
			clearToTextureInitialValue(texture->getLevel(level));
		}
	}
	else
		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
}

void ReferenceContext::texSubImage1D (deUint32 target, int level, int xoffset, int width, deUint32 format, deUint32 type, const void* data)
{
	texSubImage2D(target, level, xoffset, 0, width, 1, format, type, data);
}

void ReferenceContext::texSubImage2D (deUint32 target, int level, int xoffset, int yoffset, int width, int height, deUint32 format, deUint32 type, const void* data)
{
	texSubImage3D(target, level, xoffset, yoffset, 0, width, height, 1, format, type, data);
}

void ReferenceContext::texSubImage3D (deUint32 target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, deUint32 format, deUint32 type, const void* data)
{
	TextureUnit& unit = m_textureUnits[m_activeTexture];

	RC_IF_ERROR(xoffset < 0 || yoffset < 0 || zoffset < 0,	GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(width < 0 || height < 0 || depth < 0,		GL_INVALID_VALUE, RC_RET_VOID);

	TextureFormat transferFmt = glu::mapGLTransferFormat(format, type);
	RC_IF_ERROR(transferFmt.order	== TextureFormat::CHANNELORDER_LAST ||
				transferFmt.type	== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);

	ConstPixelBufferAccess src = getUnpack3DAccess(transferFmt, width, height, depth, getPixelUnpackPtr(data));

	if (target == GL_TEXTURE_1D && glu::isContextTypeGLCore(m_limits.contextType))
	{
		Texture1D& texture = unit.tex1DBinding ? *unit.tex1DBinding : unit.default1DTex;

		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);

		PixelBufferAccess dst = texture.getLevel(level);

		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
					yoffset + height	> dst.getHeight()	||
					zoffset + depth		> dst.getDepth(),
					GL_INVALID_VALUE, RC_RET_VOID);

		// depth components are limited to [0,1] range
		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
		else
			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
	}
	else if (target == GL_TEXTURE_2D)
	{
		Texture2D& texture = unit.tex2DBinding ? *unit.tex2DBinding : unit.default2DTex;

		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);

		PixelBufferAccess dst = texture.getLevel(level);

		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
					yoffset + height	> dst.getHeight()	||
					zoffset + depth		> dst.getDepth(),
					GL_INVALID_VALUE, RC_RET_VOID);

		// depth components are limited to [0,1] range
		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
		else
			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
	}
	else if (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ||
			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z)
	{
		TextureCube&	texture		= unit.texCubeBinding ? *unit.texCubeBinding : unit.defaultCubeTex;
		tcu::CubeFace	face		= mapGLCubeFace(target);

		RC_IF_ERROR(!texture.hasFace(level, face), GL_INVALID_VALUE, RC_RET_VOID);

		PixelBufferAccess dst = texture.getFace(level, face);

		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
					yoffset + height	> dst.getHeight()	||
					zoffset + depth		> dst.getDepth(),
					GL_INVALID_VALUE, RC_RET_VOID);

		// depth components are limited to [0,1] range
		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
		else
			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
	}
	else if (target == GL_TEXTURE_3D)
	{
		Texture3D& texture = unit.tex3DBinding ? *unit.tex3DBinding : unit.default3DTex;

		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);

		PixelBufferAccess dst = texture.getLevel(level);

		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
					yoffset + height	> dst.getHeight()	||
					zoffset + depth		> dst.getDepth(),
					GL_INVALID_VALUE, RC_RET_VOID);

		// depth components are limited to [0,1] range
		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
		else
			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
	}
	else if (target == GL_TEXTURE_2D_ARRAY)
	{
		Texture2DArray& texture = unit.tex2DArrayBinding ? *unit.tex2DArrayBinding : unit.default2DArrayTex;

		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);

		PixelBufferAccess dst = texture.getLevel(level);

		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
					yoffset + height	> dst.getHeight()	||
					zoffset + depth		> dst.getDepth(),
					GL_INVALID_VALUE, RC_RET_VOID);

		// depth components are limited to [0,1] range
		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
		else
			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
	}
	else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
	{
		TextureCubeArray& texture = unit.texCubeArrayBinding ? *unit.texCubeArrayBinding : unit.defaultCubeArrayTex;

		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);

		PixelBufferAccess dst = texture.getLevel(level);

		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
					yoffset + height	> dst.getHeight()	||
					zoffset + depth		> dst.getDepth(),
					GL_INVALID_VALUE, RC_RET_VOID);

		// depth components are limited to [0,1] range
		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
		else
			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
	}
	else
		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
}

void ReferenceContext::copyTexImage1D (deUint32 target, int level, deUint32 internalFormat, int x, int y, int width, int border)
{
	TextureUnit&							unit		= m_textureUnits[m_activeTexture];
	TextureFormat							storageFmt;
	rr::MultisampleConstPixelBufferAccess	src			= getReadColorbuffer();

	RC_IF_ERROR(border != 0, GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(width < 0 || level < 0, GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(isEmpty(src), GL_INVALID_OPERATION, RC_RET_VOID);

	// Map storage format.
	storageFmt = mapInternalFormat(internalFormat);
	RC_IF_ERROR(storageFmt.order	== TextureFormat::CHANNELORDER_LAST ||
				storageFmt.type		== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);

	if (target == GL_TEXTURE_1D)
	{
		// Validate size and level.
		RC_IF_ERROR(width > m_limits.maxTexture2DSize, GL_INVALID_VALUE, RC_RET_VOID);
		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);

		Texture1D* texture = unit.tex1DBinding ? unit.tex1DBinding : &unit.default1DTex;

		if (texture->isImmutable())
		{
			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);

			ConstPixelBufferAccess dst(texture->getLevel(level));
			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
						width		!= dst.getWidth(), GL_INVALID_OPERATION, RC_RET_VOID);
		}
		else
			texture->allocLevel(level, storageFmt, width);

		// Copy from current framebuffer.
		PixelBufferAccess dst = texture->getLevel(level);
		for (int xo = 0; xo < width; xo++)
		{
			if (!de::inBounds(x+xo, 0, src.raw().getHeight()))
				continue; // Undefined pixel.

			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y), xo, 0);
		}
	}
	else
		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
}

void ReferenceContext::copyTexImage2D (deUint32 target, int level, deUint32 internalFormat, int x, int y, int width, int height, int border)
{
	TextureUnit&							unit		= m_textureUnits[m_activeTexture];
	TextureFormat							storageFmt;
	rr::MultisampleConstPixelBufferAccess	src			= getReadColorbuffer();

	RC_IF_ERROR(border != 0, GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(width < 0 || height < 0 || level < 0, GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(isEmpty(src), GL_INVALID_OPERATION, RC_RET_VOID);

	// Map storage format.
	storageFmt = mapInternalFormat(internalFormat);
	RC_IF_ERROR(storageFmt.order	== TextureFormat::CHANNELORDER_LAST ||
				storageFmt.type		== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);

	if (target == GL_TEXTURE_2D)
	{
		// Validate size and level.
		RC_IF_ERROR(width > m_limits.maxTexture2DSize || height > m_limits.maxTexture2DSize, GL_INVALID_VALUE, RC_RET_VOID);
		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);

		Texture2D* texture = unit.tex2DBinding ? unit.tex2DBinding : &unit.default2DTex;

		if (texture->isImmutable())
		{
			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);

			ConstPixelBufferAccess dst(texture->getLevel(level));
			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
						width		!= dst.getWidth()	||
						height		!= dst.getHeight(), GL_INVALID_OPERATION, RC_RET_VOID);
		}
		else
			texture->allocLevel(level, storageFmt, width, height);

		// Copy from current framebuffer.
		PixelBufferAccess dst = texture->getLevel(level);
		for (int yo = 0; yo < height; yo++)
		for (int xo = 0; xo < width; xo++)
		{
			if (!de::inBounds(x+xo, 0, src.raw().getHeight()) || !de::inBounds(y+yo, 0, src.raw().getDepth()))
				continue; // Undefined pixel.

			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y+yo), xo, yo);
		}
	}
	else if (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ||
			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z)
	{
		// Validate size and level.
		RC_IF_ERROR(width != height || width > m_limits.maxTextureCubeSize, GL_INVALID_VALUE, RC_RET_VOID);
		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTextureCubeSize), GL_INVALID_VALUE, RC_RET_VOID);

		TextureCube*	texture	= unit.texCubeBinding ? unit.texCubeBinding : &unit.defaultCubeTex;
		tcu::CubeFace	face	= mapGLCubeFace(target);

		if (texture->isImmutable())
		{
			RC_IF_ERROR(!texture->hasFace(level, face), GL_INVALID_OPERATION, RC_RET_VOID);

			ConstPixelBufferAccess dst(texture->getFace(level, face));
			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
						width		!= dst.getWidth()	||
						height		!= dst.getHeight(), GL_INVALID_OPERATION, RC_RET_VOID);
		}
		else
			texture->allocFace(level, face, storageFmt, width, height);

		// Copy from current framebuffer.
		PixelBufferAccess dst = texture->getFace(level, face);
		for (int yo = 0; yo < height; yo++)
		for (int xo = 0; xo < width; xo++)
		{
			if (!de::inBounds(x+xo, 0, src.raw().getHeight()) || !de::inBounds(y+yo, 0, src.raw().getDepth()))
				continue; // Undefined pixel.

			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y+yo), xo, yo);
		}
	}
	else
		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
}

void ReferenceContext::copyTexSubImage1D (deUint32 target, int level, int xoffset, int x, int y, int width)
{
	TextureUnit&							unit	= m_textureUnits[m_activeTexture];
	rr::MultisampleConstPixelBufferAccess	src		= getReadColorbuffer();

	RC_IF_ERROR(xoffset < 0,	GL_INVALID_VALUE,		RC_RET_VOID);
	RC_IF_ERROR(width < 0,		GL_INVALID_VALUE,		RC_RET_VOID);
	RC_IF_ERROR(isEmpty(src),	GL_INVALID_OPERATION,	RC_RET_VOID);

	if (target == GL_TEXTURE_1D)
	{
		Texture1D& texture = unit.tex1DBinding ? *unit.tex1DBinding : unit.default1DTex;

		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);

		PixelBufferAccess dst = texture.getLevel(level);

		RC_IF_ERROR(xoffset + width > dst.getWidth(), GL_INVALID_VALUE, RC_RET_VOID);

		for (int xo = 0; xo < width; xo++)
		{
			if (!de::inBounds(x+xo, 0, src.raw().getHeight()))
				continue;

			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y), xo+xoffset, 0);
		}
	}
	else
		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
}

void ReferenceContext::copyTexSubImage2D (deUint32 target, int level, int xoffset, int yoffset, int x, int y, int width, int height)
{
	TextureUnit&							unit	= m_textureUnits[m_activeTexture];
	rr::MultisampleConstPixelBufferAccess	src		= getReadColorbuffer();

	RC_IF_ERROR(xoffset < 0 || yoffset < 0,					GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(width < 0 || height < 0,					GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(isEmpty(src),								GL_INVALID_OPERATION, RC_RET_VOID);

	if (target == GL_TEXTURE_2D)
	{
		Texture2D& texture = unit.tex2DBinding ? *unit.tex2DBinding : unit.default2DTex;

		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);

		PixelBufferAccess dst = texture.getLevel(level);

		RC_IF_ERROR(xoffset + width		> dst.getWidth() ||
					yoffset + height	> dst.getHeight(),
					GL_INVALID_VALUE, RC_RET_VOID);

		for (int yo = 0; yo < height; yo++)
		for (int xo = 0; xo < width; xo++)
		{
			if (!de::inBounds(x+xo, 0, src.raw().getHeight()) || !de::inBounds(y+yo, 0, src.raw().getDepth()))
				continue;

			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y+yo), xo+xoffset, yo+yoffset);
		}
	}
	else if (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ||
			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z)
	{
		TextureCube&	texture		= unit.texCubeBinding ? *unit.texCubeBinding : unit.defaultCubeTex;
		tcu::CubeFace	face		= mapGLCubeFace(target);

		RC_IF_ERROR(!texture.hasFace(level, face), GL_INVALID_VALUE, RC_RET_VOID);

		PixelBufferAccess dst = texture.getFace(level, face);

		RC_IF_ERROR(xoffset + width		> dst.getWidth() ||
					yoffset + height	> dst.getHeight(),
					GL_INVALID_VALUE, RC_RET_VOID);

		for (int yo = 0; yo < height; yo++)
		for (int xo = 0; xo < width; xo++)
		{
			if (!de::inBounds(x+xo, 0, src.raw().getHeight()) || !de::inBounds(y+yo, 0, src.raw().getDepth()))
				continue;

			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y+yo), xo+xoffset, yo+yoffset);
		}
	}
	else
		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
}

void ReferenceContext::copyTexSubImage3D (deUint32 target, int level, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height)
{
	DE_UNREF(target && level && xoffset && yoffset && zoffset && x && y && width && height);
	DE_ASSERT(false);
}

void ReferenceContext::texStorage2D (deUint32 target, int levels, deUint32 internalFormat, int width, int height)
{
	TextureUnit&		unit		= m_textureUnits[m_activeTexture];
	TextureFormat		storageFmt;

	RC_IF_ERROR(width <= 0 || height <= 0, GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(!de::inRange(levels, 1, (int)deLog2Floor32(de::max(width, height))+1), GL_INVALID_VALUE, RC_RET_VOID);

	// Map storage format.
	storageFmt = mapInternalFormat(internalFormat);
	RC_IF_ERROR(storageFmt.order	== TextureFormat::CHANNELORDER_LAST ||
				storageFmt.type		== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);

	if (target == GL_TEXTURE_2D)
	{
		Texture2D& texture = unit.tex2DBinding ? *unit.tex2DBinding : unit.default2DTex;

		RC_IF_ERROR(width > m_limits.maxTexture2DSize || height >= m_limits.maxTexture2DSize, GL_INVALID_VALUE, RC_RET_VOID);
		RC_IF_ERROR(texture.isImmutable(), GL_INVALID_OPERATION, RC_RET_VOID);

		texture.clearLevels();
		texture.setImmutable();

		for (int level = 0; level < levels; level++)
		{
			int levelW = de::max(1, width >> level);
			int levelH = de::max(1, height >> level);

			texture.allocLevel(level, storageFmt, levelW, levelH);
		}
	}
	else if (target == GL_TEXTURE_CUBE_MAP)
	{
		TextureCube& texture = unit.texCubeBinding ? *unit.texCubeBinding : unit.defaultCubeTex;

		RC_IF_ERROR(width > m_limits.maxTextureCubeSize || height > m_limits.maxTextureCubeSize, GL_INVALID_VALUE, RC_RET_VOID);
		RC_IF_ERROR(texture.isImmutable(), GL_INVALID_OPERATION, RC_RET_VOID);

		texture.clearLevels();
		texture.setImmutable();

		for (int level = 0; level < levels; level++)
		{
			int levelW = de::max(1, width >> level);
			int levelH = de::max(1, height >> level);

			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
				texture.allocFace(level, (tcu::CubeFace)face, storageFmt, levelW, levelH);
		}
	}
	else
		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
}

void ReferenceContext::texStorage3D (deUint32 target, int levels, deUint32 internalFormat, int width, int height, int depth)
{
	TextureUnit&		unit		= m_textureUnits[m_activeTexture];
	TextureFormat		storageFmt;

	RC_IF_ERROR(width <= 0 || height <= 0, GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(!de::inRange(levels, 1, (int)deLog2Floor32(de::max(width, height))+1), GL_INVALID_VALUE, RC_RET_VOID);

	// Map storage format.
	storageFmt = mapInternalFormat(internalFormat);
	RC_IF_ERROR(storageFmt.order	== TextureFormat::CHANNELORDER_LAST ||
				storageFmt.type		== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);

	if (target == GL_TEXTURE_2D_ARRAY)
	{
		Texture2DArray& texture = unit.tex2DArrayBinding ? *unit.tex2DArrayBinding : unit.default2DArrayTex;

		RC_IF_ERROR(width	>	m_limits.maxTexture2DSize	||
					height	>=	m_limits.maxTexture2DSize	||
					depth	>=	m_limits.maxTexture2DArrayLayers, GL_INVALID_VALUE, RC_RET_VOID);
		RC_IF_ERROR(texture.isImmutable(), GL_INVALID_OPERATION, RC_RET_VOID);

		texture.clearLevels();
		texture.setImmutable();

		for (int level = 0; level < levels; level++)
		{
			int levelW = de::max(1, width >> level);
			int levelH = de::max(1, height >> level);

			texture.allocLevel(level, storageFmt, levelW, levelH, depth);
		}
	}
	else if (target == GL_TEXTURE_3D)
	{
		Texture3D& texture = unit.tex3DBinding ? *unit.tex3DBinding : unit.default3DTex;

		RC_IF_ERROR(width	> m_limits.maxTexture3DSize	||
					height	> m_limits.maxTexture3DSize	||
					depth	> m_limits.maxTexture3DSize, GL_INVALID_VALUE, RC_RET_VOID);
		RC_IF_ERROR(texture.isImmutable(), GL_INVALID_OPERATION, RC_RET_VOID);

		texture.clearLevels();
		texture.setImmutable();

		for (int level = 0; level < levels; level++)
		{
			int levelW = de::max(1, width		>> level);
			int levelH = de::max(1, height	>> level);
			int levelD = de::max(1, depth		>> level);

			texture.allocLevel(level, storageFmt, levelW, levelH, levelD);
		}
	}
	else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
	{
		TextureCubeArray& texture = unit.texCubeArrayBinding ? *unit.texCubeArrayBinding : unit.defaultCubeArrayTex;

		RC_IF_ERROR(width		!=	height								||
					depth % 6	!= 0									||
					width		>	m_limits.maxTexture2DSize			||
					depth		>=	m_limits.maxTexture2DArrayLayers, GL_INVALID_VALUE, RC_RET_VOID);
		RC_IF_ERROR(texture.isImmutable(), GL_INVALID_OPERATION, RC_RET_VOID);

		texture.clearLevels();
		texture.setImmutable();

		for (int level = 0; level < levels; level++)
		{
			int levelW = de::max(1, width >> level);
			int levelH = de::max(1, height >> level);

			texture.allocLevel(level, storageFmt, levelW, levelH, depth);
		}
	}
	else
		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
}

// \todo [2014-02-19 pyry] Duplicated with code in gluTextureUtil.hpp

static inline tcu::Sampler::WrapMode mapGLWrapMode (int value)
{
	switch (value)
	{
		case GL_CLAMP_TO_EDGE:		return tcu::Sampler::CLAMP_TO_EDGE;
		case GL_REPEAT:				return tcu::Sampler::REPEAT_GL;
		case GL_MIRRORED_REPEAT:	return tcu::Sampler::MIRRORED_REPEAT_GL;
		default:					return tcu::Sampler::WRAPMODE_LAST;
	}
}

static inline tcu::Sampler::FilterMode mapGLFilterMode (int value)
{
	switch (value)
	{
		case GL_NEAREST:				return tcu::Sampler::NEAREST;
		case GL_LINEAR:					return tcu::Sampler::LINEAR;
		case GL_NEAREST_MIPMAP_NEAREST:	return tcu::Sampler::NEAREST_MIPMAP_NEAREST;
		case GL_NEAREST_MIPMAP_LINEAR:	return tcu::Sampler::NEAREST_MIPMAP_LINEAR;
		case GL_LINEAR_MIPMAP_NEAREST:	return tcu::Sampler::LINEAR_MIPMAP_NEAREST;
		case GL_LINEAR_MIPMAP_LINEAR:	return tcu::Sampler::LINEAR_MIPMAP_LINEAR;
		default:						return tcu::Sampler::FILTERMODE_LAST;
	}
}

void ReferenceContext::texParameteri (deUint32 target, deUint32 pname, int value)
{
	TextureUnit&	unit		= m_textureUnits[m_activeTexture];
	Texture*		texture		= DE_NULL;

	switch (target)
	{
		case GL_TEXTURE_1D:				texture = unit.tex1DBinding			? unit.tex1DBinding			: &unit.default1DTex;			break;
		case GL_TEXTURE_2D:				texture = unit.tex2DBinding			? unit.tex2DBinding			: &unit.default2DTex;			break;
		case GL_TEXTURE_CUBE_MAP:		texture = unit.texCubeBinding		? unit.texCubeBinding		: &unit.defaultCubeTex;			break;
		case GL_TEXTURE_2D_ARRAY:		texture = unit.tex2DArrayBinding	? unit.tex2DArrayBinding	: &unit.default2DArrayTex;		break;
		case GL_TEXTURE_3D:				texture = unit.tex3DBinding			? unit.tex3DBinding			: &unit.default3DTex;			break;
		case GL_TEXTURE_CUBE_MAP_ARRAY:	texture = unit.texCubeArrayBinding	? unit.texCubeArrayBinding	: &unit.defaultCubeArrayTex;	break;

		default:					RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
	}

	switch (pname)
	{
		case GL_TEXTURE_WRAP_S:
		{
			tcu::Sampler::WrapMode wrapS = mapGLWrapMode(value);
			RC_IF_ERROR(wrapS == tcu::Sampler::WRAPMODE_LAST, GL_INVALID_VALUE, RC_RET_VOID);
			texture->getSampler().wrapS = wrapS;
			break;
		}

		case GL_TEXTURE_WRAP_T:
		{
			tcu::Sampler::WrapMode wrapT = mapGLWrapMode(value);
			RC_IF_ERROR(wrapT == tcu::Sampler::WRAPMODE_LAST, GL_INVALID_VALUE, RC_RET_VOID);
			texture->getSampler().wrapT = wrapT;
			break;
		}

		case GL_TEXTURE_WRAP_R:
		{
			tcu::Sampler::WrapMode wrapR = mapGLWrapMode(value);
			RC_IF_ERROR(wrapR == tcu::Sampler::WRAPMODE_LAST, GL_INVALID_VALUE, RC_RET_VOID);
			texture->getSampler().wrapR = wrapR;
			break;
		}

		case GL_TEXTURE_MIN_FILTER:
		{
			tcu::Sampler::FilterMode minMode = mapGLFilterMode(value);
			RC_IF_ERROR(minMode == tcu::Sampler::FILTERMODE_LAST, GL_INVALID_VALUE, RC_RET_VOID);
			texture->getSampler().minFilter = minMode;
			break;
		}

		case GL_TEXTURE_MAG_FILTER:
		{
			tcu::Sampler::FilterMode magMode = mapGLFilterMode(value);
			RC_IF_ERROR(magMode != tcu::Sampler::LINEAR && magMode != tcu::Sampler::NEAREST,
						GL_INVALID_VALUE, RC_RET_VOID);
			texture->getSampler().magFilter = magMode;
			break;
		}

		case GL_TEXTURE_MAX_LEVEL:
		{
			RC_IF_ERROR(value < 0, GL_INVALID_VALUE, RC_RET_VOID);
			texture->setMaxLevel(value);
			break;
		}

		default:
			RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
	}
}

static inline Framebuffer::AttachmentPoint mapGLAttachmentPoint (deUint32 attachment)
{
	switch (attachment)
	{
		case GL_COLOR_ATTACHMENT0:	return Framebuffer::ATTACHMENTPOINT_COLOR0;
		case GL_DEPTH_ATTACHMENT:	return Framebuffer::ATTACHMENTPOINT_DEPTH;
		case GL_STENCIL_ATTACHMENT:	return Framebuffer::ATTACHMENTPOINT_STENCIL;
		default:					return Framebuffer::ATTACHMENTPOINT_LAST;
	}
}

static inline Framebuffer::TexTarget mapGLFboTexTarget (deUint32 target)
{
	switch (target)
	{
		case GL_TEXTURE_2D:						return Framebuffer::TEXTARGET_2D;
		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:	return Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_X;
		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:	return Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_Y;
		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:	return Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_Z;
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:	return Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_X;
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:	return Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Y;
		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:	return Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Z;
		default:								return Framebuffer::TEXTARGET_LAST;
	}
}

void ReferenceContext::acquireFboAttachmentReference (const Framebuffer::Attachment& attachment)
{
	switch (attachment.type)
	{
		case Framebuffer::ATTACHMENTTYPE_TEXTURE:
		{
			TCU_CHECK(attachment.name != 0);
			Texture* texture = m_textures.find(attachment.name);
			TCU_CHECK(texture);
			m_textures.acquireReference(texture);
			break;
		}

		case Framebuffer::ATTACHMENTTYPE_RENDERBUFFER:
		{
			TCU_CHECK(attachment.name != 0);
			Renderbuffer* rbo = m_renderbuffers.find(attachment.name);
			TCU_CHECK(rbo);
			m_renderbuffers.acquireReference(rbo);
			break;
		}

		default:
			break; // Silently ignore
	}
}

void ReferenceContext::releaseFboAttachmentReference (const Framebuffer::Attachment& attachment)
{
	switch (attachment.type)
	{
		case Framebuffer::ATTACHMENTTYPE_TEXTURE:
		{
			TCU_CHECK(attachment.name != 0);
			Texture* texture = m_textures.find(attachment.name);
			TCU_CHECK(texture);
			m_textures.releaseReference(texture);
			break;
		}

		case Framebuffer::ATTACHMENTTYPE_RENDERBUFFER:
		{
			TCU_CHECK(attachment.name != 0);
			Renderbuffer* rbo = m_renderbuffers.find(attachment.name);
			TCU_CHECK(rbo);
			m_renderbuffers.releaseReference(rbo);
			break;
		}

		default:
			break; // Silently ignore
	}
}

void ReferenceContext::framebufferTexture2D (deUint32 target, deUint32 attachment, deUint32 textarget, deUint32 texture, int level)
{
	if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
	{
		// Attach to both depth and stencil.
		framebufferTexture2D(target, GL_DEPTH_ATTACHMENT,	textarget, texture, level);
		framebufferTexture2D(target, GL_STENCIL_ATTACHMENT,	textarget, texture, level);
	}
	else
	{
		Framebuffer::AttachmentPoint	point			= mapGLAttachmentPoint(attachment);
		Texture*						texObj			= DE_NULL;
		Framebuffer::TexTarget			fboTexTarget	= mapGLFboTexTarget(textarget);

		RC_IF_ERROR(target != GL_FRAMEBUFFER		&&
					target != GL_DRAW_FRAMEBUFFER	&&
					target != GL_READ_FRAMEBUFFER,				GL_INVALID_ENUM,		RC_RET_VOID);
		RC_IF_ERROR(point == Framebuffer::ATTACHMENTPOINT_LAST,	GL_INVALID_ENUM,		RC_RET_VOID);

		// Select binding point.
		rc::Framebuffer* framebufferBinding = (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) ? m_drawFramebufferBinding : m_readFramebufferBinding;
		RC_IF_ERROR(!framebufferBinding, GL_INVALID_OPERATION, RC_RET_VOID);

		// If framebuffer object is bound for both reading and writing then we need to acquire/release multiple references.
		int bindingRefCount = (framebufferBinding == m_drawFramebufferBinding ? 1 : 0)
							+ (framebufferBinding == m_readFramebufferBinding ? 1 : 0);

		if (texture != 0)
		{
			texObj = m_textures.find(texture);

			RC_IF_ERROR(!texObj,		GL_INVALID_OPERATION,	RC_RET_VOID);
			RC_IF_ERROR(level != 0,		GL_INVALID_VALUE,		RC_RET_VOID); // \todo [2012-03-19 pyry] We should allow other levels as well.

			if (texObj->getType() == Texture::TYPE_2D)
				RC_IF_ERROR(fboTexTarget != Framebuffer::TEXTARGET_2D, GL_INVALID_OPERATION, RC_RET_VOID);
			else
			{
				TCU_CHECK(texObj->getType() == Texture::TYPE_CUBE_MAP);
				if (!deInRange32(fboTexTarget, Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_X, Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Z))
					RC_ERROR_RET(GL_INVALID_OPERATION, RC_RET_VOID);
			}
		}

		Framebuffer::Attachment& fboAttachment = framebufferBinding->getAttachment(point);
		for (int ndx = 0; ndx < bindingRefCount; ndx++)
			releaseFboAttachmentReference(fboAttachment);
		fboAttachment = Framebuffer::Attachment();

		if (texObj)
		{
			fboAttachment.type			= Framebuffer::ATTACHMENTTYPE_TEXTURE;
			fboAttachment.name			= texObj->getName();
			fboAttachment.texTarget		= fboTexTarget;
			fboAttachment.level			= level;

			for (int ndx = 0; ndx < bindingRefCount; ndx++)
				acquireFboAttachmentReference(fboAttachment);
		}
	}
}

void ReferenceContext::framebufferTextureLayer (deUint32 target, deUint32 attachment, deUint32 texture, int level, int layer)
{
	if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
	{
		// Attach to both depth and stencil.
		framebufferTextureLayer(target, GL_DEPTH_ATTACHMENT,	texture, level, layer);
		framebufferTextureLayer(target, GL_STENCIL_ATTACHMENT,	texture, level, layer);
	}
	else
	{
		Framebuffer::AttachmentPoint	point			= mapGLAttachmentPoint(attachment);
		Texture*						texObj			= DE_NULL;

		RC_IF_ERROR(target != GL_FRAMEBUFFER		&&
					target != GL_DRAW_FRAMEBUFFER	&&
					target != GL_READ_FRAMEBUFFER,				GL_INVALID_ENUM,		RC_RET_VOID);
		RC_IF_ERROR(point == Framebuffer::ATTACHMENTPOINT_LAST,	GL_INVALID_ENUM,		RC_RET_VOID);

		// Select binding point.
		rc::Framebuffer* framebufferBinding = (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) ? m_drawFramebufferBinding : m_readFramebufferBinding;
		RC_IF_ERROR(!framebufferBinding, GL_INVALID_OPERATION, RC_RET_VOID);

		// If framebuffer object is bound for both reading and writing then we need to acquire/release multiple references.
		int bindingRefCount = (framebufferBinding == m_drawFramebufferBinding ? 1 : 0)
							+ (framebufferBinding == m_readFramebufferBinding ? 1 : 0);

		if (texture != 0)
		{
			texObj = m_textures.find(texture);

			RC_IF_ERROR(!texObj,		GL_INVALID_OPERATION,	RC_RET_VOID);
			RC_IF_ERROR(level != 0,		GL_INVALID_VALUE,		RC_RET_VOID); // \todo [2012-03-19 pyry] We should allow other levels as well.

			RC_IF_ERROR(texObj->getType() != Texture::TYPE_2D_ARRAY			&&
						texObj->getType() != Texture::TYPE_3D				&&
						texObj->getType() != Texture::TYPE_CUBE_MAP_ARRAY,				GL_INVALID_OPERATION,	RC_RET_VOID);

			if (texObj->getType() == Texture::TYPE_2D_ARRAY || texObj->getType() == Texture::TYPE_CUBE_MAP_ARRAY)
			{
				RC_IF_ERROR((layer < 0) || (layer >= GL_MAX_ARRAY_TEXTURE_LAYERS),		GL_INVALID_VALUE,		RC_RET_VOID);
				RC_IF_ERROR((level < 0) || (level > deLog2Floor32(GL_MAX_TEXTURE_SIZE)),GL_INVALID_VALUE,		RC_RET_VOID);
			}
			else if	(texObj->getType() == Texture::TYPE_3D)
			{
				RC_IF_ERROR((layer < 0) || (layer >= GL_MAX_3D_TEXTURE_SIZE),				GL_INVALID_VALUE,		RC_RET_VOID);
				RC_IF_ERROR((level < 0) || (level > deLog2Floor32(GL_MAX_3D_TEXTURE_SIZE)),	GL_INVALID_VALUE,		RC_RET_VOID);
			}
		}

		Framebuffer::Attachment& fboAttachment = framebufferBinding->getAttachment(point);
		for (int ndx = 0; ndx < bindingRefCount; ndx++)
			releaseFboAttachmentReference(fboAttachment);
		fboAttachment = Framebuffer::Attachment();

		if (texObj)
		{
			fboAttachment.type			= Framebuffer::ATTACHMENTTYPE_TEXTURE;
			fboAttachment.name			= texObj->getName();
			fboAttachment.texTarget		= texLayeredTypeToTarget(texObj->getType());
			fboAttachment.level			= level;
			fboAttachment.layer			= layer;

			DE_ASSERT(fboAttachment.texTarget != Framebuffer::TEXTARGET_LAST);

			for (int ndx = 0; ndx < bindingRefCount; ndx++)
				acquireFboAttachmentReference(fboAttachment);
		}
	}
}

void ReferenceContext::framebufferRenderbuffer (deUint32 target, deUint32 attachment, deUint32 renderbuffertarget, deUint32 renderbuffer)
{
	if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
	{
		// Attach both to depth and stencil.
		framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT,	renderbuffertarget, renderbuffer);
		framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT,	renderbuffertarget, renderbuffer);
	}
	else
	{
		Framebuffer::AttachmentPoint	point			= mapGLAttachmentPoint(attachment);
		Renderbuffer*					rbo				= DE_NULL;

		RC_IF_ERROR(target != GL_FRAMEBUFFER		&&
					target != GL_DRAW_FRAMEBUFFER	&&
					target != GL_READ_FRAMEBUFFER,				GL_INVALID_ENUM,		RC_RET_VOID);
		RC_IF_ERROR(point == Framebuffer::ATTACHMENTPOINT_LAST,	GL_INVALID_ENUM,		RC_RET_VOID);

		// Select binding point.
		rc::Framebuffer* framebufferBinding = (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) ? m_drawFramebufferBinding : m_readFramebufferBinding;
		RC_IF_ERROR(!framebufferBinding, GL_INVALID_OPERATION, RC_RET_VOID);

		// If framebuffer object is bound for both reading and writing then we need to acquire/release multiple references.
		int bindingRefCount = (framebufferBinding == m_drawFramebufferBinding ? 1 : 0)
							+ (framebufferBinding == m_readFramebufferBinding ? 1 : 0);

		if (renderbuffer != 0)
		{
			rbo = m_renderbuffers.find(renderbuffer);

			RC_IF_ERROR(renderbuffertarget != GL_RENDERBUFFER,	GL_INVALID_ENUM,		RC_RET_VOID);
			RC_IF_ERROR(!rbo,									GL_INVALID_OPERATION,	RC_RET_VOID);
		}

		Framebuffer::Attachment& fboAttachment = framebufferBinding->getAttachment(point);
		for (int ndx = 0; ndx < bindingRefCount; ndx++)
			releaseFboAttachmentReference(fboAttachment);
		fboAttachment = Framebuffer::Attachment();

		if (rbo)
		{
			fboAttachment.type	= Framebuffer::ATTACHMENTTYPE_RENDERBUFFER;
			fboAttachment.name	= rbo->getName();

			for (int ndx = 0; ndx < bindingRefCount; ndx++)
				acquireFboAttachmentReference(fboAttachment);
		}
	}
}

deUint32 ReferenceContext::checkFramebufferStatus (deUint32 target)
{
	RC_IF_ERROR(target != GL_FRAMEBUFFER		&&
				target != GL_DRAW_FRAMEBUFFER	&&
				target != GL_READ_FRAMEBUFFER, GL_INVALID_ENUM, 0);

	// Select binding point.
	rc::Framebuffer* framebufferBinding = (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) ? m_drawFramebufferBinding : m_readFramebufferBinding;

	// Default framebuffer is always complete.
	if (!framebufferBinding)
		return GL_FRAMEBUFFER_COMPLETE;

	int		width				= -1;
	int		height				= -1;
	bool	hasAttachment		= false;
	bool	attachmentComplete	= true;
	bool	dimensionsOk		= true;

	for (int point = 0; point < Framebuffer::ATTACHMENTPOINT_LAST; point++)
	{
		const Framebuffer::Attachment&	attachment			= framebufferBinding->getAttachment((Framebuffer::AttachmentPoint)point);
		int								attachmentWidth		= 0;
		int								attachmentHeight	= 0;
		tcu::TextureFormat				attachmentFormat;

		if (attachment.type == Framebuffer::ATTACHMENTTYPE_TEXTURE)
		{
			const Texture*					texture	= m_textures.find(attachment.name);
			tcu::ConstPixelBufferAccess		level;
			TCU_CHECK(texture);

			if (attachment.texTarget == Framebuffer::TEXTARGET_2D)
			{
				DE_ASSERT(texture->getType() == Texture::TYPE_2D);
				const Texture2D* tex2D = static_cast<const Texture2D*>(texture);

				if (tex2D->hasLevel(attachment.level))
					level = tex2D->getLevel(attachment.level);
			}
			else if (deInRange32(attachment.texTarget, Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_X,
													   Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Z))
			{
				DE_ASSERT(texture->getType() == Texture::TYPE_CUBE_MAP);

				const TextureCube*	texCube	= static_cast<const TextureCube*>(texture);
				const tcu::CubeFace	face	= texTargetToFace(attachment.texTarget);
				TCU_CHECK(de::inBounds<int>(face, 0, tcu::CUBEFACE_LAST));

				if (texCube->hasFace(attachment.level, face))
					level = texCube->getFace(attachment.level, face);
			}
			else if (attachment.texTarget == Framebuffer::TEXTARGET_2D_ARRAY)
			{
				DE_ASSERT(texture->getType() == Texture::TYPE_2D_ARRAY);
				const Texture2DArray* tex2DArr = static_cast<const Texture2DArray*>(texture);

				if (tex2DArr->hasLevel(attachment.level))
					level = tex2DArr->getLevel(attachment.level); // \note Slice doesn't matter here.
			}
			else if (attachment.texTarget == Framebuffer::TEXTARGET_3D)
			{
				DE_ASSERT(texture->getType() == Texture::TYPE_3D);
				const Texture3D* tex3D = static_cast<const Texture3D*>(texture);

				if (tex3D->hasLevel(attachment.level))
					level = tex3D->getLevel(attachment.level); // \note Slice doesn't matter here.
			}
			else if (attachment.texTarget == Framebuffer::TEXTARGET_CUBE_MAP_ARRAY)
			{
				DE_ASSERT(texture->getType() == Texture::TYPE_CUBE_MAP_ARRAY);
				const TextureCubeArray* texCubeArr = static_cast<const TextureCubeArray*>(texture);

				if (texCubeArr->hasLevel(attachment.level))
					level = texCubeArr->getLevel(attachment.level); // \note Slice doesn't matter here.
			}
			else
				TCU_FAIL("Framebuffer attached to a texture but no valid target specified");

			attachmentWidth		= level.getWidth();
			attachmentHeight	= level.getHeight();
			attachmentFormat	= level.getFormat();
		}
		else if (attachment.type == Framebuffer::ATTACHMENTTYPE_RENDERBUFFER)
		{
			const Renderbuffer* renderbuffer = m_renderbuffers.find(attachment.name);
			TCU_CHECK(renderbuffer);

			attachmentWidth		= renderbuffer->getWidth();
			attachmentHeight	= renderbuffer->getHeight();
			attachmentFormat	= renderbuffer->getFormat();
		}
		else
		{
			TCU_CHECK(attachment.type == Framebuffer::ATTACHMENTTYPE_LAST);
			continue; // Skip rest of checks.
		}

		if (!hasAttachment && attachmentWidth > 0 && attachmentHeight > 0)
		{
			width			= attachmentWidth;
			height			= attachmentHeight;
			hasAttachment	= true;
		}
		else if (attachmentWidth != width || attachmentHeight != height)
			dimensionsOk = false;

		// Validate attachment point compatibility.
		switch (attachmentFormat.order)
		{
			case TextureFormat::R:
			case TextureFormat::RG:
			case TextureFormat::RGB:
			case TextureFormat::RGBA:
			case TextureFormat::sRGB:
			case TextureFormat::sRGBA:
				if (point != Framebuffer::ATTACHMENTPOINT_COLOR0)
					attachmentComplete = false;
				break;

			case TextureFormat::D:
				if (point != Framebuffer::ATTACHMENTPOINT_DEPTH)
					attachmentComplete = false;
				break;

			case TextureFormat::S:
				if (point != Framebuffer::ATTACHMENTPOINT_STENCIL)
					attachmentComplete = false;
				break;

			case TextureFormat::DS:
				if (point != Framebuffer::ATTACHMENTPOINT_DEPTH &&
					point != Framebuffer::ATTACHMENTPOINT_STENCIL)
					attachmentComplete = false;
				break;

			default:
				TCU_FAIL("Unsupported attachment channel order");
		}
	}

	if (!attachmentComplete)
		return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
	else if (!hasAttachment)
		return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
	else if (!dimensionsOk)
		return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
	else
		return GL_FRAMEBUFFER_COMPLETE;
}

void ReferenceContext::getFramebufferAttachmentParameteriv (deUint32 target, deUint32 attachment, deUint32 pname, int* params)
{
	DE_UNREF(target && attachment && pname && params);
	TCU_CHECK(false); // \todo [pyry] Implement
}

void ReferenceContext::renderbufferStorage (deUint32 target, deUint32 internalformat, int width, int height)
{
	TextureFormat format = glu::mapGLInternalFormat(internalformat);

	RC_IF_ERROR(target != GL_RENDERBUFFER, GL_INVALID_ENUM, RC_RET_VOID);
	RC_IF_ERROR(!m_renderbufferBinding, GL_INVALID_OPERATION, RC_RET_VOID);
	RC_IF_ERROR(!deInRange32(width, 0, m_limits.maxRenderbufferSize) ||
				!deInRange32(height, 0, m_limits.maxRenderbufferSize),
				GL_INVALID_OPERATION, RC_RET_VOID);
	RC_IF_ERROR(format.order == TextureFormat::CHANNELORDER_LAST ||
				format.type == TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);

	m_renderbufferBinding->setStorage(format, (int)width, (int)height);
}

void ReferenceContext::renderbufferStorageMultisample (deUint32 target, int samples, deUint32 internalFormat, int width, int height)
{
	// \todo [2012-04-07 pyry] Implement MSAA support.
	DE_UNREF(samples);
	renderbufferStorage(target, internalFormat, width, height);
}

tcu::PixelBufferAccess ReferenceContext::getFboAttachment (const rc::Framebuffer& framebuffer, rc::Framebuffer::AttachmentPoint point)
{
	const Framebuffer::Attachment& attachment = framebuffer.getAttachment(point);

	switch (attachment.type)
	{
		case Framebuffer::ATTACHMENTTYPE_TEXTURE:
		{
			Texture* texture = m_textures.find(attachment.name);
			TCU_CHECK(texture);

			if (texture->getType() == Texture::TYPE_2D)
			{
				if (Texture2D* texture2D = dynamic_cast<Texture2D*>(texture))
					return texture2D->getLevel(attachment.level);
				else
					return nullAccess();
			}
			else if (texture->getType() == Texture::TYPE_CUBE_MAP)
			{
				if (TextureCube* cubeMap = dynamic_cast<TextureCube*>(texture))
					return cubeMap->getFace(attachment.level, texTargetToFace(attachment.texTarget));
				else
					return nullAccess();
			}
			else if (texture->getType() == Texture::TYPE_2D_ARRAY	||
					 texture->getType() == Texture::TYPE_3D			||
					 texture->getType() == Texture::TYPE_CUBE_MAP_ARRAY)
			{
				tcu::PixelBufferAccess level;

				if (texture->getType() == Texture::TYPE_2D_ARRAY)
				{
					if (Texture2DArray* texture2DArray = dynamic_cast<Texture2DArray*>(texture))
						level = texture2DArray->getLevel(attachment.level);
				}
				else if (texture->getType() == Texture::TYPE_3D)
				{
					if (Texture3D* texture3D = dynamic_cast<Texture3D*>(texture))
						level = texture3D->getLevel(attachment.level);
				}
				else if (texture->getType() == Texture::TYPE_CUBE_MAP_ARRAY)
				{
					if (TextureCubeArray* cubeArray = dynamic_cast<TextureCubeArray*>(texture))
						level = cubeArray->getLevel(attachment.level);
				}

				void* layerData = static_cast<deUint8*>(level.getDataPtr()) + level.getSlicePitch() * attachment.layer;

				return tcu::PixelBufferAccess(level.getFormat(), level.getWidth(), level.getHeight(), 1, level.getRowPitch(), 0, layerData);
			}
			else
				return nullAccess();
		}

		case Framebuffer::ATTACHMENTTYPE_RENDERBUFFER:
		{
			Renderbuffer* rbo = m_renderbuffers.find(attachment.name);
			TCU_CHECK(rbo);

			return rbo->getAccess();
		}

		default:
			return nullAccess();
	}
}

const Texture2D& ReferenceContext::getTexture2D (int unitNdx) const
{
	const TextureUnit& unit = m_textureUnits[unitNdx];
	return unit.tex2DBinding ? *unit.tex2DBinding : unit.default2DTex;
}

const TextureCube& ReferenceContext::getTextureCube (int unitNdx) const
{
	const TextureUnit& unit = m_textureUnits[unitNdx];
	return unit.texCubeBinding ? *unit.texCubeBinding : unit.defaultCubeTex;
}

static bool isValidBufferTarget (deUint32 target)
{
	switch (target)
	{
		case GL_ARRAY_BUFFER:
		case GL_COPY_READ_BUFFER:
		case GL_COPY_WRITE_BUFFER:
		case GL_DRAW_INDIRECT_BUFFER:
		case GL_ELEMENT_ARRAY_BUFFER:
		case GL_PIXEL_PACK_BUFFER:
		case GL_PIXEL_UNPACK_BUFFER:
		case GL_TRANSFORM_FEEDBACK_BUFFER:
		case GL_UNIFORM_BUFFER:
			return true;

		default:
			return false;
	}
}

void ReferenceContext::setBufferBinding (deUint32 target, DataBuffer* buffer)
{
	DataBuffer** bindingPoint = DE_NULL;
	VertexArray* vertexArrayObject = (m_vertexArrayBinding) ? (m_vertexArrayBinding) : (&m_clientVertexArray);

	switch (target)
	{
		case GL_ARRAY_BUFFER:				bindingPoint = &m_arrayBufferBinding;								break;
		case GL_COPY_READ_BUFFER:			bindingPoint = &m_copyReadBufferBinding;							break;
		case GL_COPY_WRITE_BUFFER:			bindingPoint = &m_copyWriteBufferBinding;							break;
		case GL_DRAW_INDIRECT_BUFFER:		bindingPoint = &m_drawIndirectBufferBinding;						break;
		case GL_ELEMENT_ARRAY_BUFFER:		bindingPoint = &vertexArrayObject->m_elementArrayBufferBinding;		break;
		case GL_PIXEL_PACK_BUFFER:			bindingPoint = &m_pixelPackBufferBinding;							break;
		case GL_PIXEL_UNPACK_BUFFER:		bindingPoint = &m_pixelUnpackBufferBinding;							break;
		case GL_TRANSFORM_FEEDBACK_BUFFER:	bindingPoint = &m_transformFeedbackBufferBinding;					break;
		case GL_UNIFORM_BUFFER:				bindingPoint = &m_uniformBufferBinding;								break;
		default:
			DE_ASSERT(false);
			return;
	}

	if (*bindingPoint)
	{
		m_buffers.releaseReference(*bindingPoint);
		*bindingPoint = DE_NULL;
	}

	if (buffer)
		m_buffers.acquireReference(buffer);

	*bindingPoint = buffer;
}

DataBuffer* ReferenceContext::getBufferBinding (deUint32 target) const
{
	const VertexArray* vertexArrayObject = (m_vertexArrayBinding) ? (m_vertexArrayBinding) : (&m_clientVertexArray);

	switch (target)
	{
		case GL_ARRAY_BUFFER:				return m_arrayBufferBinding;
		case GL_COPY_READ_BUFFER:			return m_copyReadBufferBinding;
		case GL_COPY_WRITE_BUFFER:			return m_copyWriteBufferBinding;
		case GL_DRAW_INDIRECT_BUFFER:		return m_drawIndirectBufferBinding;
		case GL_ELEMENT_ARRAY_BUFFER:		return vertexArrayObject->m_elementArrayBufferBinding;
		case GL_PIXEL_PACK_BUFFER:			return m_pixelPackBufferBinding;
		case GL_PIXEL_UNPACK_BUFFER:		return m_pixelUnpackBufferBinding;
		case GL_TRANSFORM_FEEDBACK_BUFFER:	return m_transformFeedbackBufferBinding;
		case GL_UNIFORM_BUFFER:				return m_uniformBufferBinding;
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

void ReferenceContext::bindBuffer (deUint32 target, deUint32 buffer)
{
	RC_IF_ERROR(!isValidBufferTarget(target), GL_INVALID_ENUM, RC_RET_VOID);

	rc::DataBuffer*	bufObj	= DE_NULL;

	if (buffer != 0)
	{
		bufObj = m_buffers.find(buffer);
		if (!bufObj)
		{
			bufObj = new DataBuffer(buffer);
			m_buffers.insert(bufObj);
		}
	}

	setBufferBinding(target, bufObj);
}

void ReferenceContext::genBuffers (int numBuffers, deUint32* buffers)
{
	RC_IF_ERROR(!buffers, GL_INVALID_VALUE, RC_RET_VOID);

	for (int ndx = 0; ndx < numBuffers; ndx++)
		buffers[ndx] = m_buffers.allocateName();
}

void ReferenceContext::deleteBuffers (int numBuffers, const deUint32* buffers)
{
	RC_IF_ERROR(numBuffers < 0, GL_INVALID_VALUE, RC_RET_VOID);

	for (int ndx = 0; ndx < numBuffers; ndx++)
	{
		deUint32	buffer	= buffers[ndx];
		DataBuffer*	bufObj	= DE_NULL;

		if (buffer == 0)
			continue;

		bufObj = m_buffers.find(buffer);

		if (bufObj)
			deleteBuffer(bufObj);
	}
}

void ReferenceContext::deleteBuffer (DataBuffer* buffer)
{
	static const deUint32 bindingPoints[] =
	{
		GL_ARRAY_BUFFER,
		GL_COPY_READ_BUFFER,
		GL_COPY_WRITE_BUFFER,
		GL_DRAW_INDIRECT_BUFFER,
		GL_ELEMENT_ARRAY_BUFFER,
		GL_PIXEL_PACK_BUFFER,
		GL_PIXEL_UNPACK_BUFFER,
		GL_TRANSFORM_FEEDBACK_BUFFER,
		GL_UNIFORM_BUFFER
	};

	for (int bindingNdx = 0; bindingNdx < DE_LENGTH_OF_ARRAY(bindingPoints); bindingNdx++)
	{
		if (getBufferBinding(bindingPoints[bindingNdx]) == buffer)
			setBufferBinding(bindingPoints[bindingNdx], DE_NULL);
	}

	{
		vector<VertexArray*> vertexArrays;
		m_vertexArrays.getAll(vertexArrays);
		vertexArrays.push_back(&m_clientVertexArray);

		for (vector<VertexArray*>::iterator i = vertexArrays.begin(); i != vertexArrays.end(); i++)
		{
			if ((*i)->m_elementArrayBufferBinding == buffer)
			{
				m_buffers.releaseReference(buffer);
				(*i)->m_elementArrayBufferBinding = DE_NULL;
			}

			for (size_t vertexAttribNdx = 0; vertexAttribNdx < (*i)->m_arrays.size(); ++vertexAttribNdx)
			{
				if ((*i)->m_arrays[vertexAttribNdx].bufferBinding == buffer)
				{
					m_buffers.releaseReference(buffer);
					(*i)->m_arrays[vertexAttribNdx].bufferDeleted = true;
					(*i)->m_arrays[vertexAttribNdx].bufferBinding = DE_NULL;
				}
			}
		}
	}

	DE_ASSERT(buffer->getRefCount() == 1);
	m_buffers.releaseReference(buffer);
}

void ReferenceContext::bufferData (deUint32 target, deIntptr size, const void* data, deUint32 usage)
{
	RC_IF_ERROR(!isValidBufferTarget(target), GL_INVALID_ENUM, RC_RET_VOID);
	RC_IF_ERROR(size < 0, GL_INVALID_VALUE, RC_RET_VOID);

	DE_UNREF(usage);

	DataBuffer* buffer = getBufferBinding(target);
	RC_IF_ERROR(!buffer, GL_INVALID_OPERATION, RC_RET_VOID);

	DE_ASSERT((deIntptr)(int)size == size);
	buffer->setStorage((int)size);
	if (data)
		deMemcpy(buffer->getData(), data, (int)size);
}

void ReferenceContext::bufferSubData (deUint32 target, deIntptr offset, deIntptr size, const void* data)
{
	RC_IF_ERROR(!isValidBufferTarget(target), GL_INVALID_ENUM, RC_RET_VOID);
	RC_IF_ERROR(offset < 0 || size < 0, GL_INVALID_VALUE, RC_RET_VOID);

	DataBuffer* buffer = getBufferBinding(target);

	RC_IF_ERROR(!buffer, GL_INVALID_OPERATION, RC_RET_VOID);
	RC_IF_ERROR((int)(offset+size) > buffer->getSize(), GL_INVALID_VALUE, RC_RET_VOID);

	deMemcpy(buffer->getData()+offset, data, (int)size);
}

void ReferenceContext::clearColor (float red, float green, float blue, float alpha)
{
	m_clearColor = Vec4(de::clamp(red,	0.0f, 1.0f),
						de::clamp(green,	0.0f, 1.0f),
						de::clamp(blue,	0.0f, 1.0f),
						de::clamp(alpha,	0.0f, 1.0f));
}

void ReferenceContext::clearDepthf (float depth)
{
	m_clearDepth = de::clamp(depth, 0.0f, 1.0f);
}

void ReferenceContext::clearStencil (int stencil)
{
	m_clearStencil = stencil;
}

void ReferenceContext::scissor (int x, int y, int width, int height)
{
	RC_IF_ERROR(width < 0 || height < 0, GL_INVALID_VALUE, RC_RET_VOID);
	m_scissorBox = IVec4(x, y, width, height);
}

void ReferenceContext::enable (deUint32 cap)
{
	switch (cap)
	{
		case GL_BLEND:					m_blendEnabled				= true;	break;
		case GL_SCISSOR_TEST:			m_scissorEnabled			= true;	break;
		case GL_DEPTH_TEST:				m_depthTestEnabled			= true;	break;
		case GL_STENCIL_TEST:			m_stencilTestEnabled		= true;	break;
		case GL_POLYGON_OFFSET_FILL:	m_polygonOffsetFillEnabled	= true;	break;

		case GL_FRAMEBUFFER_SRGB:
			if (glu::isContextTypeGLCore(getType()))
			{
				m_sRGBUpdateEnabled = true;
				break;
			}
			setError(GL_INVALID_ENUM);
			break;

		case GL_DEPTH_CLAMP:
			if (glu::isContextTypeGLCore(getType()))
			{
				m_depthClampEnabled = true;
				break;
			}
			setError(GL_INVALID_ENUM);
			break;

		case GL_DITHER:
			// Not implemented - just ignored.
			break;

		case GL_PRIMITIVE_RESTART_FIXED_INDEX:
			if (!glu::isContextTypeGLCore(getType()))
			{
				m_primitiveRestartFixedIndex = true;
				break;
			}
			setError(GL_INVALID_ENUM);
			break;

		case GL_PRIMITIVE_RESTART:
			if (glu::isContextTypeGLCore(getType()))
			{
				m_primitiveRestartSettableIndex = true;
				break;
			}
			setError(GL_INVALID_ENUM);
			break;

		default:
			setError(GL_INVALID_ENUM);
			break;
	}
}

void ReferenceContext::disable (deUint32 cap)
{
	switch (cap)
	{
		case GL_BLEND:					m_blendEnabled				= false;	break;
		case GL_SCISSOR_TEST:			m_scissorEnabled			= false;	break;
		case GL_DEPTH_TEST:				m_depthTestEnabled			= false;	break;
		case GL_STENCIL_TEST:			m_stencilTestEnabled		= false;	break;
		case GL_POLYGON_OFFSET_FILL:	m_polygonOffsetFillEnabled	= false;	break;

		case GL_FRAMEBUFFER_SRGB:
			if (glu::isContextTypeGLCore(getType()))
			{
				m_sRGBUpdateEnabled = false;
				break;
			}
			setError(GL_INVALID_ENUM);
			break;

		case GL_DEPTH_CLAMP:
			if (glu::isContextTypeGLCore(getType()))
			{
				m_depthClampEnabled = false;
				break;
			}
			setError(GL_INVALID_ENUM);
			break;

		case GL_DITHER:
			break;

		case GL_PRIMITIVE_RESTART_FIXED_INDEX:
			if (!glu::isContextTypeGLCore(getType()))
			{
				m_primitiveRestartFixedIndex = false;
				break;
			}
			setError(GL_INVALID_ENUM);
			break;

		case GL_PRIMITIVE_RESTART:
			if (glu::isContextTypeGLCore(getType()))
			{
				m_primitiveRestartSettableIndex = false;
				break;
			}
			setError(GL_INVALID_ENUM);
			break;

		default:
			setError(GL_INVALID_ENUM);
			break;
	}
}

static bool isValidCompareFunc (deUint32 func)
{
	switch (func)
	{
		case GL_NEVER:
		case GL_LESS:
		case GL_LEQUAL:
		case GL_GREATER:
		case GL_GEQUAL:
		case GL_EQUAL:
		case GL_NOTEQUAL:
		case GL_ALWAYS:
			return true;

		default:
			return false;
	}
}

static bool isValidStencilOp (deUint32 op)
{
	switch (op)
	{
		case GL_KEEP:
		case GL_ZERO:
		case GL_REPLACE:
		case GL_INCR:
		case GL_INCR_WRAP:
		case GL_DECR:
		case GL_DECR_WRAP:
		case GL_INVERT:
			return true;

		default:
			return false;
	}
}

void ReferenceContext::stencilFunc (deUint32 func, int ref, deUint32 mask)
{
	stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
}

void ReferenceContext::stencilFuncSeparate (deUint32 face, deUint32 func, int ref, deUint32 mask)
{
	const bool	setFront	= face == GL_FRONT || face == GL_FRONT_AND_BACK;
	const bool	setBack		= face == GL_BACK || face == GL_FRONT_AND_BACK;

	RC_IF_ERROR(!isValidCompareFunc(func), GL_INVALID_ENUM, RC_RET_VOID);
	RC_IF_ERROR(!setFront && !setBack, GL_INVALID_ENUM, RC_RET_VOID);

	for (int type = 0; type < rr::FACETYPE_LAST; ++type)
	{
		if ((type == rr::FACETYPE_FRONT && setFront) ||
			(type == rr::FACETYPE_BACK && setBack))
		{
			m_stencil[type].func	= func;
			m_stencil[type].ref		= ref;
			m_stencil[type].opMask	= mask;
		}
	}
}

void ReferenceContext::stencilOp (deUint32 sfail, deUint32 dpfail, deUint32 dppass)
{
	stencilOpSeparate(GL_FRONT_AND_BACK, sfail, dpfail, dppass);
}

void ReferenceContext::stencilOpSeparate (deUint32 face, deUint32 sfail, deUint32 dpfail, deUint32 dppass)
{
	const bool	setFront	= face == GL_FRONT || face == GL_FRONT_AND_BACK;
	const bool	setBack		= face == GL_BACK || face == GL_FRONT_AND_BACK;

	RC_IF_ERROR(!isValidStencilOp(sfail)	||
				!isValidStencilOp(dpfail)	||
				!isValidStencilOp(dppass),
				GL_INVALID_ENUM, RC_RET_VOID);
	RC_IF_ERROR(!setFront && !setBack, GL_INVALID_ENUM, RC_RET_VOID);

	for (int type = 0; type < rr::FACETYPE_LAST; ++type)
	{
		if ((type == rr::FACETYPE_FRONT && setFront) ||
			(type == rr::FACETYPE_BACK && setBack))
		{
			m_stencil[type].opStencilFail	= sfail;
			m_stencil[type].opDepthFail		= dpfail;
			m_stencil[type].opDepthPass		= dppass;
		}
	}
}

void ReferenceContext::depthFunc (deUint32 func)
{
	RC_IF_ERROR(!isValidCompareFunc(func), GL_INVALID_ENUM, RC_RET_VOID);
	m_depthFunc = func;
}

void ReferenceContext::depthRangef (float n, float f)
{
	m_depthRangeNear = de::clamp(n, 0.0f, 1.0f);
	m_depthRangeFar = de::clamp(f, 0.0f, 1.0f);
}

void ReferenceContext::depthRange (double n, double f)
{
	depthRangef((float)n, (float)f);
}

void ReferenceContext::polygonOffset (float factor, float units)
{
	m_polygonOffsetFactor = factor;
	m_polygonOffsetUnits = units;
}

void ReferenceContext::provokingVertex (deUint32 convention)
{
	// only in core
	DE_ASSERT(glu::isContextTypeGLCore(getType()));

	switch (convention)
	{
		case GL_FIRST_VERTEX_CONVENTION:	m_provokingFirstVertexConvention = true; break;
		case GL_LAST_VERTEX_CONVENTION:		m_provokingFirstVertexConvention = false; break;

		default:
			RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
	}
}

void ReferenceContext::primitiveRestartIndex (deUint32 index)
{
	// only in core
	DE_ASSERT(glu::isContextTypeGLCore(getType()));
	m_primitiveRestartIndex = index;
}

static inline bool isValidBlendEquation (deUint32 mode)
{
	return mode == GL_FUNC_ADD				||
		   mode == GL_FUNC_SUBTRACT			||
		   mode == GL_FUNC_REVERSE_SUBTRACT	||
		   mode == GL_MIN					||
		   mode == GL_MAX;
}

static bool isValidBlendFactor (deUint32 factor)
{
	switch (factor)
	{
		case GL_ZERO:
		case GL_ONE:
		case GL_SRC_COLOR:
		case GL_ONE_MINUS_SRC_COLOR:
		case GL_DST_COLOR:
		case GL_ONE_MINUS_DST_COLOR:
		case GL_SRC_ALPHA:
		case GL_ONE_MINUS_SRC_ALPHA:
		case GL_DST_ALPHA:
		case GL_ONE_MINUS_DST_ALPHA:
		case GL_CONSTANT_COLOR:
		case GL_ONE_MINUS_CONSTANT_COLOR:
		case GL_CONSTANT_ALPHA:
		case GL_ONE_MINUS_CONSTANT_ALPHA:
		case GL_SRC_ALPHA_SATURATE:
			return true;

		default:
			return false;
	}
}

void ReferenceContext::blendEquation (deUint32 mode)
{
	RC_IF_ERROR(!isValidBlendEquation(mode), GL_INVALID_ENUM, RC_RET_VOID);

	m_blendModeRGB		= mode;
	m_blendModeAlpha	= mode;
}

void ReferenceContext::blendEquationSeparate (deUint32 modeRGB, deUint32 modeAlpha)
{
	RC_IF_ERROR(!isValidBlendEquation(modeRGB) ||
				!isValidBlendEquation(modeAlpha),
				GL_INVALID_ENUM, RC_RET_VOID);

	m_blendModeRGB		= modeRGB;
	m_blendModeAlpha	= modeAlpha;
}

void ReferenceContext::blendFunc (deUint32 src, deUint32 dst)
{
	RC_IF_ERROR(!isValidBlendFactor(src) ||
				!isValidBlendFactor(dst),
				GL_INVALID_ENUM, RC_RET_VOID);

	m_blendFactorSrcRGB		= src;
	m_blendFactorSrcAlpha	= src;
	m_blendFactorDstRGB		= dst;
	m_blendFactorDstAlpha	= dst;
}

void ReferenceContext::blendFuncSeparate (deUint32 srcRGB, deUint32 dstRGB, deUint32 srcAlpha, deUint32 dstAlpha)
{
	RC_IF_ERROR(!isValidBlendFactor(srcRGB)		||
				!isValidBlendFactor(dstRGB)		||
				!isValidBlendFactor(srcAlpha)	||
				!isValidBlendFactor(dstAlpha),
				GL_INVALID_ENUM, RC_RET_VOID);

	m_blendFactorSrcRGB		= srcRGB;
	m_blendFactorSrcAlpha	= srcAlpha;
	m_blendFactorDstRGB		= dstRGB;
	m_blendFactorDstAlpha	= dstAlpha;
}

void ReferenceContext::blendColor (float red, float green, float blue, float alpha)
{
	m_blendColor = Vec4(de::clamp(red,	0.0f, 1.0f),
						de::clamp(green,	0.0f, 1.0f),
						de::clamp(blue,	0.0f, 1.0f),
						de::clamp(alpha,	0.0f, 1.0f));
}

void ReferenceContext::colorMask (deBool r, deBool g, deBool b, deBool a)
{
	m_colorMask = tcu::BVec4(!!r, !!g, !!b, !!a);
}

void ReferenceContext::depthMask (deBool mask)
{
	m_depthMask = !!mask;
}

void ReferenceContext::stencilMask (deUint32 mask)
{
	stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
}

void ReferenceContext::stencilMaskSeparate (deUint32 face, deUint32 mask)
{
	const bool	setFront	= face == GL_FRONT || face == GL_FRONT_AND_BACK;
	const bool	setBack		= face == GL_BACK || face == GL_FRONT_AND_BACK;

	RC_IF_ERROR(!setFront && !setBack, GL_INVALID_ENUM, RC_RET_VOID);

	if (setFront)	m_stencil[rr::FACETYPE_FRONT].writeMask	= mask;
	if (setBack)	m_stencil[rr::FACETYPE_BACK].writeMask	= mask;
}

static int getNumStencilBits (const tcu::TextureFormat& format)
{
	switch (format.order)
	{
		case tcu::TextureFormat::S:
			switch (format.type)
			{
				case tcu::TextureFormat::UNSIGNED_INT8:		return 8;
				case tcu::TextureFormat::UNSIGNED_INT16:	return 16;
				case tcu::TextureFormat::UNSIGNED_INT32:	return 32;
				default:
					DE_ASSERT(false);
					return 0;
			}

		case tcu::TextureFormat::DS:
			switch (format.type)
			{
				case tcu::TextureFormat::UNSIGNED_INT_24_8:				return 8;
				case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:	return 8;
				default:
					DE_ASSERT(false);
					return 0;
			}

		default:
			DE_ASSERT(false);
			return 0;
	}
}

static inline deUint32 maskStencil (int numBits, deUint32 s)
{
	return s & deBitMask32(0, numBits);
}

static inline void writeMaskedStencil (const rr::MultisamplePixelBufferAccess& access, int s, int x, int y, deUint32 stencil, deUint32 writeMask)
{
	DE_ASSERT(access.raw().getFormat().order == tcu::TextureFormat::S);

	const deUint32 oldVal = access.raw().getPixelUint(s, x, y).x();
	const deUint32 newVal = (oldVal & ~writeMask) | (stencil & writeMask);
	access.raw().setPixel(tcu::UVec4(newVal, 0u, 0u, 0u), s, x, y);
}

static inline void writeDepthOnly (const rr::MultisamplePixelBufferAccess& access, int s, int x, int y, float depth)
{
	access.raw().setPixDepth(depth, s, x, y);
}

static rr::MultisamplePixelBufferAccess getDepthMultisampleAccess (const rr::MultisamplePixelBufferAccess& combinedDSaccess)
{
	return rr::MultisamplePixelBufferAccess::fromMultisampleAccess(tcu::getEffectiveDepthStencilAccess(combinedDSaccess.raw(), tcu::Sampler::MODE_DEPTH));
}

static rr::MultisamplePixelBufferAccess getStencilMultisampleAccess (const rr::MultisamplePixelBufferAccess& combinedDSaccess)
{
	return rr::MultisamplePixelBufferAccess::fromMultisampleAccess(tcu::getEffectiveDepthStencilAccess(combinedDSaccess.raw(), tcu::Sampler::MODE_STENCIL));
}

deUint32 ReferenceContext::blitResolveMultisampleFramebuffer (deUint32 mask, const IVec4& srcRect, const IVec4& dstRect, bool flipX, bool flipY)
{
	if (mask & GL_COLOR_BUFFER_BIT)
	{
		rr::MultisampleConstPixelBufferAccess	src			= rr::getSubregion(getReadColorbuffer(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w());
		tcu::PixelBufferAccess					dst			= tcu::getSubregion(getDrawColorbuffer().toSinglesampleAccess(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w());
		tcu::TextureChannelClass				dstClass	= tcu::getTextureChannelClass(dst.getFormat().type);
		bool									dstIsFloat	= dstClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT		||
															  dstClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT	||
															  dstClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
		bool									srcIsSRGB	= tcu::isSRGB(src.raw().getFormat());
		bool									dstIsSRGB	= tcu::isSRGB(dst.getFormat());
		const bool								convertSRGB	= m_sRGBUpdateEnabled && glu::isContextTypeES(getType());

		if (!convertSRGB)
		{
			tcu::ConstPixelBufferAccess	srcRaw	= src.raw();
			tcu::TextureFormat			srcFmt	= toNonSRGBFormat(srcRaw.getFormat());

			srcRaw	= tcu::ConstPixelBufferAccess(srcFmt, srcRaw.getWidth(), srcRaw.getHeight(), srcRaw.getDepth(), srcRaw.getRowPitch(), srcRaw.getSlicePitch(), srcRaw.getDataPtr());
			src		= rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(srcRaw);

			dst		= tcu::PixelBufferAccess(toNonSRGBFormat(dst.getFormat()), dst.getWidth(), dst.getHeight(), dst.getDepth(), dst.getRowPitch(), dst.getSlicePitch(), dst.getDataPtr());
		}

		for (int x = 0; x < dstRect.z(); ++x)
		for (int y = 0; y < dstRect.w(); ++y)
		{
			int srcX = (flipX) ? (srcRect.z() - x - 1) : (x);
			int srcY = (flipY) ? (srcRect.z() - y - 1) : (y);

			if (dstIsFloat || srcIsSRGB)
			{
				Vec4 p = src.raw().getPixel(0, srcX,srcY);
				dst.setPixel((dstIsSRGB && convertSRGB) ? tcu::linearToSRGB(p) : p, x, y);
			}
			else
				dst.setPixel(src.raw().getPixelInt(0, srcX, srcY), x, y);
		}
	}

	if (mask & GL_DEPTH_BUFFER_BIT)
	{
		rr::MultisampleConstPixelBufferAccess	src	= rr::getSubregion(getReadDepthbuffer(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w());
		rr::MultisamplePixelBufferAccess		dst	= rr::getSubregion(getDrawDepthbuffer(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w());

		for (int x = 0; x < dstRect.z(); ++x)
		for (int y = 0; y < dstRect.w(); ++y)
		{
			int srcX = (flipX) ? (srcRect.z() - x - 1) : (x);
			int srcY = (flipY) ? (srcRect.z() - y - 1) : (y);

			writeDepthOnly(dst, 0, x, y, src.raw().getPixel(0, srcX, srcY).x());
		}
	}

	if (mask & GL_STENCIL_BUFFER_BIT)
	{
		rr::MultisampleConstPixelBufferAccess	src	= getStencilMultisampleAccess(rr::getSubregion(getReadStencilbuffer(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w()));
		rr::MultisamplePixelBufferAccess		dst	= getStencilMultisampleAccess(rr::getSubregion(getDrawStencilbuffer(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w()));

		for (int x = 0; x < dstRect.z(); ++x)
		for (int y = 0; y < dstRect.w(); ++y)
		{
			int			srcX		= (flipX) ? (srcRect.z() - x - 1) : (x);
			int			srcY		= (flipY) ? (srcRect.z() - y - 1) : (y);
			deUint32	srcStencil	= src.raw().getPixelUint(0, srcX, srcY).x();

			writeMaskedStencil(dst, 0, x, y, srcStencil, m_stencil[rr::FACETYPE_FRONT].writeMask);
		}
	}

	return GL_NO_ERROR;
}

void ReferenceContext::blitFramebuffer (int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, deUint32 mask, deUint32 filter)
{
	// p0 in inclusive, p1 exclusive.
	// Negative width/height means swap.
	bool	swapSrcX	= srcX1 < srcX0;
	bool	swapSrcY	= srcY1 < srcY0;
	bool	swapDstX	= dstX1 < dstX0;
	bool	swapDstY	= dstY1 < dstY0;
	int		srcW		= de::abs(srcX1-srcX0);
	int		srcH		= de::abs(srcY1-srcY0);
	int		dstW		= de::abs(dstX1-dstX0);
	int		dstH		= de::abs(dstY1-dstY0);
	bool	scale		= srcW != dstW || srcH != dstH;
	int		srcOriginX	= swapSrcX ? srcX1 : srcX0;
	int		srcOriginY	= swapSrcY ? srcY1 : srcY0;
	int		dstOriginX	= swapDstX ? dstX1 : dstX0;
	int		dstOriginY	= swapDstY ? dstY1 : dstY0;
	IVec4	srcRect		= IVec4(srcOriginX, srcOriginY, srcW, srcH);
	IVec4	dstRect		= IVec4(dstOriginX, dstOriginY, dstW, dstH);

	RC_IF_ERROR(filter != GL_NEAREST && filter != GL_LINEAR, GL_INVALID_ENUM, RC_RET_VOID);
	RC_IF_ERROR((mask & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) != 0 && filter != GL_NEAREST, GL_INVALID_OPERATION, RC_RET_VOID);

	// Validate that both targets are complete.
	RC_IF_ERROR(checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE ||
				checkFramebufferStatus(GL_READ_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_OPERATION, RC_RET_VOID);

	// Check samples count is valid
	RC_IF_ERROR(getDrawColorbuffer().getNumSamples() != 1, GL_INVALID_OPERATION, RC_RET_VOID);

	// Check size restrictions of multisampled case
	if (getReadColorbuffer().getNumSamples() != 1)
	{
		// Src and Dst rect dimensions must be the same
		RC_IF_ERROR(srcW != dstW || srcH != dstH, GL_INVALID_OPERATION, RC_RET_VOID);

		// Framebuffer formats must match
		if (mask & GL_COLOR_BUFFER_BIT)		RC_IF_ERROR(getReadColorbuffer().raw().getFormat()   != getDrawColorbuffer().raw().getFormat(),   GL_INVALID_OPERATION, RC_RET_VOID);
		if (mask & GL_DEPTH_BUFFER_BIT)		RC_IF_ERROR(getReadDepthbuffer().raw().getFormat()   != getDrawDepthbuffer().raw().getFormat(),   GL_INVALID_OPERATION, RC_RET_VOID);
		if (mask & GL_STENCIL_BUFFER_BIT)	RC_IF_ERROR(getReadStencilbuffer().raw().getFormat() != getDrawStencilbuffer().raw().getFormat(), GL_INVALID_OPERATION, RC_RET_VOID);
	}

	// Compute actual source rect.
	srcRect = (mask & GL_COLOR_BUFFER_BIT)		? intersect(srcRect, getBufferRect(getReadColorbuffer()))	: srcRect;
	srcRect = (mask & GL_DEPTH_BUFFER_BIT)		? intersect(srcRect, getBufferRect(getReadDepthbuffer()))	: srcRect;
	srcRect = (mask & GL_STENCIL_BUFFER_BIT)	? intersect(srcRect, getBufferRect(getReadStencilbuffer()))	: srcRect;

	// Compute destination rect.
	dstRect = (mask & GL_COLOR_BUFFER_BIT)		? intersect(dstRect, getBufferRect(getDrawColorbuffer()))	: dstRect;
	dstRect = (mask & GL_DEPTH_BUFFER_BIT)		? intersect(dstRect, getBufferRect(getDrawDepthbuffer()))	: dstRect;
	dstRect = (mask & GL_STENCIL_BUFFER_BIT)	? intersect(dstRect, getBufferRect(getDrawStencilbuffer()))	: dstRect;
	dstRect = m_scissorEnabled					? intersect(dstRect, m_scissorBox)							: dstRect;

	if (isEmpty(srcRect) || isEmpty(dstRect))
		return; // Don't attempt copy.

	// Multisampled read buffer is a special case
	if (getReadColorbuffer().getNumSamples() != 1)
	{
		deUint32 error = blitResolveMultisampleFramebuffer(mask, srcRect, dstRect, swapSrcX ^ swapDstX, swapSrcY ^ swapDstY);

		if (error != GL_NO_ERROR)
			setError(error);

		return;
	}

	// \note Multisample pixel buffers can now be accessed like non-multisampled because multisample read buffer case is already handled. => sample count must be 1

	// Coordinate transformation:
	// Dst offset space -> dst rectangle space -> src rectangle space -> src offset space.
	tcu::Mat3 transform = tcu::translationMatrix(Vec2((float)(srcX0 - srcRect.x()), (float)(srcY0 - srcRect.y())))
						* tcu::Mat3(Vec3((float)(srcX1-srcX0) / (float)(dstX1-dstX0),
										 (float)(srcY1-srcY0) / (float)(dstY1-dstY0),
										 1.0f))
						* tcu::translationMatrix(Vec2((float)(dstRect.x() - dstX0), (float)(dstRect.y() - dstY0)));

	if (mask & GL_COLOR_BUFFER_BIT)
	{
		tcu::ConstPixelBufferAccess		src			= tcu::getSubregion(getReadColorbuffer().toSinglesampleAccess(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w());
		tcu::PixelBufferAccess			dst			= tcu::getSubregion(getDrawColorbuffer().toSinglesampleAccess(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w());
		tcu::TextureChannelClass		dstClass	= tcu::getTextureChannelClass(dst.getFormat().type);
		bool							dstIsFloat	= dstClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT		||
													  dstClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT	||
													  dstClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
		tcu::Sampler::FilterMode		sFilter		= (scale && filter == GL_LINEAR) ? tcu::Sampler::LINEAR : tcu::Sampler::NEAREST;
		tcu::Sampler					sampler		(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
													 sFilter, sFilter, 0.0f /* lod threshold */, false /* non-normalized coords */);
		bool							srcIsSRGB	= tcu::isSRGB(src.getFormat());
		bool							dstIsSRGB	= tcu::isSRGB(dst.getFormat());
		const bool						convertSRGB	= m_sRGBUpdateEnabled && glu::isContextTypeES(getType());

		if (!convertSRGB)
		{
			src	= tcu::ConstPixelBufferAccess	(toNonSRGBFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth(), src.getRowPitch(), src.getSlicePitch(), src.getDataPtr());
			dst	= tcu::PixelBufferAccess		(toNonSRGBFormat(dst.getFormat()), dst.getWidth(), dst.getHeight(), dst.getDepth(), dst.getRowPitch(), dst.getSlicePitch(), dst.getDataPtr());
		}

		// \note We don't check for unsupported conversions, unlike spec requires.

		for (int yo = 0; yo < dstRect.w(); yo++)
		{
			for (int xo = 0; xo < dstRect.z(); xo++)
			{
				float	dX	= (float)xo + 0.5f;
				float	dY	= (float)yo + 0.5f;

				// \note Only affine part is used.
				float	sX	= transform(0, 0)*dX + transform(0, 1)*dY + transform(0, 2);
				float	sY	= transform(1, 0)*dX + transform(1, 1)*dY + transform(1, 2);

				// do not copy pixels outside the modified source region (modified by buffer intersection)
				if (sX < 0.0f || sX >= (float)srcRect.z() ||
					sY < 0.0f || sY >= (float)srcRect.w())
					continue;

				if (dstIsFloat || srcIsSRGB || filter == tcu::Sampler::LINEAR)
				{
					Vec4 p = src.sample2D(sampler, sampler.minFilter, sX, sY, 0);
					dst.setPixel((dstIsSRGB && convertSRGB) ? tcu::linearToSRGB(p) : p, xo, yo);
				}
				else
					dst.setPixel(src.getPixelInt(deFloorFloatToInt32(sX), deFloorFloatToInt32(sY)), xo, yo);
			}
		}
	}

	if ((mask & GL_DEPTH_BUFFER_BIT) && m_depthMask)
	{
		rr::MultisampleConstPixelBufferAccess	src		= getDepthMultisampleAccess(rr::getSubregion(getReadDepthbuffer(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w()));
		rr::MultisamplePixelBufferAccess		dst		= getDepthMultisampleAccess(rr::getSubregion(getDrawDepthbuffer(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w()));

		for (int yo = 0; yo < dstRect.w(); yo++)
		{
			for (int xo = 0; xo < dstRect.z(); xo++)
			{
				const int sampleNdx = 0; // multisample read buffer case is already handled

				float	dX	= (float)xo + 0.5f;
				float	dY	= (float)yo + 0.5f;
				float	sX	= transform(0, 0)*dX + transform(0, 1)*dY + transform(0, 2);
				float	sY	= transform(1, 0)*dX + transform(1, 1)*dY + transform(1, 2);

				writeDepthOnly(dst, sampleNdx, xo, yo, src.raw().getPixDepth(sampleNdx, deFloorFloatToInt32(sX), deFloorFloatToInt32(sY)));
			}
		}
	}

	if (mask & GL_STENCIL_BUFFER_BIT)
	{
		rr::MultisampleConstPixelBufferAccess	src	= getStencilMultisampleAccess(rr::getSubregion(getReadStencilbuffer(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w()));
		rr::MultisamplePixelBufferAccess		dst	= getStencilMultisampleAccess(rr::getSubregion(getDrawStencilbuffer(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w()));

		for (int yo = 0; yo < dstRect.w(); yo++)
		{
			for (int xo = 0; xo < dstRect.z(); xo++)
			{
				const int	sampleNdx = 0; // multisample read buffer case is already handled

				float		dX			= (float)xo + 0.5f;
				float		dY			= (float)yo + 0.5f;
				float		sX			= transform(0, 0)*dX + transform(0, 1)*dY + transform(0, 2);
				float		sY			= transform(1, 0)*dX + transform(1, 1)*dY + transform(1, 2);
				deUint32	srcStencil	= src.raw().getPixelUint(sampleNdx, deFloorFloatToInt32(sX), deFloorFloatToInt32(sY)).x();

				writeMaskedStencil(dst, sampleNdx, xo, yo, srcStencil, m_stencil[rr::FACETYPE_FRONT].writeMask);
			}
		}
	}
}

void ReferenceContext::invalidateSubFramebuffer (deUint32 target, int numAttachments, const deUint32* attachments, int x, int y, int width, int height)
{
	RC_IF_ERROR(target != GL_FRAMEBUFFER, GL_INVALID_ENUM, RC_RET_VOID);
	RC_IF_ERROR((numAttachments < 0) || (numAttachments > 1 && attachments == DE_NULL), GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(width < 0 || height < 0, GL_INVALID_VALUE, RC_RET_VOID);

	// \todo [2012-07-17 pyry] Support multiple color attachments.

	const Vec4		colorClearValue		(0.0f);
	const float		depthClearValue		= 1.0f;
	const int		stencilClearValue	= 0;

	bool			isFboBound			= m_drawFramebufferBinding != DE_NULL;
	bool			discardBuffers[3]	= { false, false, false }; // Color, depth, stencil

	for (int attNdx = 0; attNdx < numAttachments; attNdx++)
	{
		bool	isColor			= attachments[attNdx] == (isFboBound ? GL_COLOR_ATTACHMENT0		: GL_COLOR);
		bool	isDepth			= attachments[attNdx] == (isFboBound ? GL_DEPTH_ATTACHMENT		: GL_DEPTH);
		bool	isStencil		= attachments[attNdx] == (isFboBound ? GL_STENCIL_ATTACHMENT	: GL_STENCIL);
		bool	isDepthStencil	= isFboBound && attachments[attNdx] == GL_DEPTH_STENCIL_ATTACHMENT;

		RC_IF_ERROR(!isColor && !isDepth && !isStencil && !isDepthStencil, GL_INVALID_VALUE, RC_RET_VOID);

		if (isColor)						discardBuffers[0] = true;
		if (isDepth || isDepthStencil)		discardBuffers[1] = true;
		if (isStencil || isDepthStencil)	discardBuffers[2] = true;
	}

	for (int ndx = 0; ndx < 3; ndx++)
	{
		if (!discardBuffers[ndx])
			continue;

		bool								isColor					= ndx == 0;
		bool								isDepth					= ndx == 1;
		bool								isStencil				= ndx == 2;
		rr::MultisamplePixelBufferAccess	buf						= isColor ? getDrawColorbuffer()								:
																	  isDepth ? getDepthMultisampleAccess(getDrawDepthbuffer())		:
																				getStencilMultisampleAccess(getDrawStencilbuffer());

		if (isEmpty(buf))
			continue;

		tcu::IVec4							area					= intersect(tcu::IVec4(0, 0, buf.raw().getHeight(), buf.raw().getDepth()), tcu::IVec4(x, y, width, height));
		rr::MultisamplePixelBufferAccess	access					= rr::getSubregion(buf, area.x(), area.y(), area.z(), area.w());

		if (isColor)
			rr::clear(access, colorClearValue);
		else if (isDepth)
			rr::clear(access, tcu::Vec4(depthClearValue));
		else if (isStencil)
			rr::clear(access, tcu::IVec4(stencilClearValue));
	}
}

void ReferenceContext::invalidateFramebuffer (deUint32 target, int numAttachments, const deUint32* attachments)
{
	// \todo [2012-07-17 pyry] Support multiple color attachments.
	rr::MultisampleConstPixelBufferAccess	colorBuf0	= getDrawColorbuffer();
	rr::MultisampleConstPixelBufferAccess	depthBuf	= getDrawDepthbuffer();
	rr::MultisampleConstPixelBufferAccess	stencilBuf	= getDrawStencilbuffer();
	int										width		= 0;
	int										height		= 0;

	width = de::max(width, colorBuf0.raw().getHeight());
	width = de::max(width, depthBuf.raw().getHeight());
	width = de::max(width, stencilBuf.raw().getHeight());

	height = de::max(height, colorBuf0.raw().getDepth());
	height = de::max(height, depthBuf.raw().getDepth());
	height = de::max(height, stencilBuf.raw().getDepth());

	invalidateSubFramebuffer(target, numAttachments, attachments, 0, 0, width, height);
}

void ReferenceContext::clear (deUint32 buffers)
{
	RC_IF_ERROR((buffers & ~(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) != 0, GL_INVALID_VALUE, RC_RET_VOID);

	rr::MultisamplePixelBufferAccess	colorBuf0	= getDrawColorbuffer();
	rr::MultisamplePixelBufferAccess	depthBuf	= getDrawDepthbuffer();
	rr::MultisamplePixelBufferAccess	stencilBuf	= getDrawStencilbuffer();
	IVec4								baseArea	= m_scissorEnabled ? m_scissorBox : IVec4(0, 0, 0x7fffffff, 0x7fffffff);
	IVec4								colorArea	= intersect(baseArea, getBufferRect(colorBuf0));
	IVec4								depthArea	= intersect(baseArea, getBufferRect(depthBuf));
	IVec4								stencilArea	= intersect(baseArea, getBufferRect(stencilBuf));
	bool								hasColor0	= !isEmpty(colorArea);
	bool								hasDepth	= !isEmpty(depthArea);
	bool								hasStencil	= !isEmpty(stencilArea);

	if (hasColor0 && (buffers & GL_COLOR_BUFFER_BIT) != 0)
	{
		rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(colorBuf0, colorArea.x(), colorArea.y(), colorArea.z(), colorArea.w());
		bool								isSRGB		= tcu::isSRGB(colorBuf0.raw().getFormat());
		Vec4								c			= (isSRGB && m_sRGBUpdateEnabled) ? tcu::linearToSRGB(m_clearColor) : m_clearColor;
		bool								maskUsed	= !m_colorMask[0] || !m_colorMask[1] || !m_colorMask[2] || !m_colorMask[3];
		bool								maskZero	= !m_colorMask[0] && !m_colorMask[1] && !m_colorMask[2] && !m_colorMask[3];

		if (!maskUsed)
			rr::clear(access, c);
		else if (!maskZero)
		{
			for (int y = 0; y < access.raw().getDepth(); y++)
				for (int x = 0; x < access.raw().getHeight(); x++)
					for (int s = 0; s < access.getNumSamples(); s++)
						access.raw().setPixel(tcu::select(c, access.raw().getPixel(s, x, y), m_colorMask), s, x, y);
		}
		// else all channels masked out
	}

	if (hasDepth && (buffers & GL_DEPTH_BUFFER_BIT) != 0 && m_depthMask)
	{
		rr::MultisamplePixelBufferAccess access = getDepthMultisampleAccess(rr::getSubregion(depthBuf, depthArea.x(), depthArea.y(), depthArea.z(), depthArea.w()));
		rr::clearDepth(access, m_clearDepth);
	}

	if (hasStencil && (buffers & GL_STENCIL_BUFFER_BIT) != 0)
	{
		rr::MultisamplePixelBufferAccess	access					= getStencilMultisampleAccess(rr::getSubregion(stencilBuf, stencilArea.x(), stencilArea.y(), stencilArea.z(), stencilArea.w()));
		int									stencilBits				= getNumStencilBits(stencilBuf.raw().getFormat());
		int									stencil					= maskStencil(stencilBits, m_clearStencil);

		if ((m_stencil[rr::FACETYPE_FRONT].writeMask & ((1u<<stencilBits)-1u)) != ((1u<<stencilBits)-1u))
		{
			// Slow path where depth or stencil is masked out in write.
			for (int y = 0; y < access.raw().getDepth(); y++)
				for (int x = 0; x < access.raw().getHeight(); x++)
					for (int s = 0; s < access.getNumSamples(); s++)
						writeMaskedStencil(access, s, x, y, stencil, m_stencil[rr::FACETYPE_FRONT].writeMask);
		}
		else
			rr::clearStencil(access, stencil);
	}
}

void ReferenceContext::clearBufferiv (deUint32 buffer, int drawbuffer, const int* value)
{
	RC_IF_ERROR(buffer != GL_COLOR && buffer != GL_STENCIL, GL_INVALID_ENUM, RC_RET_VOID);
	RC_IF_ERROR(drawbuffer != 0, GL_INVALID_VALUE, RC_RET_VOID); // \todo [2012-04-06 pyry] MRT support.

	IVec4 baseArea = m_scissorEnabled ? m_scissorBox : IVec4(0, 0, 0x7fffffff, 0x7fffffff);

	if (buffer == GL_COLOR)
	{
		rr::MultisamplePixelBufferAccess	colorBuf	= getDrawColorbuffer();
		bool								maskUsed	= !m_colorMask[0] || !m_colorMask[1] || !m_colorMask[2] || !m_colorMask[3];
		bool								maskZero	= !m_colorMask[0] && !m_colorMask[1] && !m_colorMask[2] && !m_colorMask[3];
		IVec4								area		= intersect(baseArea, getBufferRect(colorBuf));

		if (!isEmpty(area) && !maskZero)
		{
			rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(colorBuf, area.x(), area.y(), area.z(), area.w());
			IVec4								color		(value[0], value[1], value[2], value[3]);

			if (!maskUsed)
				rr::clear(access, color);
			else
			{
				for (int y = 0; y < access.raw().getDepth(); y++)
					for (int x = 0; x < access.raw().getHeight(); x++)
						for (int s = 0; s < access.getNumSamples(); s++)
							access.raw().setPixel(tcu::select(color, access.raw().getPixelInt(s, x, y), m_colorMask), s, x, y);
			}
		}
	}
	else
	{
		TCU_CHECK_INTERNAL(buffer == GL_STENCIL);

		rr::MultisamplePixelBufferAccess	stencilBuf	= getDrawStencilbuffer();
		IVec4								area		= intersect(baseArea, getBufferRect(stencilBuf));

		if (!isEmpty(area) && m_stencil[rr::FACETYPE_FRONT].writeMask != 0)
		{
			rr::MultisamplePixelBufferAccess	access		= getStencilMultisampleAccess(rr::getSubregion(stencilBuf, area.x(), area.y(), area.z(), area.w()));
			int									stencil		= value[0];

			for (int y = 0; y < access.raw().getDepth(); y++)
				for (int x = 0; x < access.raw().getHeight(); x++)
					for (int s = 0; s < access.getNumSamples(); s++)
						writeMaskedStencil(access, s, x, y, stencil, m_stencil[rr::FACETYPE_FRONT].writeMask);
		}
	}
}

void ReferenceContext::clearBufferfv (deUint32 buffer, int drawbuffer, const float* value)
{
	RC_IF_ERROR(buffer != GL_COLOR && buffer != GL_DEPTH, GL_INVALID_ENUM, RC_RET_VOID);
	RC_IF_ERROR(drawbuffer != 0, GL_INVALID_VALUE, RC_RET_VOID); // \todo [2012-04-06 pyry] MRT support.

	IVec4 baseArea = m_scissorEnabled ? m_scissorBox : IVec4(0, 0, 0x7fffffff, 0x7fffffff);

	if (buffer == GL_COLOR)
	{
		rr::MultisamplePixelBufferAccess	colorBuf	= getDrawColorbuffer();
		bool								maskUsed	= !m_colorMask[0] || !m_colorMask[1] || !m_colorMask[2] || !m_colorMask[3];
		bool								maskZero	= !m_colorMask[0] && !m_colorMask[1] && !m_colorMask[2] && !m_colorMask[3];
		IVec4								area		= intersect(baseArea, getBufferRect(colorBuf));

		if (!isEmpty(area) && !maskZero)
		{
			rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(colorBuf, area.x(), area.y(), area.z(), area.w());
			Vec4								color		(value[0], value[1], value[2], value[3]);

			if (m_sRGBUpdateEnabled && tcu::isSRGB(access.raw().getFormat()))
				color = tcu::linearToSRGB(color);

			if (!maskUsed)
				rr::clear(access, color);
			else
			{
				for (int y = 0; y < access.raw().getDepth(); y++)
					for (int x = 0; x < access.raw().getHeight(); x++)
						for (int s = 0; s < access.getNumSamples(); s++)
							access.raw().setPixel(tcu::select(color, access.raw().getPixel(s, x, y), m_colorMask), s, x, y);
			}
		}
	}
	else
	{
		TCU_CHECK_INTERNAL(buffer == GL_DEPTH);

		rr::MultisamplePixelBufferAccess	depthBuf	= getDrawDepthbuffer();
		IVec4								area		= intersect(baseArea, getBufferRect(depthBuf));

		if (!isEmpty(area) && m_depthMask)
		{
			rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(depthBuf, area.x(), area.y(), area.z(), area.w());
			float								depth		= value[0];

			rr::clearDepth(access, depth);
		}
	}
}

void ReferenceContext::clearBufferuiv (deUint32 buffer, int drawbuffer, const deUint32* value)
{
	RC_IF_ERROR(buffer != GL_COLOR, GL_INVALID_ENUM, RC_RET_VOID);
	RC_IF_ERROR(drawbuffer != 0, GL_INVALID_VALUE, RC_RET_VOID); // \todo [2012-04-06 pyry] MRT support.

	IVec4 baseArea = m_scissorEnabled ? m_scissorBox : IVec4(0, 0, 0x7fffffff, 0x7fffffff);

	TCU_CHECK_INTERNAL(buffer == GL_COLOR);
	{
		rr::MultisamplePixelBufferAccess	colorBuf	= getDrawColorbuffer();
		bool								maskUsed	= !m_colorMask[0] || !m_colorMask[1] || !m_colorMask[2] || !m_colorMask[3];
		bool								maskZero	= !m_colorMask[0] && !m_colorMask[1] && !m_colorMask[2] && !m_colorMask[3];
		IVec4								area		= intersect(baseArea, getBufferRect(colorBuf));

		if (!isEmpty(area) && !maskZero)
		{
			rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(colorBuf, area.x(), area.y(), area.z(), area.w());
			tcu::UVec4							color		(value[0], value[1], value[2], value[3]);

			if (!maskUsed)
				rr::clear(access, color.asInt());
			else
			{
				for (int y = 0; y < access.raw().getDepth(); y++)
					for (int x = 0; x < access.raw().getHeight(); x++)
						for (int s = 0; s < access.getNumSamples(); s++)
							access.raw().setPixel(tcu::select(color, access.raw().getPixelUint(s, x, y), m_colorMask), s, x, y);
			}
		}
	}
}

void ReferenceContext::clearBufferfi (deUint32 buffer, int drawbuffer, float depth, int stencil)
{
	RC_IF_ERROR(buffer != GL_DEPTH_STENCIL, GL_INVALID_ENUM, RC_RET_VOID);
	clearBufferfv(GL_DEPTH, drawbuffer, &depth);
	clearBufferiv(GL_STENCIL, drawbuffer, &stencil);
}

void ReferenceContext::bindVertexArray (deUint32 array)
{
	rc::VertexArray* vertexArrayObject = DE_NULL;

	if (array != 0)
	{
		vertexArrayObject = m_vertexArrays.find(array);
		if (!vertexArrayObject)
		{
			vertexArrayObject = new rc::VertexArray(array, m_limits.maxVertexAttribs);
			m_vertexArrays.insert(vertexArrayObject);
		}
	}

	// Create new references
	if (vertexArrayObject)
		m_vertexArrays.acquireReference(vertexArrayObject);

	// Remove old references
	if (m_vertexArrayBinding)
		m_vertexArrays.releaseReference(m_vertexArrayBinding);

	m_vertexArrayBinding = vertexArrayObject;
}

void ReferenceContext::genVertexArrays (int numArrays, deUint32* vertexArrays)
{
	RC_IF_ERROR(!vertexArrays, GL_INVALID_VALUE, RC_RET_VOID);

	for (int ndx = 0; ndx < numArrays; ndx++)
		vertexArrays[ndx] = m_vertexArrays.allocateName();
}

void ReferenceContext::deleteVertexArrays (int numArrays, const deUint32* vertexArrays)
{
	for (int i = 0; i < numArrays; i++)
	{
		deUint32		name		= vertexArrays[i];
		VertexArray*	vertexArray	= name ? m_vertexArrays.find(name) : DE_NULL;

		if (vertexArray)
			deleteVertexArray(vertexArray);
	}
}

void ReferenceContext::vertexAttribPointer (deUint32 index, int rawSize, deUint32 type, deBool normalized, int stride, const void *pointer)
{
	const bool allowBGRA	= !glu::isContextTypeES(getType());
	const int effectiveSize	= (allowBGRA && rawSize == GL_BGRA) ? (4) : (rawSize);

	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(effectiveSize <= 0 || effectiveSize > 4, GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(type != GL_BYTE					&&	type != GL_UNSIGNED_BYTE	&&
				type != GL_SHORT				&&	type != GL_UNSIGNED_SHORT	&&
				type != GL_INT					&&	type != GL_UNSIGNED_INT		&&
				type != GL_FIXED				&&	type != GL_DOUBLE			&&
				type != GL_FLOAT				&&	type != GL_HALF_FLOAT		&&
				type != GL_INT_2_10_10_10_REV	&&	type != GL_UNSIGNED_INT_2_10_10_10_REV, GL_INVALID_ENUM, RC_RET_VOID);
	RC_IF_ERROR(normalized != GL_TRUE && normalized != GL_FALSE, GL_INVALID_ENUM, RC_RET_VOID);
	RC_IF_ERROR(stride < 0, GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && effectiveSize != 4, GL_INVALID_OPERATION, RC_RET_VOID);
	RC_IF_ERROR(m_vertexArrayBinding != DE_NULL && m_arrayBufferBinding == DE_NULL && pointer != DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
	RC_IF_ERROR(allowBGRA && rawSize == GL_BGRA && type != GL_INT_2_10_10_10_REV && type != GL_UNSIGNED_INT_2_10_10_10_REV && type != GL_UNSIGNED_BYTE, GL_INVALID_OPERATION, RC_RET_VOID);
	RC_IF_ERROR(allowBGRA && rawSize == GL_BGRA && normalized == GL_FALSE, GL_INVALID_OPERATION, RC_RET_VOID);

	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);

	vao.m_arrays[index].size			= rawSize;
	vao.m_arrays[index].stride			= stride;
	vao.m_arrays[index].type			= type;
	vao.m_arrays[index].normalized		= normalized == GL_TRUE;
	vao.m_arrays[index].integer			= false;
	vao.m_arrays[index].pointer			= pointer;

	// acquire new reference
	if (m_arrayBufferBinding)
		m_buffers.acquireReference(m_arrayBufferBinding);

	// release old reference
	if (vao.m_arrays[index].bufferBinding)
		m_buffers.releaseReference(vao.m_arrays[index].bufferBinding);

	vao.m_arrays[index].bufferDeleted	= false;
	vao.m_arrays[index].bufferBinding	= m_arrayBufferBinding;
}

void ReferenceContext::vertexAttribIPointer (deUint32 index, int size, deUint32 type, int stride, const void *pointer)
{
	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(size <= 0 || size > 4, GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(type != GL_BYTE					&&	type != GL_UNSIGNED_BYTE	&&
				type != GL_SHORT				&&	type != GL_UNSIGNED_SHORT	&&
				type != GL_INT					&&	type != GL_UNSIGNED_INT, GL_INVALID_ENUM, RC_RET_VOID);
	RC_IF_ERROR(stride < 0, GL_INVALID_VALUE, RC_RET_VOID);
	RC_IF_ERROR(m_vertexArrayBinding != DE_NULL && m_arrayBufferBinding == DE_NULL && pointer != DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);

	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);

	vao.m_arrays[index].size			= size;
	vao.m_arrays[index].stride			= stride;
	vao.m_arrays[index].type			= type;
	vao.m_arrays[index].normalized		= false;
	vao.m_arrays[index].integer			= true;
	vao.m_arrays[index].pointer			= pointer;

	// acquire new reference
	if (m_arrayBufferBinding)
		m_buffers.acquireReference(m_arrayBufferBinding);

	// release old reference
	if (vao.m_arrays[index].bufferBinding)
		m_buffers.releaseReference(vao.m_arrays[index].bufferBinding);

	vao.m_arrays[index].bufferDeleted	= false;
	vao.m_arrays[index].bufferBinding	= m_arrayBufferBinding;
}

void ReferenceContext::enableVertexAttribArray (deUint32 index)
{
	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);

	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
	vao.m_arrays[index].enabled = true;
}

void ReferenceContext::disableVertexAttribArray (deUint32 index)
{
	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);

	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
	vao.m_arrays[index].enabled = false;
}

void ReferenceContext::vertexAttribDivisor (deUint32 index, deUint32 divisor)
{
	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);

	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
	vao.m_arrays[index].divisor = divisor;
}

void ReferenceContext::vertexAttrib1f (deUint32 index, float x)
{
	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);

	m_currentAttribs[index] = rr::GenericVec4(tcu::Vec4(x, 0, 0, 1));
}

void ReferenceContext::vertexAttrib2f (deUint32 index, float x, float y)
{
	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);

	m_currentAttribs[index] = rr::GenericVec4(tcu::Vec4(x, y, 0, 1));
}

void ReferenceContext::vertexAttrib3f (deUint32 index, float x, float y, float z)
{
	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);

	m_currentAttribs[index] = rr::GenericVec4(tcu::Vec4(x, y, z, 1));
}

void ReferenceContext::vertexAttrib4f (deUint32 index, float x, float y, float z, float w)
{
	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);

	m_currentAttribs[index] = rr::GenericVec4(tcu::Vec4(x, y, z, w));
}

void ReferenceContext::vertexAttribI4i (deUint32 index, deInt32 x, deInt32 y, deInt32 z, deInt32 w)
{
	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);

	m_currentAttribs[index] = rr::GenericVec4(tcu::IVec4(x, y, z, w));
}

void ReferenceContext::vertexAttribI4ui (deUint32 index, deUint32 x, deUint32 y, deUint32 z, deUint32 w)
{
	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);

	m_currentAttribs[index] = rr::GenericVec4(tcu::UVec4(x, y, z, w));
}

deInt32 ReferenceContext::getAttribLocation (deUint32 program, const char *name)
{
	ShaderProgramObjectContainer* shaderProg = m_programs.find(program);

	RC_IF_ERROR(shaderProg == DE_NULL, GL_INVALID_OPERATION, -1);

	if (name)
	{
		std::string nameString(name);

		for (size_t ndx = 0; ndx < shaderProg->m_program->m_attributeNames.size(); ++ndx)
			if (shaderProg->m_program->m_attributeNames[ndx] == nameString)
				return (int)ndx;
	}

	return -1;
}

void ReferenceContext::uniformv (deInt32 location, glu::DataType type, deInt32 count, const void* v)
{
	RC_IF_ERROR(m_currentProgram == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);

	std::vector<sglr::UniformSlot>& uniforms = m_currentProgram->m_program->m_uniforms;

	if (location == -1)
		return;

	RC_IF_ERROR(location < 0 || (size_t)location >= uniforms.size(), GL_INVALID_OPERATION, RC_RET_VOID);
	RC_IF_ERROR(uniforms[location].type != type, GL_INVALID_OPERATION, RC_RET_VOID);
	RC_IF_ERROR(count != 1, GL_INVALID_OPERATION, RC_RET_VOID); // \todo [2013-12-13 pyry] Array uniforms.

	{
		const int scalarSize = glu::getDataTypeScalarSize(type);
		DE_ASSERT(scalarSize*sizeof(deUint32) <= sizeof(uniforms[location].value));
		deMemcpy(&uniforms[location].value, v, scalarSize*(int)sizeof(deUint32));
	}
}

void ReferenceContext::uniform1iv (deInt32 location, deInt32 count, const deInt32* v)
{
	RC_IF_ERROR(m_currentProgram == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);

	std::vector<sglr::UniformSlot>& uniforms = m_currentProgram->m_program->m_uniforms;

	if (location == -1)
		return;

	RC_IF_ERROR(location < 0 || (size_t)location >= uniforms.size(), GL_INVALID_OPERATION, RC_RET_VOID);
	RC_IF_ERROR(count != 1, GL_INVALID_OPERATION, RC_RET_VOID); // \todo [2013-12-13 pyry] Array uniforms.

	switch (uniforms[location].type)
	{
		case glu::TYPE_INT:		uniforms[location].value.i = *v;	return;

		// \note texture unit is stored to value
		case glu::TYPE_SAMPLER_2D:
		case glu::TYPE_UINT_SAMPLER_2D:
		case glu::TYPE_INT_SAMPLER_2D:
		case glu::TYPE_SAMPLER_CUBE:
		case glu::TYPE_UINT_SAMPLER_CUBE:
		case glu::TYPE_INT_SAMPLER_CUBE:
		case glu::TYPE_SAMPLER_2D_ARRAY:
		case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
		case glu::TYPE_INT_SAMPLER_2D_ARRAY:
		case glu::TYPE_SAMPLER_3D:
		case glu::TYPE_UINT_SAMPLER_3D:
		case glu::TYPE_INT_SAMPLER_3D:
		case glu::TYPE_SAMPLER_CUBE_ARRAY:
		case glu::TYPE_UINT_SAMPLER_CUBE_ARRAY:
		case glu::TYPE_INT_SAMPLER_CUBE_ARRAY:
			uniforms[location].value.i = *v;
			return;

		default:
			setError(GL_INVALID_OPERATION);
			return;
	}
}

void ReferenceContext::uniform1f (deInt32 location, const float v0)
{
	uniform1fv(location, 1, &v0);
}

void ReferenceContext::uniform1i (deInt32 location, deInt32 v0)
{
	uniform1iv(location, 1, &v0);
}

void ReferenceContext::uniform1fv (deInt32 location, deInt32 count, const float* v)
{
	uniformv(location, glu::TYPE_FLOAT, count, v);
}

void ReferenceContext::uniform2fv (deInt32 location, deInt32 count, const float* v)
{
	uniformv(location, glu::TYPE_FLOAT_VEC2, count, v);
}

void ReferenceContext::uniform3fv (deInt32 location, deInt32 count, const float* v)
{
	uniformv(location, glu::TYPE_FLOAT_VEC3, count, v);
}

void ReferenceContext::uniform4fv (deInt32 location, deInt32 count, const float* v)
{
	uniformv(location, glu::TYPE_FLOAT_VEC4, count, v);
}

void ReferenceContext::uniform2iv (deInt32 location, deInt32 count, const deInt32* v)
{
	uniformv(location, glu::TYPE_INT_VEC2, count, v);
}

void ReferenceContext::uniform3iv (deInt32 location, deInt32 count, const deInt32* v)
{
	uniformv(location, glu::TYPE_INT_VEC3, count, v);
}

void ReferenceContext::uniform4iv (deInt32 location, deInt32 count, const deInt32* v)
{
	uniformv(location, glu::TYPE_INT_VEC4, count, v);
}

void ReferenceContext::uniformMatrix3fv (deInt32 location, deInt32 count, deBool transpose, const float *value)
{
	RC_IF_ERROR(m_currentProgram == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);

	std::vector<sglr::UniformSlot>& uniforms = m_currentProgram->m_program->m_uniforms;

	if (location == -1)
		return;

	RC_IF_ERROR(location < 0 || (size_t)location >= uniforms.size(), GL_INVALID_OPERATION, RC_RET_VOID);

	if (count == 0)
		return;

	RC_IF_ERROR(transpose != GL_TRUE && transpose != GL_FALSE, GL_INVALID_ENUM, RC_RET_VOID);

	switch (uniforms[location].type)
	{
		case glu::TYPE_FLOAT_MAT3:
			RC_IF_ERROR(count > 1, GL_INVALID_OPERATION, RC_RET_VOID);

			if (transpose == GL_FALSE) // input is column major => transpose from column major to internal row major
				for (int row = 0; row < 3; ++row)
				for (int col = 0; col < 3; ++col)
					uniforms[location].value.m3[row*3+col] = value[col*3+row];
			else // input is row major
				for (int row = 0; row < 3; ++row)
				for (int col = 0; col < 3; ++col)
					uniforms[location].value.m3[row*3+col] = value[row*3+col];

			break;

		default:
			setError(GL_INVALID_OPERATION);
			return;
	}
}

void ReferenceContext::uniformMatrix4fv (deInt32 location, deInt32 count, deBool transpose, const float *value)
{
	RC_IF_ERROR(m_currentProgram == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);

	std::vector<sglr::UniformSlot>& uniforms = m_currentProgram->m_program->m_uniforms;

	if (location == -1)
		return;

	RC_IF_ERROR(location < 0 || (size_t)location >= uniforms.size(), GL_INVALID_OPERATION, RC_RET_VOID);

	if (count == 0)
		return;

	RC_IF_ERROR(transpose != GL_TRUE && transpose != GL_FALSE, GL_INVALID_ENUM, RC_RET_VOID);

	switch (uniforms[location].type)
	{
		case glu::TYPE_FLOAT_MAT4:
			RC_IF_ERROR(count > 1, GL_INVALID_OPERATION, RC_RET_VOID);

			if (transpose == GL_FALSE) // input is column major => transpose from column major to internal row major
				for (int row = 0; row < 4; ++row)
				for (int col = 0; col < 4; ++col)
					uniforms[location].value.m4[row*3+col] = value[col*3+row];
			else // input is row major
				for (int row = 0; row < 4; ++row)
				for (int col = 0; col < 4; ++col)
					uniforms[location].value.m4[row*3+col] = value[row*3+col];

			break;

		default:
			setError(GL_INVALID_OPERATION);
			return;
	}
}

deInt32 ReferenceContext::getUniformLocation (deUint32 program, const char *name)
{
	ShaderProgramObjectContainer* shaderProg = m_programs.find(program);
	RC_IF_ERROR(shaderProg == DE_NULL, GL_INVALID_OPERATION, -1);

	std::vector<sglr::UniformSlot>& uniforms = shaderProg->m_program->m_uniforms;

	for (size_t i = 0; i < uniforms.size(); ++i)
		if (name && deStringEqual(uniforms[i].name.c_str(), name))
			return (int)i;

	return -1;
}

void ReferenceContext::lineWidth (float w)
{
	RC_IF_ERROR(w < 0.0f, GL_INVALID_VALUE, RC_RET_VOID);
	m_lineWidth = w;
}

void ReferenceContext::deleteVertexArray (rc::VertexArray* vertexArray)
{
	if (m_vertexArrayBinding == vertexArray)
		bindVertexArray(0);

	if (vertexArray->m_elementArrayBufferBinding)
		m_buffers.releaseReference(vertexArray->m_elementArrayBufferBinding);

	for (size_t ndx = 0; ndx < vertexArray->m_arrays.size(); ++ndx)
		if (vertexArray->m_arrays[ndx].bufferBinding)
			m_buffers.releaseReference(vertexArray->m_arrays[ndx].bufferBinding);

	DE_ASSERT(vertexArray->getRefCount() == 1);
	m_vertexArrays.releaseReference(vertexArray);
}

void ReferenceContext::deleteProgramObject (rc::ShaderProgramObjectContainer* sp)
{
	// Unbinding program will delete it
	if (m_currentProgram == sp && sp->m_deleteFlag)
	{
		useProgram(0);
		return;
	}

	// Unbinding program will NOT delete it
	if (m_currentProgram == sp)
		useProgram(0);

	DE_ASSERT(sp->getRefCount() == 1);
	m_programs.releaseReference(sp);
}

void ReferenceContext::drawArrays (deUint32 mode, int first, int count)
{
	drawArraysInstanced(mode, first, count, 1);
}

void ReferenceContext::drawArraysInstanced (deUint32 mode, int first, int count, int instanceCount)
{
	// Error conditions
	{
		RC_IF_ERROR(first < 0 || count < 0 || instanceCount < 0, GL_INVALID_VALUE, RC_RET_VOID);

		if (!predrawErrorChecks(mode))
			return;
	}

	// All is ok
	{
		const rr::PrimitiveType primitiveType = sglr::rr_util::mapGLPrimitiveType(mode);

		drawWithReference(rr::PrimitiveList(primitiveType, count, first), instanceCount);
	}
}

void ReferenceContext::drawElements (deUint32 mode, int count, deUint32 type, const void *indices)
{
	drawElementsInstanced(mode, count, type, indices, 1);
}

void ReferenceContext::drawElementsBaseVertex (deUint32 mode, int count, deUint32 type, const void *indices, int baseVertex)
{
	drawElementsInstancedBaseVertex(mode, count, type, indices, 1, baseVertex);
}

void ReferenceContext::drawElementsInstanced (deUint32 mode, int count, deUint32 type, const void *indices, int instanceCount)
{
	drawElementsInstancedBaseVertex(mode, count, type, indices, instanceCount, 0);
}

void ReferenceContext::drawElementsInstancedBaseVertex (deUint32 mode, int count, deUint32 type, const void *indices, int instanceCount, int baseVertex)
{
	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);

	// Error conditions
	{
		RC_IF_ERROR(type != GL_UNSIGNED_BYTE &&
					type != GL_UNSIGNED_SHORT &&
					type != GL_UNSIGNED_INT, GL_INVALID_ENUM, RC_RET_VOID);
		RC_IF_ERROR(count < 0 || instanceCount < 0, GL_INVALID_VALUE, RC_RET_VOID);

		if (!predrawErrorChecks(mode))
			return;
	}

	// All is ok
	{
		const rr::PrimitiveType primitiveType	= sglr::rr_util::mapGLPrimitiveType(mode);
		const void*				indicesPtr		= (vao.m_elementArrayBufferBinding) ? (vao.m_elementArrayBufferBinding->getData() + reinterpret_cast<uintptr_t>(indices)) : (indices);

		drawWithReference(rr::PrimitiveList(primitiveType, count, rr::DrawIndices(indicesPtr, sglr::rr_util::mapGLIndexType(type), baseVertex)), instanceCount);
	}
}

void ReferenceContext::drawRangeElements (deUint32 mode, deUint32 start, deUint32 end, int count, deUint32 type, const void *indices)
{
	RC_IF_ERROR(end < start, GL_INVALID_VALUE, RC_RET_VOID);

	drawElements(mode, count, type, indices);
}

void ReferenceContext::drawRangeElementsBaseVertex (deUint32 mode, deUint32 start, deUint32 end, int count, deUint32 type, const void *indices, int baseVertex)
{
	RC_IF_ERROR(end < start, GL_INVALID_VALUE, RC_RET_VOID);

	drawElementsBaseVertex(mode, count, type, indices, baseVertex);
}

void ReferenceContext::drawArraysIndirect (deUint32 mode, const void *indirect)
{
	struct DrawArraysIndirectCommand
	{
		deUint32 count;
		deUint32 primCount;
		deUint32 first;
		deUint32 reservedMustBeZero;
	};

	const DrawArraysIndirectCommand* command;

	// Check errors

	if (!predrawErrorChecks(mode))
		return;

	// Check pointer validity

	RC_IF_ERROR(m_drawIndirectBufferBinding == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
	RC_IF_ERROR(!deIsAlignedPtr(indirect, 4), GL_INVALID_OPERATION, RC_RET_VOID);

	// \note watch for overflows, indirect might be close to 0xFFFFFFFF and indirect+something might overflow
	RC_IF_ERROR((size_t)reinterpret_cast<uintptr_t>(indirect)                                     > (size_t)m_drawIndirectBufferBinding->getSize(), GL_INVALID_OPERATION, RC_RET_VOID);
	RC_IF_ERROR((size_t)reinterpret_cast<uintptr_t>(indirect) + sizeof(DrawArraysIndirectCommand) > (size_t)m_drawIndirectBufferBinding->getSize(), GL_INVALID_OPERATION, RC_RET_VOID);

	// Check values

	command = (const DrawArraysIndirectCommand*)(m_drawIndirectBufferBinding->getData() + reinterpret_cast<uintptr_t>(indirect));
	RC_IF_ERROR(command->reservedMustBeZero != 0, GL_INVALID_OPERATION, RC_RET_VOID);

	// draw
	drawArraysInstanced(mode, command->first, command->count, command->primCount);
}

void ReferenceContext::drawElementsIndirect	(deUint32 mode, deUint32 type, const void *indirect)
{
	struct DrawElementsIndirectCommand
	{
		deUint32 count;
		deUint32 primCount;
		deUint32 firstIndex;
		deInt32  baseVertex;
		deUint32 reservedMustBeZero;
	};

	const DrawElementsIndirectCommand* command;

	// Check errors

	if (!predrawErrorChecks(mode))
		return;

	RC_IF_ERROR(type != GL_UNSIGNED_BYTE &&
				type != GL_UNSIGNED_SHORT &&
				type != GL_UNSIGNED_INT, GL_INVALID_ENUM, RC_RET_VOID);

	RC_IF_ERROR(!getBufferBinding(GL_ELEMENT_ARRAY_BUFFER), GL_INVALID_OPERATION, RC_RET_VOID);

	// Check pointer validity

	RC_IF_ERROR(m_drawIndirectBufferBinding == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
	RC_IF_ERROR(!deIsAlignedPtr(indirect, 4), GL_INVALID_OPERATION, RC_RET_VOID);

	// \note watch for overflows, indirect might be close to 0xFFFFFFFF and indirect+something might overflow
	RC_IF_ERROR((size_t)reinterpret_cast<uintptr_t>(indirect)                                       > (size_t)m_drawIndirectBufferBinding->getSize(), GL_INVALID_OPERATION, RC_RET_VOID);
	RC_IF_ERROR((size_t)reinterpret_cast<uintptr_t>(indirect) + sizeof(DrawElementsIndirectCommand) > (size_t)m_drawIndirectBufferBinding->getSize(), GL_INVALID_OPERATION, RC_RET_VOID);

	// Check values

	command = (const DrawElementsIndirectCommand*)(m_drawIndirectBufferBinding->getData() + reinterpret_cast<uintptr_t>(indirect));
	RC_IF_ERROR(command->reservedMustBeZero != 0, GL_INVALID_OPERATION, RC_RET_VOID);

	// Check command error conditions
	RC_IF_ERROR((int)command->count < 0 || (int)command->primCount < 0, GL_INVALID_VALUE, RC_RET_VOID);

	// Draw
	{
		const size_t			sizeOfType		= (type == GL_UNSIGNED_BYTE) ?  (1) : ((type == GL_UNSIGNED_SHORT) ? (2) : (4));
		const void*				indicesPtr		= glu::BufferOffsetAsPointer(command->firstIndex * sizeOfType);

		drawElementsInstancedBaseVertex(mode, (int)command->count, type, indicesPtr, (int)command->primCount, command->baseVertex);
	}
}

void ReferenceContext::multiDrawArrays (deUint32 mode, const int* first, const int* count, int primCount)
{
	DE_UNREF(mode);
	DE_UNREF(first);
	DE_UNREF(count);
	DE_UNREF(primCount);

	// not supported in gles, prevent accidental use
	DE_ASSERT(false);
}

void ReferenceContext::multiDrawElements (deUint32 mode, const int* count, deUint32 type, const void** indices, int primCount)
{
	DE_UNREF(mode);
	DE_UNREF(count);
	DE_UNREF(type);
	DE_UNREF(indices);
	DE_UNREF(primCount);

	// not supported in gles, prevent accidental use
	DE_ASSERT(false);
}

void ReferenceContext::multiDrawElementsBaseVertex (deUint32 mode, const int* count, deUint32 type, const void** indices, int primCount, const int* baseVertex)
{
	DE_UNREF(mode);
	DE_UNREF(count);
	DE_UNREF(type);
	DE_UNREF(indices);
	DE_UNREF(primCount);
	DE_UNREF(baseVertex);

	// not supported in gles, prevent accidental use
	DE_ASSERT(false);
}

bool ReferenceContext::predrawErrorChecks (deUint32 mode)
{
	RC_IF_ERROR(mode != GL_POINTS &&
				mode != GL_LINE_STRIP && mode != GL_LINE_LOOP && mode != GL_LINES &&
				mode != GL_TRIANGLE_STRIP && mode != GL_TRIANGLE_FAN && mode != GL_TRIANGLES &&
				mode != GL_LINES_ADJACENCY && mode != GL_LINE_STRIP_ADJACENCY &&
				mode != GL_TRIANGLES_ADJACENCY && mode != GL_TRIANGLE_STRIP_ADJACENCY,
				GL_INVALID_ENUM, false);

	// \todo [jarkko] Uncomment following code when the buffer mapping support is added
	//for (size_t ndx = 0; ndx < vao.m_arrays.size(); ++ndx)
	//	if (vao.m_arrays[ndx].enabled && vao.m_arrays[ndx].bufferBinding && vao.m_arrays[ndx].bufferBinding->isMapped)
	//		RC_ERROR_RET(GL_INVALID_OPERATION, RC_RET_VOID);

	RC_IF_ERROR(checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION, false);

	// Geometry shader checks
	if (m_currentProgram && m_currentProgram->m_program->m_hasGeometryShader)
	{
		RC_IF_ERROR(m_currentProgram->m_program->rr::GeometryShader::getInputType() == rr::GEOMETRYSHADERINPUTTYPE_POINTS && mode != GL_POINTS, GL_INVALID_OPERATION, false);

		RC_IF_ERROR(m_currentProgram->m_program->rr::GeometryShader::getInputType() == rr::GEOMETRYSHADERINPUTTYPE_LINES &&
			(mode != GL_LINES &&
			 mode != GL_LINE_STRIP &&
			 mode != GL_LINE_LOOP),
			 GL_INVALID_OPERATION, false);

		RC_IF_ERROR(m_currentProgram->m_program->rr::GeometryShader::getInputType() == rr::GEOMETRYSHADERINPUTTYPE_TRIANGLES &&
			(mode != GL_TRIANGLES &&
			 mode != GL_TRIANGLE_STRIP &&
			 mode != GL_TRIANGLE_FAN),
			 GL_INVALID_OPERATION, false);

		RC_IF_ERROR(m_currentProgram->m_program->rr::GeometryShader::getInputType() == rr::GEOMETRYSHADERINPUTTYPE_LINES_ADJACENCY &&
			(mode != GL_LINES_ADJACENCY &&
			 mode != GL_LINE_STRIP_ADJACENCY),
			 GL_INVALID_OPERATION, false);

		RC_IF_ERROR(m_currentProgram->m_program->rr::GeometryShader::getInputType() == rr::GEOMETRYSHADERINPUTTYPE_TRIANGLES_ADJACENCY &&
			(mode != GL_TRIANGLES_ADJACENCY &&
			 mode != GL_TRIANGLE_STRIP_ADJACENCY),
			 GL_INVALID_OPERATION, false);
	}

	return true;
}

static rr::PrimitiveType getPrimitiveBaseType (rr::PrimitiveType derivedType)
{
	switch (derivedType)
	{
		case rr::PRIMITIVETYPE_TRIANGLES:
		case rr::PRIMITIVETYPE_TRIANGLE_STRIP:
		case rr::PRIMITIVETYPE_TRIANGLE_FAN:
		case rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY:
		case rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY:
			return rr::PRIMITIVETYPE_TRIANGLES;

		case rr::PRIMITIVETYPE_LINES:
		case rr::PRIMITIVETYPE_LINE_STRIP:
		case rr::PRIMITIVETYPE_LINE_LOOP:
		case rr::PRIMITIVETYPE_LINES_ADJACENCY:
		case rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY:
			return rr::PRIMITIVETYPE_LINES;

		case rr::PRIMITIVETYPE_POINTS:
			return rr::PRIMITIVETYPE_POINTS;

		default:
			DE_ASSERT(false);
			return rr::PRIMITIVETYPE_LAST;
	}
}

static deUint32 getFixedRestartIndex (rr::IndexType indexType)
{
	switch (indexType)
	{
		case rr::INDEXTYPE_UINT8:		return 0xFF;
		case rr::INDEXTYPE_UINT16:		return 0xFFFF;
		case rr::INDEXTYPE_UINT32:		return 0xFFFFFFFFul;

		case rr::INDEXTYPE_LAST:
		default:
			DE_ASSERT(false);
			return 0;
	}
}

void ReferenceContext::drawWithReference (const rr::PrimitiveList& primitives, int instanceCount)
{
	// undefined results
	if (m_currentProgram == DE_NULL)
		return;

	rr::MultisamplePixelBufferAccess	colorBuf0	= getDrawColorbuffer();
	rr::MultisamplePixelBufferAccess	depthBuf	= getDepthMultisampleAccess(getDrawDepthbuffer());
	rr::MultisamplePixelBufferAccess	stencilBuf	= getStencilMultisampleAccess(getDrawStencilbuffer());
	const bool							hasStencil	= !isEmpty(stencilBuf);
	const int							stencilBits	= (hasStencil) ? (getNumStencilBits(stencilBuf.raw().getFormat())) : (0);

	const rr::RenderTarget				renderTarget(colorBuf0, depthBuf, stencilBuf);
	const rr::Program					program		(m_currentProgram->m_program->getVertexShader(),
													 m_currentProgram->m_program->getFragmentShader(),
													 (m_currentProgram->m_program->m_hasGeometryShader) ? (m_currentProgram->m_program->getGeometryShader()) : (DE_NULL));
	rr::RenderState						state		((rr::ViewportState)(colorBuf0), m_limits.subpixelBits);

	const rr::Renderer					referenceRenderer;
	std::vector<rr::VertexAttrib>		vertexAttribs;

	// Gen state
	{
		const rr::PrimitiveType	baseType							= getPrimitiveBaseType(primitives.getPrimitiveType());
		const bool				polygonOffsetEnabled				= (baseType == rr::PRIMITIVETYPE_TRIANGLES) ? (m_polygonOffsetFillEnabled) : (false);

		//state.cullMode											= m_cullMode

		state.fragOps.scissorTestEnabled							= m_scissorEnabled;
		state.fragOps.scissorRectangle								= rr::WindowRectangle(m_scissorBox.x(), m_scissorBox.y(), m_scissorBox.z(), m_scissorBox.w());

		state.fragOps.numStencilBits								= stencilBits;
		state.fragOps.stencilTestEnabled							= m_stencilTestEnabled;

		for (int faceType = 0; faceType < rr::FACETYPE_LAST; faceType++)
		{
			state.fragOps.stencilStates[faceType].compMask	= m_stencil[faceType].opMask;
			state.fragOps.stencilStates[faceType].writeMask	= m_stencil[faceType].writeMask;
			state.fragOps.stencilStates[faceType].ref		= m_stencil[faceType].ref;
			state.fragOps.stencilStates[faceType].func		= sglr::rr_util::mapGLTestFunc(m_stencil[faceType].func);
			state.fragOps.stencilStates[faceType].sFail		= sglr::rr_util::mapGLStencilOp(m_stencil[faceType].opStencilFail);
			state.fragOps.stencilStates[faceType].dpFail	= sglr::rr_util::mapGLStencilOp(m_stencil[faceType].opDepthFail);
			state.fragOps.stencilStates[faceType].dpPass	= sglr::rr_util::mapGLStencilOp(m_stencil[faceType].opDepthPass);
		}

		state.fragOps.depthTestEnabled								= m_depthTestEnabled;
		state.fragOps.depthFunc										= sglr::rr_util::mapGLTestFunc(m_depthFunc);
		state.fragOps.depthMask										= m_depthMask;

		state.fragOps.blendMode										= m_blendEnabled ? rr::BLENDMODE_STANDARD : rr::BLENDMODE_NONE;
		state.fragOps.blendRGBState.equation						= sglr::rr_util::mapGLBlendEquation(m_blendModeRGB);
		state.fragOps.blendRGBState.srcFunc							= sglr::rr_util::mapGLBlendFunc(m_blendFactorSrcRGB);
		state.fragOps.blendRGBState.dstFunc							= sglr::rr_util::mapGLBlendFunc(m_blendFactorDstRGB);
		state.fragOps.blendAState.equation							= sglr::rr_util::mapGLBlendEquation(m_blendModeAlpha);
		state.fragOps.blendAState.srcFunc							= sglr::rr_util::mapGLBlendFunc(m_blendFactorSrcAlpha);
		state.fragOps.blendAState.dstFunc							= sglr::rr_util::mapGLBlendFunc(m_blendFactorDstAlpha);
		state.fragOps.blendColor									= m_blendColor;

		state.fragOps.sRGBEnabled									= m_sRGBUpdateEnabled;

		state.fragOps.colorMask										= m_colorMask;

		state.fragOps.depthClampEnabled								= m_depthClampEnabled;

		state.viewport.rect											= rr::WindowRectangle(m_viewport.x(), m_viewport.y(), m_viewport.z(), m_viewport.w());
		state.viewport.zn											= m_depthRangeNear;
		state.viewport.zf											= m_depthRangeFar;

		//state.point.pointSize										= m_pointSize;
		state.line.lineWidth										= m_lineWidth;

		state.fragOps.polygonOffsetEnabled							= polygonOffsetEnabled;
		state.fragOps.polygonOffsetFactor							= m_polygonOffsetFactor;
		state.fragOps.polygonOffsetUnits							= m_polygonOffsetUnits;

		{
			const rr::IndexType indexType = primitives.getIndexType();

			if (m_primitiveRestartFixedIndex && indexType != rr::INDEXTYPE_LAST)
			{
				state.restart.enabled = true;
				state.restart.restartIndex = getFixedRestartIndex(indexType);
			}
			else if (m_primitiveRestartSettableIndex)
			{
				// \note PRIMITIVE_RESTART is active for non-indexed (DrawArrays) operations too.
				state.restart.enabled = true;
				state.restart.restartIndex = m_primitiveRestartIndex;
			}
			else
			{
				state.restart.enabled = false;
			}
		}

		state.provokingVertexConvention								= (m_provokingFirstVertexConvention) ? (rr::PROVOKINGVERTEX_FIRST) : (rr::PROVOKINGVERTEX_LAST);
	}

	// gen attributes
	{
		rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);

		vertexAttribs.resize(vao.m_arrays.size());
		for (size_t ndx = 0; ndx < vao.m_arrays.size(); ++ndx)
		{
			if (!vao.m_arrays[ndx].enabled)
			{
				vertexAttribs[ndx].type = rr::VERTEXATTRIBTYPE_DONT_CARE; // reading with wrong type is allowed, but results are undefined
				vertexAttribs[ndx].generic = m_currentAttribs[ndx];
			}
			else if (vao.m_arrays[ndx].bufferDeleted)
			{
				vertexAttribs[ndx].type = rr::VERTEXATTRIBTYPE_DONT_CARE; // reading from deleted buffer, output zeros
				vertexAttribs[ndx].generic = tcu::Vec4(0, 0, 0, 0);
			}
			else
			{
				vertexAttribs[ndx].type				= (vao.m_arrays[ndx].integer) ?
														(sglr::rr_util::mapGLPureIntegerVertexAttributeType(vao.m_arrays[ndx].type)) :
														(sglr::rr_util::mapGLFloatVertexAttributeType(vao.m_arrays[ndx].type, vao.m_arrays[ndx].normalized, vao.m_arrays[ndx].size, this->getType()));
				vertexAttribs[ndx].size				= sglr::rr_util::mapGLSize(vao.m_arrays[ndx].size);
				vertexAttribs[ndx].stride			= vao.m_arrays[ndx].stride;
				vertexAttribs[ndx].instanceDivisor	= vao.m_arrays[ndx].divisor;
				vertexAttribs[ndx].pointer			= (vao.m_arrays[ndx].bufferBinding) ? (vao.m_arrays[ndx].bufferBinding->getData() + reinterpret_cast<uintptr_t>(vao.m_arrays[ndx].pointer)) : (vao.m_arrays[ndx].pointer);
			}
		}
	}

	// Set shader samplers
	for (size_t uniformNdx = 0; uniformNdx < m_currentProgram->m_program->m_uniforms.size(); ++uniformNdx)
	{
		const tcu::Sampler::DepthStencilMode	depthStencilMode	= tcu::Sampler::MODE_DEPTH; // \todo[jarkko] support sampler state
		const int								texNdx				= m_currentProgram->m_program->m_uniforms[uniformNdx].value.i;

		switch (m_currentProgram->m_program->m_uniforms[uniformNdx].type)
		{
			case glu::TYPE_SAMPLER_1D:
			case glu::TYPE_UINT_SAMPLER_1D:
			case glu::TYPE_INT_SAMPLER_1D:
			{
				rc::Texture1D* tex = DE_NULL;

				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
					tex = (m_textureUnits[texNdx].tex1DBinding) ? (m_textureUnits[texNdx].tex1DBinding) : (&m_textureUnits[texNdx].default1DTex);

				if (tex && tex->isComplete())
				{
					tex->updateView(depthStencilMode);
					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex1D = tex;
				}
				else
					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex1D = &m_emptyTex1D;

				break;
			}
			case glu::TYPE_SAMPLER_2D:
			case glu::TYPE_UINT_SAMPLER_2D:
			case glu::TYPE_INT_SAMPLER_2D:
			{
				rc::Texture2D* tex = DE_NULL;

				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
					tex = (m_textureUnits[texNdx].tex2DBinding) ? (m_textureUnits[texNdx].tex2DBinding) : (&m_textureUnits[texNdx].default2DTex);

				if (tex && tex->isComplete())
				{
					tex->updateView(depthStencilMode);
					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex2D = tex;
				}
				else
					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex2D = &m_emptyTex2D;

				break;
			}
			case glu::TYPE_SAMPLER_CUBE:
			case glu::TYPE_UINT_SAMPLER_CUBE:
			case glu::TYPE_INT_SAMPLER_CUBE:
			{
				rc::TextureCube* tex = DE_NULL;

				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
					tex = (m_textureUnits[texNdx].texCubeBinding) ? (m_textureUnits[texNdx].texCubeBinding) : (&m_textureUnits[texNdx].defaultCubeTex);

				if (tex && tex->isComplete())
				{
					tex->updateView(depthStencilMode);
					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.texCube = tex;
				}
				else
					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.texCube = &m_emptyTexCube;

				break;
			}
			case glu::TYPE_SAMPLER_2D_ARRAY:
			case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
			case glu::TYPE_INT_SAMPLER_2D_ARRAY:
			{
				rc::Texture2DArray* tex = DE_NULL;

				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
					tex = (m_textureUnits[texNdx].tex2DArrayBinding) ? (m_textureUnits[texNdx].tex2DArrayBinding) : (&m_textureUnits[texNdx].default2DArrayTex);

				if (tex && tex->isComplete())
				{
					tex->updateView(depthStencilMode);
					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex2DArray = tex;
				}
				else
					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex2DArray = &m_emptyTex2DArray;

				break;
			}
			case glu::TYPE_SAMPLER_3D:
			case glu::TYPE_UINT_SAMPLER_3D:
			case glu::TYPE_INT_SAMPLER_3D:
			{
				rc::Texture3D* tex = DE_NULL;

				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
					tex = (m_textureUnits[texNdx].tex3DBinding) ? (m_textureUnits[texNdx].tex3DBinding) : (&m_textureUnits[texNdx].default3DTex);

				if (tex && tex->isComplete())
				{
					tex->updateView(depthStencilMode);
					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex3D = tex;
				}
				else
					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex3D = &m_emptyTex3D;

				break;
			}
			case glu::TYPE_SAMPLER_CUBE_ARRAY:
			case glu::TYPE_UINT_SAMPLER_CUBE_ARRAY:
			case glu::TYPE_INT_SAMPLER_CUBE_ARRAY:
			{
				rc::TextureCubeArray* tex = DE_NULL;

				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
					tex = (m_textureUnits[texNdx].texCubeArrayBinding) ? (m_textureUnits[texNdx].texCubeArrayBinding) : (&m_textureUnits[texNdx].defaultCubeArrayTex);

				if (tex && tex->isComplete())
				{
					tex->updateView(depthStencilMode);
					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.texCubeArray = tex;
				}
				else
					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.texCubeArray = &m_emptyTexCubeArray;

				break;
			}
			default:
				// nothing
				break;
		}
	}

	referenceRenderer.drawInstanced(rr::DrawCommand(state, renderTarget, program, (int)vertexAttribs.size(), &vertexAttribs[0], primitives), instanceCount);
}

deUint32 ReferenceContext::createProgram (ShaderProgram* program)
{
	int name = m_programs.allocateName();

	m_programs.insert(new rc::ShaderProgramObjectContainer(name, program));

	return name;
}

void ReferenceContext::useProgram (deUint32 program)
{
	rc::ShaderProgramObjectContainer* shaderProg			= DE_NULL;
	rc::ShaderProgramObjectContainer* programToBeDeleted	= DE_NULL;

	if (program)
	{
		shaderProg = m_programs.find(program);

		// shader has not been linked
		if (!shaderProg || shaderProg->m_deleteFlag)
			RC_ERROR_RET(GL_INVALID_OPERATION, RC_RET_VOID);
	}

	if (m_currentProgram && m_currentProgram->m_deleteFlag)
		programToBeDeleted = m_currentProgram;

	m_currentProgram = shaderProg;

	if (programToBeDeleted)
	{
		DE_ASSERT(programToBeDeleted->getRefCount() == 1);
		deleteProgramObject(programToBeDeleted);
	}
}

void ReferenceContext::deleteProgram (deUint32 program)
{
	if (!program)
		return;

	rc::ShaderProgramObjectContainer* shaderProg = m_programs.find(program);
	if (shaderProg)
	{
		if (shaderProg == m_currentProgram)
		{
			m_currentProgram->m_deleteFlag = true;
		}
		else
		{
			DE_ASSERT(shaderProg->getRefCount() == 1);
			m_programs.releaseReference(shaderProg);
		}
	}
}

void ReferenceContext::readPixels (int x, int y, int width, int height, deUint32 format, deUint32 type, void* data)
{
	rr::MultisamplePixelBufferAccess	src = getReadColorbuffer();
	TextureFormat						transferFmt;

	// Map transfer format.
	transferFmt = glu::mapGLTransferFormat(format, type);
	RC_IF_ERROR(transferFmt.order	== TextureFormat::CHANNELORDER_LAST ||
				transferFmt.type	== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);

	// Clamp input values
	const int copyX			= deClamp32(x,		0, src.raw().getHeight());
	const int copyY			= deClamp32(y,		0, src.raw().getDepth());
	const int copyWidth		= deClamp32(width,	0, src.raw().getHeight()-x);
	const int copyHeight	= deClamp32(height,	0, src.raw().getDepth()-y);

	PixelBufferAccess dst(transferFmt, width, height, 1, deAlign32(width*transferFmt.getPixelSize(), m_pixelPackAlignment), 0, getPixelPackPtr(data));
	rr::resolveMultisampleColorBuffer(tcu::getSubregion(dst, 0, 0, copyWidth, copyHeight), rr::getSubregion(src, copyX, copyY, copyWidth, copyHeight));
}

deUint32 ReferenceContext::getError (void)
{
	deUint32 err = m_lastError;
	m_lastError = GL_NO_ERROR;
	return err;
}

void ReferenceContext::finish (void)
{
}

inline void ReferenceContext::setError (deUint32 error)
{
	if (m_lastError == GL_NO_ERROR)
		m_lastError = error;
}

void ReferenceContext::getIntegerv (deUint32 pname, int* param)
{
	switch (pname)
	{
		case GL_MAX_TEXTURE_SIZE:			*param = m_limits.maxTexture2DSize;			break;
		case GL_MAX_CUBE_MAP_TEXTURE_SIZE:	*param = m_limits.maxTextureCubeSize;		break;
		case GL_MAX_ARRAY_TEXTURE_LAYERS:	*param = m_limits.maxTexture2DArrayLayers;	break;
		case GL_MAX_3D_TEXTURE_SIZE:		*param = m_limits.maxTexture3DSize;			break;
		case GL_MAX_RENDERBUFFER_SIZE:		*param = m_limits.maxRenderbufferSize;		break;
		case GL_MAX_TEXTURE_IMAGE_UNITS:	*param = m_limits.maxTextureImageUnits;		break;
		case GL_MAX_VERTEX_ATTRIBS:			*param = m_limits.maxVertexAttribs;			break;

		default:
			setError(GL_INVALID_ENUM);
			break;
	}
}

const char* ReferenceContext::getString (deUint32 pname)
{
	switch (pname)
	{
		case GL_EXTENSIONS:		return m_limits.extensionStr.c_str();

		default:
			setError(GL_INVALID_ENUM);
			return DE_NULL;
	}
}

namespace rc
{

TextureLevelArray::TextureLevelArray (void)
{
}

TextureLevelArray::~TextureLevelArray (void)
{
	clear();
}

void TextureLevelArray::clear (void)
{
	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(m_data) == DE_LENGTH_OF_ARRAY(m_access));

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(m_data); ndx++)
	{
		m_data[ndx].clear();
		m_access[ndx] = PixelBufferAccess();
	}
}

void TextureLevelArray::allocLevel (int level, const tcu::TextureFormat& format, int width, int height, int depth)
{
	const int dataSize = format.getPixelSize()*width*height*depth;

	DE_ASSERT(deInBounds32(level, 0, DE_LENGTH_OF_ARRAY(m_data)));

	if (hasLevel(level))
		clearLevel(level);

	m_data[level].setStorage(dataSize);
	m_access[level] = PixelBufferAccess(format, width, height, depth, m_data[level].getPtr());
}

void TextureLevelArray::clearLevel (int level)
{
	DE_ASSERT(deInBounds32(level, 0, DE_LENGTH_OF_ARRAY(m_data)));

	m_data[level].clear();
	m_access[level] = PixelBufferAccess();
}

void TextureLevelArray::updateSamplerMode (tcu::Sampler::DepthStencilMode mode)
{
	for (int levelNdx = 0; hasLevel(levelNdx); ++levelNdx)
		m_effectiveAccess[levelNdx] = tcu::getEffectiveDepthStencilAccess(m_access[levelNdx], mode);
}

Texture::Texture (deUint32 name, Type type, deBool seamless)
	: NamedObject	(name)
	, m_type		(type)
	, m_immutable	(false)
	, m_sampler		(tcu::Sampler::REPEAT_GL,
					 tcu::Sampler::REPEAT_GL,
					 tcu::Sampler::REPEAT_GL,
					 tcu::Sampler::NEAREST_MIPMAP_LINEAR,
					 tcu::Sampler::LINEAR,
					 0.0f,				// LOD threshold
					 true,				// normalized coords
					 tcu::Sampler::COMPAREMODE_NONE,
					 0,					// cmp channel ndx
					 tcu::Vec4(0.0f),	// border color
					 seamless			// seamless cube map, Default value is True.
					 )
	, m_baseLevel	(0)
	, m_maxLevel	(1000)
{
}

Texture1D::Texture1D (deUint32 name)
	: Texture	(name, TYPE_1D)
	, m_view	(0, DE_NULL)
{
}

Texture1D::~Texture1D (void)
{
}

void Texture1D::allocLevel (int level, const tcu::TextureFormat& format, int width)
{
	m_levels.allocLevel(level, format, width, 1, 1);
}

bool Texture1D::isComplete (void) const
{
	const int	baseLevel	= getBaseLevel();

	if (hasLevel(baseLevel))
	{
		const tcu::ConstPixelBufferAccess&	level0		= getLevel(baseLevel);
		const bool							mipmap		= isMipmapFilter(getSampler().minFilter);

		if (mipmap)
		{
			const TextureFormat&	format		= level0.getFormat();
			const int				w			= level0.getWidth();
			const int				numLevels	= de::min(getMaxLevel()-baseLevel+1, getNumMipLevels1D(w));

			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
			{
				if (hasLevel(baseLevel+levelNdx))
				{
					const tcu::ConstPixelBufferAccess&	level		= getLevel(baseLevel+levelNdx);
					const int							expectedW	= getMipLevelSize(w, levelNdx);

					if (level.getWidth()	!= expectedW	||
						level.getFormat()	!= format)
						return false;
				}
				else
					return false;
			}
		}

		return true;
	}
	else
		return false;
}

tcu::Vec4 Texture1D::sample (float s, float lod) const
{
	return m_view.sample(getSampler(), s, 0.0f, lod);
}

void Texture1D::sample4 (tcu::Vec4 output[4], const float packetTexcoords[4], float lodBias) const
{
	const float texWidth = (float)m_view.getWidth();

	const float dFdx0 = packetTexcoords[1] - packetTexcoords[0];
	const float dFdx1 = packetTexcoords[3] - packetTexcoords[2];
	const float dFdy0 = packetTexcoords[2] - packetTexcoords[0];
	const float dFdy1 = packetTexcoords[3] - packetTexcoords[1];

	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
	{
		const float& dFdx = (fragNdx > 2) ? dFdx1 : dFdx0;
		const float& dFdy = (fragNdx % 2) ? dFdy1 : dFdy0;

		const float mu = de::max(de::abs(dFdx), de::abs(dFdy));
		const float p = mu * texWidth;

		const float	lod = deFloatLog2(p) + lodBias;

		output[fragNdx] = sample(packetTexcoords[fragNdx], lod);
	}
}

void Texture1D::updateView (tcu::Sampler::DepthStencilMode mode)
{
	const int baseLevel	= getBaseLevel();

	if (hasLevel(baseLevel) && !isEmpty(getLevel(baseLevel)))
	{
		const int	width		= getLevel(baseLevel).getWidth();
		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels1D(width)) : 1;

		m_levels.updateSamplerMode(mode);
		m_view = tcu::Texture2DView(numLevels, m_levels.getEffectiveLevels() + baseLevel);
	}
	else
		m_view = tcu::Texture2DView(0, DE_NULL);
}

Texture2D::Texture2D (deUint32 name, bool es2)
	: Texture	(name, TYPE_2D)
	, m_view	(0, DE_NULL, es2)
{
}

Texture2D::~Texture2D (void)
{
}

void Texture2D::allocLevel (int level, const tcu::TextureFormat& format, int width, int height)
{
	m_levels.allocLevel(level, format, width, height, 1);
}

bool Texture2D::isComplete (void) const
{
	const int	baseLevel	= getBaseLevel();

	if (hasLevel(baseLevel))
	{
		const tcu::ConstPixelBufferAccess&	level0		= getLevel(baseLevel);
		const bool							mipmap		= isMipmapFilter(getSampler().minFilter);

		if (mipmap)
		{
			const TextureFormat&	format		= level0.getFormat();
			const int				w			= level0.getWidth();
			const int				h			= level0.getHeight();
			const int				numLevels	= de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(w, h));

			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
			{
				if (hasLevel(baseLevel+levelNdx))
				{
					const tcu::ConstPixelBufferAccess&	level		= getLevel(baseLevel+levelNdx);
					const int							expectedW	= getMipLevelSize(w, levelNdx);
					const int							expectedH	= getMipLevelSize(h, levelNdx);

					if (level.getWidth()	!= expectedW	||
						level.getHeight()	!= expectedH	||
						level.getFormat()	!= format)
						return false;
				}
				else
					return false;
			}
		}

		return true;
	}
	else
		return false;
}

void Texture2D::updateView (tcu::Sampler::DepthStencilMode mode)
{
	const int baseLevel	= getBaseLevel();

	if (hasLevel(baseLevel) && !isEmpty(getLevel(baseLevel)))
	{
		// Update number of levels in mipmap pyramid.
		const int	width		= getLevel(baseLevel).getWidth();
		const int	height		= getLevel(baseLevel).getHeight();
		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(width, height)) : 1;

		m_levels.updateSamplerMode(mode);
		m_view = tcu::Texture2DView(numLevels, m_levels.getEffectiveLevels() + baseLevel);
	}
	else
		m_view = tcu::Texture2DView(0, DE_NULL);
}

tcu::Vec4 Texture2D::sample (float s, float t, float lod) const
{
	return m_view.sample(getSampler(), s, t, lod);
}

void Texture2D::sample4 (tcu::Vec4 output[4], const tcu::Vec2 packetTexcoords[4], float lodBias) const
{
	const float texWidth  = (float)m_view.getWidth();
	const float texHeight = (float)m_view.getHeight();

	const tcu::Vec2 dFdx0 = packetTexcoords[1] - packetTexcoords[0];
	const tcu::Vec2 dFdx1 = packetTexcoords[3] - packetTexcoords[2];
	const tcu::Vec2 dFdy0 = packetTexcoords[2] - packetTexcoords[0];
	const tcu::Vec2 dFdy1 = packetTexcoords[3] - packetTexcoords[1];

	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
	{
		const tcu::Vec2& dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
		const tcu::Vec2& dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;

		const float mu = de::max(de::abs(dFdx.x()), de::abs(dFdy.x()));
		const float mv = de::max(de::abs(dFdx.y()), de::abs(dFdy.y()));
		const float p = de::max(mu * texWidth, mv * texHeight);

		const float	lod = deFloatLog2(p) + lodBias;

		output[fragNdx] = sample(packetTexcoords[fragNdx].x(), packetTexcoords[fragNdx].y(), lod);
	}
}

TextureCube::TextureCube (deUint32 name, deBool seamless)
	: Texture(name, TYPE_CUBE_MAP, seamless)
{
}

TextureCube::~TextureCube (void)
{
}

void TextureCube::clearLevels (void)
{
	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
		m_levels[face].clear();
}

void TextureCube::allocFace (int level, tcu::CubeFace face, const tcu::TextureFormat& format, int width, int height)
{
	m_levels[face].allocLevel(level, format, width, height, 1);
}

bool TextureCube::isComplete (void) const
{
	const int	baseLevel	= getBaseLevel();

	if (hasFace(baseLevel, tcu::CUBEFACE_NEGATIVE_X))
	{
		const int					width		= getFace(baseLevel, tcu::CUBEFACE_NEGATIVE_X).getWidth();
		const int					height		= getFace(baseLevel, tcu::CUBEFACE_NEGATIVE_X).getHeight();
		const tcu::TextureFormat&	format		= getFace(baseLevel, tcu::CUBEFACE_NEGATIVE_X).getFormat();
		const bool					mipmap		= isMipmapFilter(getSampler().minFilter);
		const int					numLevels	= mipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(width, height)) : 1;

		if (width != height)
			return false; // Non-square is not supported.

		// \note Level 0 is always checked for consistency
		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
		{
			const int levelW	= getMipLevelSize(width,	levelNdx);
			const int levelH	= getMipLevelSize(height,	levelNdx);

			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
			{
				if (hasFace(baseLevel+levelNdx, (tcu::CubeFace)face))
				{
					const tcu::ConstPixelBufferAccess& level = getFace(baseLevel+levelNdx, (tcu::CubeFace)face);

					if (level.getWidth()	!= levelW	||
						level.getHeight()	!= levelH	||
						level.getFormat()	!= format)
						return false;
				}
				else
					return false;
			}
		}

		return true;
	}
	else
		return false;
}

void TextureCube::updateView (tcu::Sampler::DepthStencilMode mode)
{
	const int							baseLevel	= getBaseLevel();
	const tcu::ConstPixelBufferAccess*	faces[tcu::CUBEFACE_LAST];

	deMemset(&faces[0], 0, sizeof(faces));

	if (isComplete())
	{
		const int	size		= getFace(baseLevel, tcu::CUBEFACE_NEGATIVE_X).getWidth();
		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels1D(size)) : 1;

		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
		{
			m_levels[face].updateSamplerMode(mode);
			faces[face] = m_levels[face].getEffectiveLevels() + baseLevel;
		}

		m_view = tcu::TextureCubeView(numLevels, faces);
	}
	else
		m_view = tcu::TextureCubeView(0, faces);
}

tcu::Vec4 TextureCube::sample (float s, float t, float p, float lod) const
{
	return m_view.sample(getSampler(), s, t, p, lod);
}

void TextureCube::sample4 (tcu::Vec4 output[4], const tcu::Vec3 packetTexcoords[4], float lodBias) const
{
	const float cubeSide = (float)m_view.getSize();

	// Each tex coord might be in a different face.

	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
	{
		const tcu::CubeFace face		= tcu::selectCubeFace(packetTexcoords[fragNdx]);
		const tcu::Vec2		coords[4]	=
		{
			tcu::projectToFace(face, packetTexcoords[0]),
			tcu::projectToFace(face, packetTexcoords[1]),
			tcu::projectToFace(face, packetTexcoords[2]),
			tcu::projectToFace(face, packetTexcoords[3]),
		};

		const tcu::Vec2 dFdx0 = coords[1] - coords[0];
		const tcu::Vec2 dFdx1 = coords[3] - coords[2];
		const tcu::Vec2 dFdy0 = coords[2] - coords[0];
		const tcu::Vec2 dFdy1 = coords[3] - coords[1];

		const tcu::Vec2& dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
		const tcu::Vec2& dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;

		const float mu = de::max(de::abs(dFdx.x()), de::abs(dFdy.x()));
		const float mv = de::max(de::abs(dFdx.y()), de::abs(dFdy.y()));
		const float p = de::max(mu * cubeSide, mv * cubeSide);

		const float	lod = deFloatLog2(p) + lodBias;

		output[fragNdx] = sample(packetTexcoords[fragNdx].x(), packetTexcoords[fragNdx].y(), packetTexcoords[fragNdx].z(), lod);
	}
}

Texture2DArray::Texture2DArray (deUint32 name)
	: Texture	(name, TYPE_2D_ARRAY)
	, m_view	(0, DE_NULL)
{
}

Texture2DArray::~Texture2DArray (void)
{
}

void Texture2DArray::allocLevel (int level, const tcu::TextureFormat& format, int width, int height, int numLayers)
{
	m_levels.allocLevel(level, format, width, height, numLayers);
}

bool Texture2DArray::isComplete (void) const
{
	const int	baseLevel	= getBaseLevel();

	if (hasLevel(baseLevel))
	{
		const tcu::ConstPixelBufferAccess&	level0		= getLevel(baseLevel);
		const bool							mipmap		= isMipmapFilter(getSampler().minFilter);

		if (mipmap)
		{
			const TextureFormat&	format		= level0.getFormat();
			const int				w			= level0.getWidth();
			const int				h			= level0.getHeight();
			const int				numLayers	= level0.getDepth();
			const int				numLevels	= de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(w, h));

			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
			{
				if (hasLevel(baseLevel+levelNdx))
				{
					const tcu::ConstPixelBufferAccess&	level		= getLevel(baseLevel+levelNdx);
					const int							expectedW	= getMipLevelSize(w, levelNdx);
					const int							expectedH	= getMipLevelSize(h, levelNdx);

					if (level.getWidth()	!= expectedW	||
						level.getHeight()	!= expectedH	||
						level.getDepth()	!= numLayers	||
						level.getFormat()	!= format)
						return false;
				}
				else
					return false;
			}
		}

		return true;
	}
	else
		return false;
}

void Texture2DArray::updateView (tcu::Sampler::DepthStencilMode mode)
{
	const int baseLevel	= getBaseLevel();

	if (hasLevel(baseLevel) && !isEmpty(getLevel(baseLevel)))
	{
		const int	width		= getLevel(baseLevel).getWidth();
		const int	height		= getLevel(baseLevel).getHeight();
		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(width, height)) : 1;

		m_levels.updateSamplerMode(mode);
		m_view = tcu::Texture2DArrayView(numLevels, m_levels.getEffectiveLevels() + baseLevel);
	}
	else
		m_view = tcu::Texture2DArrayView(0, DE_NULL);
}

tcu::Vec4 Texture2DArray::sample (float s, float t, float r, float lod) const
{
	return m_view.sample(getSampler(), s, t, r, lod);
}

void Texture2DArray::sample4 (tcu::Vec4 output[4], const tcu::Vec3 packetTexcoords[4], float lodBias) const
{
	const float texWidth  = (float)m_view.getWidth();
	const float texHeight = (float)m_view.getHeight();

	const tcu::Vec3 dFdx0 = packetTexcoords[1] - packetTexcoords[0];
	const tcu::Vec3 dFdx1 = packetTexcoords[3] - packetTexcoords[2];
	const tcu::Vec3 dFdy0 = packetTexcoords[2] - packetTexcoords[0];
	const tcu::Vec3 dFdy1 = packetTexcoords[3] - packetTexcoords[1];

	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
	{
		const tcu::Vec3& dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
		const tcu::Vec3& dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;

		const float mu = de::max(de::abs(dFdx.x()), de::abs(dFdy.x()));
		const float mv = de::max(de::abs(dFdx.y()), de::abs(dFdy.y()));
		const float p = de::max(mu * texWidth, mv * texHeight);

		const float	lod = deFloatLog2(p) + lodBias;

		output[fragNdx] = sample(packetTexcoords[fragNdx].x(), packetTexcoords[fragNdx].y(), packetTexcoords[fragNdx].z(), lod);
	}
}

TextureCubeArray::TextureCubeArray (deUint32 name)
	: Texture	(name, TYPE_CUBE_MAP_ARRAY)
	, m_view	(0, DE_NULL)
{
}

TextureCubeArray::~TextureCubeArray (void)
{
}

void TextureCubeArray::allocLevel (int level, const tcu::TextureFormat& format, int width, int height, int numLayers)
{
	DE_ASSERT(numLayers % 6 == 0);
	m_levels.allocLevel(level, format, width, height, numLayers);
}

bool TextureCubeArray::isComplete (void) const
{
	const int	baseLevel	= getBaseLevel();

	if (hasLevel(baseLevel))
	{
		const tcu::ConstPixelBufferAccess&	level0		= getLevel(baseLevel);
		const bool							mipmap		= isMipmapFilter(getSampler().minFilter);

		if (mipmap)
		{
			const TextureFormat&	format		= level0.getFormat();
			const int				w			= level0.getWidth();
			const int				h			= level0.getHeight();
			const int				numLayers	= level0.getDepth();
			const int				numLevels	= de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(w, h));

			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
			{
				if (hasLevel(baseLevel+levelNdx))
				{
					const tcu::ConstPixelBufferAccess&	level		= getLevel(baseLevel+levelNdx);
					const int							expectedW	= getMipLevelSize(w, levelNdx);
					const int							expectedH	= getMipLevelSize(h, levelNdx);

					if (level.getWidth()	!= expectedW	||
						level.getHeight()	!= expectedH	||
						level.getDepth()	!= numLayers	||
						level.getFormat()	!= format)
						return false;
				}
				else
					return false;
			}
		}

		return true;
	}
	else
		return false;
}

void TextureCubeArray::updateView (tcu::Sampler::DepthStencilMode mode)
{
	const int baseLevel	= getBaseLevel();

	if (hasLevel(baseLevel) && !isEmpty(getLevel(baseLevel)))
	{
		const int	width		= getLevel(baseLevel).getWidth();
		const int	height		= getLevel(baseLevel).getHeight();
		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(width, height)) : 1;

		m_levels.updateSamplerMode(mode);
		m_view = tcu::TextureCubeArrayView(numLevels, m_levels.getEffectiveLevels() + baseLevel);
	}
	else
		m_view = tcu::TextureCubeArrayView(0, DE_NULL);
}

tcu::Vec4 TextureCubeArray::sample (float s, float t, float r, float q, float lod) const
{
	return m_view.sample(getSampler(), s, t, r, q, lod);
}

void TextureCubeArray::sample4 (tcu::Vec4 output[4], const tcu::Vec4 packetTexcoords[4], float lodBias) const
{
	const float		cubeSide		= (float)m_view.getSize();
	const tcu::Vec3	cubeCoords[4]	=
	{
		packetTexcoords[0].toWidth<3>(),
		packetTexcoords[1].toWidth<3>(),
		packetTexcoords[2].toWidth<3>(),
		packetTexcoords[3].toWidth<3>()
	};

	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
	{
		const tcu::CubeFace face			= tcu::selectCubeFace(cubeCoords[fragNdx]);
		const tcu::Vec2		faceCoords[4]	=
		{
			tcu::projectToFace(face, cubeCoords[0]),
			tcu::projectToFace(face, cubeCoords[1]),
			tcu::projectToFace(face, cubeCoords[2]),
			tcu::projectToFace(face, cubeCoords[3]),
		};

		const tcu::Vec2 dFdx0 = faceCoords[1] - faceCoords[0];
		const tcu::Vec2 dFdx1 = faceCoords[3] - faceCoords[2];
		const tcu::Vec2 dFdy0 = faceCoords[2] - faceCoords[0];
		const tcu::Vec2 dFdy1 = faceCoords[3] - faceCoords[1];

		const tcu::Vec2& dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
		const tcu::Vec2& dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;

		const float mu = de::max(de::abs(dFdx.x()), de::abs(dFdy.x()));
		const float mv = de::max(de::abs(dFdx.y()), de::abs(dFdy.y()));
		const float p = de::max(mu * cubeSide, mv * cubeSide);

		const float	lod = deFloatLog2(p) + lodBias;

		output[fragNdx] = sample(packetTexcoords[fragNdx].x(), packetTexcoords[fragNdx].y(), packetTexcoords[fragNdx].z(), packetTexcoords[fragNdx].w(), lod);
	}
}

Texture3D::Texture3D (deUint32 name)
	: Texture	(name, TYPE_3D)
	, m_view	(0, DE_NULL)
{
}

Texture3D::~Texture3D (void)
{
}

void Texture3D::allocLevel (int level, const tcu::TextureFormat& format, int width, int height, int depth)
{
	m_levels.allocLevel(level, format, width, height, depth);
}

bool Texture3D::isComplete (void) const
{
	const int	baseLevel	= getBaseLevel();

	if (hasLevel(baseLevel))
	{
		const tcu::ConstPixelBufferAccess&	level0		= getLevel(baseLevel);
		const bool							mipmap		= isMipmapFilter(getSampler().minFilter);

		if (mipmap)
		{
			const TextureFormat&	format		= level0.getFormat();
			const int				w			= level0.getWidth();
			const int				h			= level0.getHeight();
			const int				d			= level0.getDepth();
			const int				numLevels	= de::min(getMaxLevel()-baseLevel+1, getNumMipLevels3D(w, h, d));

			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
			{
				if (hasLevel(baseLevel+levelNdx))
				{
					const tcu::ConstPixelBufferAccess&	level		= getLevel(baseLevel+levelNdx);
					const int							expectedW	= getMipLevelSize(w, levelNdx);
					const int							expectedH	= getMipLevelSize(h, levelNdx);
					const int							expectedD	= getMipLevelSize(d, levelNdx);

					if (level.getWidth()	!= expectedW	||
						level.getHeight()	!= expectedH	||
						level.getDepth()	!= expectedD	||
						level.getFormat()	!= format)
						return false;
				}
				else
					return false;
			}
		}

		return true;
	}
	else
		return false;
}

tcu::Vec4 Texture3D::sample (float s, float t, float r, float lod) const
{
	return m_view.sample(getSampler(), s, t, r, lod);
}

void Texture3D::sample4 (tcu::Vec4 output[4], const tcu::Vec3 packetTexcoords[4], float lodBias) const
{
	const float texWidth  = (float)m_view.getWidth();
	const float texHeight = (float)m_view.getHeight();
	const float texDepth  = (float)m_view.getDepth();

	const tcu::Vec3 dFdx0 = packetTexcoords[1] - packetTexcoords[0];
	const tcu::Vec3 dFdx1 = packetTexcoords[3] - packetTexcoords[2];
	const tcu::Vec3 dFdy0 = packetTexcoords[2] - packetTexcoords[0];
	const tcu::Vec3 dFdy1 = packetTexcoords[3] - packetTexcoords[1];

	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
	{
		const tcu::Vec3& dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
		const tcu::Vec3& dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;

		const float mu = de::max(de::abs(dFdx.x()), de::abs(dFdy.x()));
		const float mv = de::max(de::abs(dFdx.y()), de::abs(dFdy.y()));
		const float mw = de::max(de::abs(dFdx.z()), de::abs(dFdy.z()));
		const float p = de::max(de::max(mu * texWidth, mv * texHeight), mw * texDepth);

		const float	lod = deFloatLog2(p) + lodBias;

		output[fragNdx] = sample(packetTexcoords[fragNdx].x(), packetTexcoords[fragNdx].y(), packetTexcoords[fragNdx].z(), lod);
	}
}

void Texture3D::updateView (tcu::Sampler::DepthStencilMode mode)
{
	const int baseLevel	= getBaseLevel();

	if (hasLevel(baseLevel) && !isEmpty(getLevel(baseLevel)))
	{
		const int	width		= getLevel(baseLevel).getWidth();
		const int	height		= getLevel(baseLevel).getHeight();
		const int	depth		= getLevel(baseLevel).getDepth();
		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels3D(width, height, depth)) : 1;

		m_levels.updateSamplerMode(mode);
		m_view = tcu::Texture3DView(numLevels, m_levels.getEffectiveLevels() + baseLevel);
	}
	else
		m_view = tcu::Texture3DView(0, DE_NULL);
}

Renderbuffer::Renderbuffer (deUint32 name)
	: NamedObject		(name)
{
}

Renderbuffer::~Renderbuffer (void)
{
}

void Renderbuffer::setStorage (const TextureFormat& format, int width, int height)
{
	m_data.setStorage(format, width, height);
}

Framebuffer::Framebuffer (deUint32 name)
	: NamedObject(name)
{
}

Framebuffer::~Framebuffer (void)
{
}

VertexArray::VertexArray (deUint32 name, int maxVertexAttribs)
	: NamedObject					(name)
	, m_elementArrayBufferBinding	(DE_NULL)
	, m_arrays						(maxVertexAttribs)
{
	for (int i = 0; i < maxVertexAttribs; ++i)
	{
		m_arrays[i].enabled			= false;
		m_arrays[i].size			= 4;
		m_arrays[i].stride			= 0;
		m_arrays[i].type			= GL_FLOAT;
		m_arrays[i].normalized		= false;
		m_arrays[i].integer			= false;
		m_arrays[i].divisor			= 0;
		m_arrays[i].bufferDeleted	= false;
		m_arrays[i].bufferBinding	= DE_NULL;
		m_arrays[i].pointer			= DE_NULL;
	}
}

ShaderProgramObjectContainer::ShaderProgramObjectContainer (deUint32 name, ShaderProgram* program)
	: NamedObject	(name)
	, m_program		(program)
	, m_deleteFlag	(false)
{
}

ShaderProgramObjectContainer::~ShaderProgramObjectContainer (void)
{
}

} // rc
} // sglr
