13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES Utilities
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Reference Rendering Context.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "sglrReferenceContext.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "sglrReferenceUtils.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "sglrShaderProgram.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuMatrix.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuMatrixUtil.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluDefs.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTextureUtil.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMemory.h"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rrFragmentOperations.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "rrRenderer.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace sglr
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::map;
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec2;
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec3;
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4;
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec2;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec4;
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::RGBA;
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Reference context implementation
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace rc;
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TextureFormat;
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::PixelBufferAccess;
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::ConstPixelBufferAccess;
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Utilities for ReferenceContext
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define RC_RET_VOID
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define RC_ERROR_RET(ERR, RET)			\
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrydo {									\
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setError(ERR);						\
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return RET;							\
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} while (deGetFalse())
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define RC_IF_ERROR(COND, ERR, RET)		\
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrydo {									\
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (COND)							\
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(ERR, RET);			\
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} while (deGetFalse())
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::PixelBufferAccess nullAccess (void)
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::PixelBufferAccess(TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT8), 0, 0, 0, DE_NULL);
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool isEmpty (const tcu::ConstPixelBufferAccess& access)
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return access.getWidth() == 0 || access.getHeight() == 0 || access.getDepth() == 0;
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool isEmpty (const rr::MultisampleConstPixelBufferAccess& access)
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return access.raw().getWidth() == 0 || access.raw().getHeight() == 0 || access.raw().getDepth() == 0;
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool isEmpty (const IVec4& rect)
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return rect.z() == 0 || rect.w() == 0;
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int getNumMipLevels1D (int size)
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(size)+1;
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int getNumMipLevels2D (int width, int height)
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(de::max(width, height))+1;
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int getNumMipLevels3D (int width, int height, int depth)
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deLog2Floor32(de::max(width, de::max(height, depth)))+1;
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int getMipLevelSize (int baseLevelSize, int levelNdx)
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return de::max(baseLevelSize >> levelNdx, 1);
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline bool isMipmapFilter (const tcu::Sampler::FilterMode mode)
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return mode != tcu::Sampler::NEAREST && mode != tcu::Sampler::LINEAR;
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic tcu::CubeFace texTargetToFace (Framebuffer::TexTarget target)
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (target)
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_X:	return tcu::CUBEFACE_NEGATIVE_X;
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_X:	return tcu::CUBEFACE_POSITIVE_X;
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Y:	return tcu::CUBEFACE_NEGATIVE_Y;
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_Y:	return tcu::CUBEFACE_POSITIVE_Y;
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Z:	return tcu::CUBEFACE_NEGATIVE_Z;
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_Z:	return tcu::CUBEFACE_POSITIVE_Z;
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:											return tcu::CUBEFACE_LAST;
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystatic Framebuffer::TexTarget texLayeredTypeToTarget (Texture::Type type)
1348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
1358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	switch (type)
1368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
1378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		case Texture::TYPE_2D_ARRAY:		return Framebuffer::TEXTARGET_2D_ARRAY;
1388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		case Texture::TYPE_3D:				return Framebuffer::TEXTARGET_3D;
1398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		case Texture::TYPE_CUBE_MAP_ARRAY:	return Framebuffer::TEXTARGET_CUBE_MAP_ARRAY;
1408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		default:							return Framebuffer::TEXTARGET_LAST;
1418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
1428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
1438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic tcu::CubeFace mapGLCubeFace (deUint32 face)
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (face)
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:	return tcu::CUBEFACE_NEGATIVE_X;
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:	return tcu::CUBEFACE_POSITIVE_X;
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:	return tcu::CUBEFACE_NEGATIVE_Y;
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:	return tcu::CUBEFACE_POSITIVE_Y;
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:	return tcu::CUBEFACE_NEGATIVE_Z;
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:	return tcu::CUBEFACE_POSITIVE_Z;
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:								return tcu::CUBEFACE_LAST;
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::TextureFormat toTextureFormat (const tcu::PixelFormat& pixelFmt)
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::PixelFormat	pixelFmt;
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureFormat	texFmt;
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} pixelFormatMap[] =
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ tcu::PixelFormat(8,8,8,8),	tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNORM_INT8)			},
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ tcu::PixelFormat(8,8,8,0),	tcu::TextureFormat(tcu::TextureFormat::RGB,		tcu::TextureFormat::UNORM_INT8)			},
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ tcu::PixelFormat(4,4,4,4),	tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNORM_SHORT_4444)	},
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ tcu::PixelFormat(5,5,5,1),	tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNORM_SHORT_5551)	},
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ tcu::PixelFormat(5,6,5,0),	tcu::TextureFormat(tcu::TextureFormat::RGB,		tcu::TextureFormat::UNORM_SHORT_565)	}
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(pixelFormatMap); ndx++)
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (pixelFormatMap[ndx].pixelFmt == pixelFmt)
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return pixelFormatMap[ndx].texFmt;
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_FAIL("Can't map pixel format to texture format");
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::TextureFormat toNonSRGBFormat (const tcu::TextureFormat& fmt)
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (fmt.order)
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::TextureFormat::sRGB:
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return tcu::TextureFormat(tcu::TextureFormat::RGB,	fmt.type);
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::TextureFormat::sRGBA:
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return tcu::TextureFormat(tcu::TextureFormat::RGBA,	fmt.type);
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return fmt;
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::TextureFormat getDepthFormat (int depthBits)
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (depthBits)
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 8:		return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT8);
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 16:	return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 24:	return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8);
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 32:	return tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Can't map depth buffer format");
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::TextureFormat getStencilFormat (int stencilBits)
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (stencilBits)
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 8:		return tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT8);
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 16:	return tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT16);
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 24:	return tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT_24_8);
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case 32:	return tcu::TextureFormat(tcu::TextureFormat::S, tcu::TextureFormat::UNSIGNED_INT32);
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Can't map depth buffer format");
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::IVec4 intersect (const tcu::IVec4& a, const tcu::IVec4& b)
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		x0	= de::max(a.x(), b.x());
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		y0	= de::max(a.y(), b.y());
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		x1	= de::min(a.x()+a.z(), b.x()+b.z());
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		y1	= de::min(a.y()+a.w(), b.y()+b.w());
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		w	= de::max(0, x1-x0);
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		h	= de::max(0, y1-y0);
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::IVec4(x0, y0, w, h);
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::IVec4 getBufferRect (const rr::MultisampleConstPixelBufferAccess& access)
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::IVec4(0, 0, access.raw().getHeight(), access.raw().getDepth());
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2383c827367444ee418f129b2c238299f49d3264554Jarkko PoyryReferenceContextLimits::ReferenceContextLimits (const glu::RenderContext& renderCtx)
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: contextType				(renderCtx.getType())
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, maxTextureImageUnits		(0)
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, maxTexture2DSize			(0)
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, maxTextureCubeSize		(0)
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, maxTexture2DArrayLayers	(0)
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, maxTexture3DSize			(0)
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, maxRenderbufferSize		(0)
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, maxVertexAttribs			(0)
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = renderCtx.getFunctions();
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,		&maxTextureImageUnits);
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(GL_MAX_TEXTURE_SIZE,				&maxTexture2DSize);
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE,	&maxTextureCubeSize);
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(GL_MAX_RENDERBUFFER_SIZE,		&maxRenderbufferSize);
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS,			&maxVertexAttribs);
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (contextSupports(contextType, glu::ApiType::es(3,0)) || glu::isContextTypeGLCore(contextType))
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS,	&maxTexture2DArrayLayers);
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.getIntegerv(GL_MAX_3D_TEXTURE_SIZE,		&maxTexture3DSize);
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Limit texture sizes to supported values
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	maxTexture2DSize	= de::min(maxTexture2DSize,		(int)MAX_TEXTURE_SIZE);
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	maxTextureCubeSize	= de::min(maxTextureCubeSize,	(int)MAX_TEXTURE_SIZE);
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	maxTexture3DSize	= de::min(maxTexture3DSize,		(int)MAX_TEXTURE_SIZE);
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLU_EXPECT_NO_ERROR(gl.getError(), GL_NO_ERROR);
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [pyry] Figure out following things:
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// + supported fbo configurations
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// ...
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2013-08-01 pyry] Do we want to make these conditional based on renderCtx?
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addExtension("GL_EXT_color_buffer_half_float");
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addExtension("GL_EXT_color_buffer_float");
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (contextSupports(contextType, glu::ApiType::es(3,1)))
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		addExtension("GL_EXT_texture_cube_map_array");
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContextLimits::addExtension (const char* extension)
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	extensionList.push_back(extension);
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!extensionStr.empty())
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		extensionStr += " ";
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	extensionStr += extension;
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryReferenceContextBuffers::ReferenceContextBuffers (const tcu::PixelFormat& colorBits, int depthBits, int stencilBits, int width, int height, int samples)
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colorbuffer.setStorage(toTextureFormat(colorBits), samples, width, height);
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (depthBits > 0)
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_depthbuffer.setStorage(getDepthFormat(depthBits), samples, width, height);
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (stencilBits > 0)
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_stencilbuffer.setStorage(getStencilFormat(stencilBits), samples, width, height);
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3013c827367444ee418f129b2c238299f49d3264554Jarkko PoyryReferenceContext::StencilState::StencilState (void)
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: func				(GL_ALWAYS)
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, ref				(0)
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, opMask			(~0u)
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, opStencilFail		(GL_KEEP)
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, opDepthFail		(GL_KEEP)
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, opDepthPass		(GL_KEEP)
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, writeMask			(~0u)
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryReferenceContext::ReferenceContext (const ReferenceContextLimits& limits, const rr::MultisamplePixelBufferAccess& colorbuffer, const rr::MultisamplePixelBufferAccess& depthbuffer, const rr::MultisamplePixelBufferAccess& stencilbuffer)
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: Context							(limits.contextType)
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_limits							(limits)
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_defaultColorbuffer				(colorbuffer)
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_defaultDepthbuffer				(depthbuffer)
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_defaultStencilbuffer			(stencilbuffer)
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_clientVertexArray				(0, m_limits.maxVertexAttribs)
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_viewport						(0, 0, colorbuffer.raw().getHeight(), colorbuffer.raw().getDepth())
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_activeTexture					(0)
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_textureUnits					(m_limits.maxTextureImageUnits)
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_emptyTex1D						()
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_emptyTex2D						()
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_emptyTexCube					()
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_emptyTex2DArray					()
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_emptyTex3D						()
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_emptyTexCubeArray				()
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_pixelUnpackRowLength			(0)
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_pixelUnpackSkipRows				(0)
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_pixelUnpackSkipPixels			(0)
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_pixelUnpackImageHeight			(0)
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_pixelUnpackSkipImages			(0)
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_pixelUnpackAlignment			(4)
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_pixelPackAlignment				(4)
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_readFramebufferBinding			(DE_NULL)
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_drawFramebufferBinding			(DE_NULL)
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderbufferBinding				(DE_NULL)
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_vertexArrayBinding				(DE_NULL)
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_currentProgram					(DE_NULL)
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_arrayBufferBinding				(DE_NULL)
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_pixelPackBufferBinding			(DE_NULL)
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_pixelUnpackBufferBinding		(DE_NULL)
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_transformFeedbackBufferBinding	(DE_NULL)
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_uniformBufferBinding			(DE_NULL)
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_copyReadBufferBinding			(DE_NULL)
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_copyWriteBufferBinding			(DE_NULL)
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_drawIndirectBufferBinding		(DE_NULL)
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_clearColor						(0.0f, 0.0f, 0.0f, 0.0f)
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_clearDepth						(1.0f)
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_clearStencil					(0)
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_scissorEnabled					(false)
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_scissorBox						(m_viewport)
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_stencilTestEnabled				(false)
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depthTestEnabled				(false)
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depthFunc						(GL_LESS)
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depthRangeNear					(0.0f)
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depthRangeFar					(1.0f)
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_polygonOffsetFactor				(0.0f)
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_polygonOffsetUnits				(0.0f)
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_polygonOffsetFillEnabled		(false)
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_provokingFirstVertexConvention	(false)
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_blendEnabled					(false)
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_blendModeRGB					(GL_FUNC_ADD)
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_blendModeAlpha					(GL_FUNC_ADD)
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_blendFactorSrcRGB				(GL_ONE)
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_blendFactorDstRGB				(GL_ZERO)
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_blendFactorSrcAlpha				(GL_ONE)
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_blendFactorDstAlpha				(GL_ZERO)
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_blendColor						(0.0f, 0.0f, 0.0f, 0.0f)
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_sRGBUpdateEnabled				(true)
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depthClampEnabled				(false)
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_colorMask						(true, true, true, true)
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_depthMask						(true)
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_currentAttribs					(m_limits.maxVertexAttribs, rr::GenericVec4(tcu::Vec4(0, 0, 0, 1)))
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_lineWidth						(1.0f)
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_primitiveRestartFixedIndex		(false)
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_primitiveRestartSettableIndex	(false)
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_primitiveRestartIndex			(0)
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_lastError						(GL_NO_ERROR)
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create empty textures to be used when texture objects are incomplete.
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex1D.getSampler().wrapS		= tcu::Sampler::CLAMP_TO_EDGE;
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex1D.getSampler().wrapT		= tcu::Sampler::CLAMP_TO_EDGE;
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex1D.getSampler().minFilter	= tcu::Sampler::NEAREST;
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex1D.getSampler().magFilter	= tcu::Sampler::NEAREST;
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex1D.allocLevel(0, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1);
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex1D.getLevel(0).setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0, 0);
3955a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	m_emptyTex1D.updateView(tcu::Sampler::MODE_LAST);
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex2D.getSampler().wrapS		= tcu::Sampler::CLAMP_TO_EDGE;
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex2D.getSampler().wrapT		= tcu::Sampler::CLAMP_TO_EDGE;
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex2D.getSampler().minFilter	= tcu::Sampler::NEAREST;
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex2D.getSampler().magFilter	= tcu::Sampler::NEAREST;
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex2D.allocLevel(0, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1);
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex2D.getLevel(0).setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0, 0);
4035a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	m_emptyTex2D.updateView(tcu::Sampler::MODE_LAST);
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTexCube.getSampler().wrapS		= tcu::Sampler::CLAMP_TO_EDGE;
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTexCube.getSampler().wrapT		= tcu::Sampler::CLAMP_TO_EDGE;
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTexCube.getSampler().minFilter	= tcu::Sampler::NEAREST;
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTexCube.getSampler().magFilter	= tcu::Sampler::NEAREST;
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_emptyTexCube.allocFace(0, (tcu::CubeFace)face, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1);
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_emptyTexCube.getFace(0, (tcu::CubeFace)face).setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0, 0);
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4145a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	m_emptyTexCube.updateView(tcu::Sampler::MODE_LAST);
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex2DArray.getSampler().wrapS		= tcu::Sampler::CLAMP_TO_EDGE;
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex2DArray.getSampler().wrapT		= tcu::Sampler::CLAMP_TO_EDGE;
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex2DArray.getSampler().minFilter	= tcu::Sampler::NEAREST;
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex2DArray.getSampler().magFilter	= tcu::Sampler::NEAREST;
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex2DArray.allocLevel(0, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1, 1);
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex2DArray.getLevel(0).setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0, 0);
4225a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	m_emptyTex2DArray.updateView(tcu::Sampler::MODE_LAST);
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex3D.getSampler().wrapS		= tcu::Sampler::CLAMP_TO_EDGE;
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex3D.getSampler().wrapT		= tcu::Sampler::CLAMP_TO_EDGE;
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex3D.getSampler().wrapR		= tcu::Sampler::CLAMP_TO_EDGE;
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex3D.getSampler().minFilter	= tcu::Sampler::NEAREST;
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex3D.getSampler().magFilter	= tcu::Sampler::NEAREST;
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex3D.allocLevel(0, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1, 1);
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex3D.getLevel(0).setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0, 0);
4315a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	m_emptyTex3D.updateView(tcu::Sampler::MODE_LAST);
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTexCubeArray.getSampler().wrapS		= tcu::Sampler::CLAMP_TO_EDGE;
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTexCubeArray.getSampler().wrapT		= tcu::Sampler::CLAMP_TO_EDGE;
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTexCubeArray.getSampler().minFilter	= tcu::Sampler::NEAREST;
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTexCubeArray.getSampler().magFilter	= tcu::Sampler::NEAREST;
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTexCubeArray.allocLevel(0, tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1, 1, 6);
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int faceNdx = 0; faceNdx < 6; faceNdx++)
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_emptyTexCubeArray.getLevel(0).setPixel(Vec4(0.0f, 0.0f, 0.0f, 1.0f), 0, 0, faceNdx);
4405a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	m_emptyTexCubeArray.updateView(tcu::Sampler::MODE_LAST);
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (glu::isContextTypeGLCore(getType()))
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_sRGBUpdateEnabled = false;
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryReferenceContext::~ReferenceContext (void)
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Destroy all objects -- verifies that ref counting works
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VertexArray*> vertexArrays;
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_vertexArrays.getAll(vertexArrays);
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<VertexArray*>::iterator i = vertexArrays.begin(); i != vertexArrays.end(); i++)
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deleteVertexArray(*i);
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_clientVertexArray.getRefCount() == 1);
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<Texture*> textures;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.getAll(textures);
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<Texture*>::iterator i = textures.begin(); i != textures.end(); i++)
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deleteTexture(*i);
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<Framebuffer*> framebuffers;
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_framebuffers.getAll(framebuffers);
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<Framebuffer*>::iterator i = framebuffers.begin(); i != framebuffers.end(); i++)
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deleteFramebuffer(*i);
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<Renderbuffer*> renderbuffers;
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_renderbuffers.getAll(renderbuffers);
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<Renderbuffer*>::iterator i = renderbuffers.begin(); i != renderbuffers.end(); i++)
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deleteRenderbuffer(*i);
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<DataBuffer*> buffers;
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffers.getAll(buffers);
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<DataBuffer*>::iterator i = buffers.begin(); i != buffers.end(); i++)
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deleteBuffer(*i);
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<ShaderProgramObjectContainer*> programs;
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_programs.getAll(programs);
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<ShaderProgramObjectContainer*>::iterator i = programs.begin(); i != programs.end(); i++)
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deleteProgramObject(*i);
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::activeTexture (deUint32 texture)
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (deInBounds32(texture, GL_TEXTURE0, GL_TEXTURE0 + (deUint32)m_textureUnits.size()))
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_activeTexture = texture - GL_TEXTURE0;
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setError(GL_INVALID_ENUM);
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::setTex1DBinding (int unitNdx, Texture1D* texture)
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_textureUnits[unitNdx].tex1DBinding)
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.releaseReference(m_textureUnits[unitNdx].tex1DBinding);
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureUnits[unitNdx].tex1DBinding = DE_NULL;
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (texture)
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.acquireReference(texture);
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureUnits[unitNdx].tex1DBinding = texture;
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::setTex2DBinding (int unitNdx, Texture2D* texture)
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_textureUnits[unitNdx].tex2DBinding)
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.releaseReference(m_textureUnits[unitNdx].tex2DBinding);
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureUnits[unitNdx].tex2DBinding = DE_NULL;
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (texture)
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.acquireReference(texture);
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureUnits[unitNdx].tex2DBinding = texture;
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::setTexCubeBinding (int unitNdx, TextureCube* texture)
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_textureUnits[unitNdx].texCubeBinding)
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.releaseReference(m_textureUnits[unitNdx].texCubeBinding);
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureUnits[unitNdx].texCubeBinding = DE_NULL;
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (texture)
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.acquireReference(texture);
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureUnits[unitNdx].texCubeBinding = texture;
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::setTex2DArrayBinding (int unitNdx, Texture2DArray* texture)
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_textureUnits[unitNdx].tex2DArrayBinding)
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.releaseReference(m_textureUnits[unitNdx].tex2DArrayBinding);
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureUnits[unitNdx].tex2DArrayBinding = DE_NULL;
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (texture)
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.acquireReference(texture);
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureUnits[unitNdx].tex2DArrayBinding = texture;
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::setTex3DBinding (int unitNdx, Texture3D* texture)
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_textureUnits[unitNdx].tex3DBinding)
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.releaseReference(m_textureUnits[unitNdx].tex3DBinding);
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureUnits[unitNdx].tex3DBinding = DE_NULL;
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (texture)
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.acquireReference(texture);
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureUnits[unitNdx].tex3DBinding = texture;
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::setTexCubeArrayBinding (int unitNdx, TextureCubeArray* texture)
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_textureUnits[unitNdx].texCubeArrayBinding)
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.releaseReference(m_textureUnits[unitNdx].texCubeArrayBinding);
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureUnits[unitNdx].texCubeArrayBinding = DE_NULL;
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (texture)
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.acquireReference(texture);
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textureUnits[unitNdx].texCubeArrayBinding = texture;
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::bindTexture (deUint32 target, deUint32 texture)
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int unitNdx = m_activeTexture;
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(target != GL_TEXTURE_1D				&&
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				target != GL_TEXTURE_2D				&&
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				target != GL_TEXTURE_CUBE_MAP		&&
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				target != GL_TEXTURE_2D_ARRAY		&&
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				target != GL_TEXTURE_3D				&&
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				target != GL_TEXTURE_CUBE_MAP_ARRAY,
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_INVALID_ENUM, RC_RET_VOID);
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(glu::isContextTypeES(m_limits.contextType) && (target == GL_TEXTURE_1D), GL_INVALID_ENUM, RC_RET_VOID);
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (texture == 0)
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clear binding.
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (target)
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case GL_TEXTURE_1D:				setTex1DBinding			(unitNdx, DE_NULL);	break;
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case GL_TEXTURE_2D:				setTex2DBinding			(unitNdx, DE_NULL);	break;
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case GL_TEXTURE_CUBE_MAP:		setTexCubeBinding		(unitNdx, DE_NULL);	break;
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case GL_TEXTURE_2D_ARRAY:		setTex2DArrayBinding	(unitNdx, DE_NULL);	break;
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case GL_TEXTURE_3D:				setTex3DBinding			(unitNdx, DE_NULL);	break;
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case GL_TEXTURE_CUBE_MAP_ARRAY:	setTexCubeArrayBinding	(unitNdx, DE_NULL);	break;
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture* texObj = m_textures.find(texture);
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texObj)
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Validate type.
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Texture::Type expectedType = Texture::TYPE_LAST;
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (target)
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case GL_TEXTURE_1D:				expectedType = Texture::TYPE_1D;				break;
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case GL_TEXTURE_2D:				expectedType = Texture::TYPE_2D;				break;
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case GL_TEXTURE_CUBE_MAP:		expectedType = Texture::TYPE_CUBE_MAP;			break;
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case GL_TEXTURE_2D_ARRAY:		expectedType = Texture::TYPE_2D_ARRAY;			break;
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case GL_TEXTURE_3D:				expectedType = Texture::TYPE_3D;				break;
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case GL_TEXTURE_CUBE_MAP_ARRAY:	expectedType = Texture::TYPE_CUBE_MAP_ARRAY;	break;
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(texObj->getType() != expectedType, GL_INVALID_OPERATION, RC_RET_VOID);
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// New texture object.
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (target)
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case GL_TEXTURE_1D:				texObj = new Texture1D			(texture);	break;
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case GL_TEXTURE_2D:				texObj = new Texture2D			(texture);	break;
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case GL_TEXTURE_CUBE_MAP:		texObj = new TextureCube		(texture);	break;
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case GL_TEXTURE_2D_ARRAY:		texObj = new Texture2DArray		(texture);	break;
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case GL_TEXTURE_3D:				texObj = new Texture3D			(texture);	break;
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case GL_TEXTURE_CUBE_MAP_ARRAY:	texObj = new TextureCubeArray	(texture);	break;
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.insert(texObj);
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (target)
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case GL_TEXTURE_1D:				setTex1DBinding			(unitNdx, static_cast<Texture1D*>			(texObj));	break;
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case GL_TEXTURE_2D:				setTex2DBinding			(unitNdx, static_cast<Texture2D*>			(texObj));	break;
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case GL_TEXTURE_CUBE_MAP:		setTexCubeBinding		(unitNdx, static_cast<TextureCube*>			(texObj));	break;
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case GL_TEXTURE_2D_ARRAY:		setTex2DArrayBinding	(unitNdx, static_cast<Texture2DArray*>		(texObj));	break;
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case GL_TEXTURE_3D:				setTex3DBinding			(unitNdx, static_cast<Texture3D*>			(texObj));	break;
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case GL_TEXTURE_CUBE_MAP_ARRAY:	setTexCubeArrayBinding	(unitNdx, static_cast<TextureCubeArray*>	(texObj));	break;
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::genTextures (int numTextures, deUint32* textures)
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	while (numTextures--)
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*textures++ = m_textures.allocateName();
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteTextures (int numTextures, const deUint32* textures)
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numTextures; i++)
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	name		= textures[i];
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture*	texture		= name ? m_textures.find(name) : DE_NULL;
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture)
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deleteTexture(texture);
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteTexture (Texture* texture)
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Unbind from context
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int unitNdx = 0; unitNdx < (int)m_textureUnits.size(); unitNdx++)
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_textureUnits[unitNdx].tex1DBinding				== texture)	setTex1DBinding			(unitNdx, DE_NULL);
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_textureUnits[unitNdx].tex2DBinding			== texture)	setTex2DBinding			(unitNdx, DE_NULL);
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_textureUnits[unitNdx].texCubeBinding			== texture)	setTexCubeBinding		(unitNdx, DE_NULL);
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_textureUnits[unitNdx].tex2DArrayBinding		== texture)	setTex2DArrayBinding	(unitNdx, DE_NULL);
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_textureUnits[unitNdx].tex3DBinding			== texture)	setTex3DBinding			(unitNdx, DE_NULL);
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (m_textureUnits[unitNdx].texCubeArrayBinding	== texture)	setTexCubeArrayBinding	(unitNdx, DE_NULL);
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Unbind from currently bound framebuffers
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < 2; ndx++)
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rc::Framebuffer* framebufferBinding = ndx ? m_drawFramebufferBinding : m_readFramebufferBinding;
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (framebufferBinding)
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int releaseRefCount = (framebufferBinding == m_drawFramebufferBinding ? 1 : 0)
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								+ (framebufferBinding == m_readFramebufferBinding ? 1 : 0);
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int point = 0; point < Framebuffer::ATTACHMENTPOINT_LAST; point++)
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Framebuffer::Attachment& attachment = framebufferBinding->getAttachment((Framebuffer::AttachmentPoint)point);
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (attachment.name == texture->getName())
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int refNdx = 0; refNdx < releaseRefCount; refNdx++)
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						releaseFboAttachmentReference(attachment);
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					attachment = Framebuffer::Attachment();
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(texture->getRefCount() == 1);
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures.releaseReference(texture);
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::bindFramebuffer (deUint32 target, deUint32 name)
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Framebuffer* fbo = DE_NULL;
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(target != GL_FRAMEBUFFER		&&
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				target != GL_DRAW_FRAMEBUFFER	&&
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				target != GL_READ_FRAMEBUFFER, GL_INVALID_ENUM, RC_RET_VOID);
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (name != 0)
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Find or create framebuffer object.
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fbo = m_framebuffers.find(name);
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!fbo)
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fbo = new Framebuffer(name);
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_framebuffers.insert(fbo);
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < 2; ndx++)
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32			bindingTarget	= ndx ? GL_DRAW_FRAMEBUFFER			: GL_READ_FRAMEBUFFER;
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rc::Framebuffer*&	binding			= ndx ? m_drawFramebufferBinding	: m_readFramebufferBinding;
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (target != GL_FRAMEBUFFER && target != bindingTarget)
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue; // Doesn't match this target.
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Remove old references
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (binding)
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Clear all attachment point references
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int point = 0; point < Framebuffer::ATTACHMENTPOINT_LAST; point++)
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				releaseFboAttachmentReference(binding->getAttachment((Framebuffer::AttachmentPoint)point));
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_framebuffers.releaseReference(binding);
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Create new references
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (fbo)
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_framebuffers.acquireReference(fbo);
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int point = 0; point < Framebuffer::ATTACHMENTPOINT_LAST; point++)
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				acquireFboAttachmentReference(fbo->getAttachment((Framebuffer::AttachmentPoint)point));
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		binding = fbo;
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::genFramebuffers (int numFramebuffers, deUint32* framebuffers)
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	while (numFramebuffers--)
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*framebuffers++ = m_framebuffers.allocateName();
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteFramebuffer (Framebuffer* framebuffer)
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Remove bindings.
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_drawFramebufferBinding == framebuffer) bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_readFramebufferBinding == framebuffer) bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(framebuffer->getRefCount() == 1);
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_framebuffers.releaseReference(framebuffer);
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteFramebuffers (int numFramebuffers, const deUint32* framebuffers)
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numFramebuffers; i++)
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		name		= framebuffers[i];
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Framebuffer*	framebuffer	= name ? m_framebuffers.find(name) : DE_NULL;
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (framebuffer)
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deleteFramebuffer(framebuffer);
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::bindRenderbuffer (deUint32 target, deUint32 name)
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Renderbuffer* rbo = DE_NULL;
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(target != GL_RENDERBUFFER, GL_INVALID_ENUM, RC_RET_VOID);
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (name != 0)
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rbo = m_renderbuffers.find(name);
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!rbo)
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rbo = new Renderbuffer(name);
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_renderbuffers.insert(rbo);
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Remove old reference
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_renderbufferBinding)
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_renderbuffers.releaseReference(m_renderbufferBinding);
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create new reference
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (rbo)
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_renderbuffers.acquireReference(rbo);
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderbufferBinding = rbo;
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::genRenderbuffers (int numRenderbuffers, deUint32* renderbuffers)
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	while (numRenderbuffers--)
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*renderbuffers++ = m_renderbuffers.allocateName();
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteRenderbuffer (Renderbuffer* renderbuffer)
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_renderbufferBinding == renderbuffer)
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bindRenderbuffer(GL_RENDERBUFFER, 0);
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Unbind from currently bound framebuffers
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < 2; ndx++)
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rc::Framebuffer* framebufferBinding = ndx ? m_drawFramebufferBinding : m_readFramebufferBinding;
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (framebufferBinding)
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int releaseRefCount = (framebufferBinding == m_drawFramebufferBinding ? 1 : 0)
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								+ (framebufferBinding == m_readFramebufferBinding ? 1 : 0);
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int point = 0; point < Framebuffer::ATTACHMENTPOINT_LAST; point++)
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Framebuffer::Attachment& attachment = framebufferBinding->getAttachment((Framebuffer::AttachmentPoint)point);
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (attachment.name == renderbuffer->getName())
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int refNdx = 0; refNdx < releaseRefCount; refNdx++)
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						releaseFboAttachmentReference(attachment);
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					attachment = Framebuffer::Attachment();
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(renderbuffer->getRefCount() == 1);
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderbuffers.releaseReference(renderbuffer);
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteRenderbuffers (int numRenderbuffers, const deUint32* renderbuffers)
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numRenderbuffers; i++)
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		name			= renderbuffers[i];
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Renderbuffer*	renderbuffer	= name ? m_renderbuffers.find(name) : DE_NULL;
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (renderbuffer)
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deleteRenderbuffer(renderbuffer);
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::pixelStorei (deUint32 pname, int param)
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (pname)
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_UNPACK_ALIGNMENT:
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(param != 1 && param != 2 && param != 4 && param != 8, GL_INVALID_VALUE, RC_RET_VOID);
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_pixelUnpackAlignment = param;
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PACK_ALIGNMENT:
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(param != 1 && param != 2 && param != 4 && param != 8, GL_INVALID_VALUE, RC_RET_VOID);
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_pixelPackAlignment = param;
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_UNPACK_ROW_LENGTH:
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(param < 0, GL_INVALID_VALUE, RC_RET_VOID);
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_pixelUnpackRowLength = param;
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_UNPACK_SKIP_ROWS:
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(param < 0, GL_INVALID_VALUE, RC_RET_VOID);
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_pixelUnpackSkipRows = param;
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_UNPACK_SKIP_PIXELS:
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(param < 0, GL_INVALID_VALUE, RC_RET_VOID);
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_pixelUnpackSkipPixels = param;
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_UNPACK_IMAGE_HEIGHT:
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(param < 0, GL_INVALID_VALUE, RC_RET_VOID);
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_pixelUnpackImageHeight = param;
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_UNPACK_SKIP_IMAGES:
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(param < 0, GL_INVALID_VALUE, RC_RET_VOID);
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_pixelUnpackSkipImages = param;
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::ConstPixelBufferAccess ReferenceContext::getUnpack2DAccess (const tcu::TextureFormat& format, int width, int height, const void* data)
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				pixelSize	= format.getPixelSize();
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				rowLen		= m_pixelUnpackRowLength > 0 ? m_pixelUnpackRowLength : width;
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				rowPitch	= deAlign32(rowLen*pixelSize, m_pixelUnpackAlignment);
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint8*	ptr			= (const deUint8*)data + m_pixelUnpackSkipRows*rowPitch + m_pixelUnpackSkipPixels*pixelSize;
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::ConstPixelBufferAccess(format, width, height, 1, rowPitch, 0, ptr);
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::ConstPixelBufferAccess ReferenceContext::getUnpack3DAccess (const tcu::TextureFormat& format, int width, int height, int depth, const void* data)
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				pixelSize	= format.getPixelSize();
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				rowLen		= m_pixelUnpackRowLength	> 0 ? m_pixelUnpackRowLength	: width;
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				imageHeight	= m_pixelUnpackImageHeight	> 0 ? m_pixelUnpackImageHeight	: height;
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				rowPitch	= deAlign32(rowLen*pixelSize, m_pixelUnpackAlignment);
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				slicePitch	= imageHeight*rowPitch;
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint8*	ptr			= (const deUint8*)data + m_pixelUnpackSkipImages*slicePitch + m_pixelUnpackSkipRows*rowPitch + m_pixelUnpackSkipPixels*pixelSize;
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::ConstPixelBufferAccess(format, width, height, depth, rowPitch, slicePitch, ptr);
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic tcu::TextureFormat mapInternalFormat (deUint32 internalFormat)
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (internalFormat)
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ALPHA:				return TextureFormat(TextureFormat::A,		TextureFormat::UNORM_INT8);
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LUMINANCE:			return TextureFormat(TextureFormat::L,		TextureFormat::UNORM_INT8);
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LUMINANCE_ALPHA:	return TextureFormat(TextureFormat::LA,		TextureFormat::UNORM_INT8);
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_RGB:				return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_INT8);
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_RGBA:				return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8);
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return glu::mapGLInternalFormat(internalFormat);
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void depthValueFloatClampCopy (const PixelBufferAccess& dst, const ConstPixelBufferAccess& src)
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width	= dst.getWidth();
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height	= dst.getHeight();
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int depth	= dst.getDepth();
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(src.getWidth() == width && src.getHeight() == height && src.getDepth() == depth);
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// clamping copy
9755a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry
9765a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	if (src.getFormat().order == tcu::TextureFormat::DS && dst.getFormat().order == tcu::TextureFormat::DS)
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9785a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		// copy only depth and stencil
9795a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		for (int z = 0; z < depth; z++)
9805a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		for (int y = 0; y < height; y++)
9815a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		for (int x = 0; x < width; x++)
9825a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		{
9835a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			dst.setPixDepth(de::clamp(src.getPixDepth(x, y, z), 0.0f, 1.0f), x, y, z);
9845a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			dst.setPixStencil(src.getPixStencil(x, y, z), x, y, z);
9855a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		}
9865a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	}
9875a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	else
9885a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	{
9895a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		// copy only depth
9905a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		for (int z = 0; z < depth; z++)
9915a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		for (int y = 0; y < height; y++)
9925a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		for (int x = 0; x < width; x++)
9935a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			dst.setPixDepth(de::clamp(src.getPixDepth(x, y, z), 0.0f, 1.0f), x, y, z);
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texImage1D (deUint32 target, int level, deUint32 internalFormat, int width, int border, deUint32 format, deUint32 type, const void* data)
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	texImage2D(target, level, internalFormat, width, 1, border, format, type, data);
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texImage2D (deUint32 target, int level, deUint32 internalFormat, int width, int height, int border, deUint32 format, deUint32 type, const void* data)
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	texImage3D(target, level, internalFormat, width, height, 1, border, format, type, data);
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10075a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyrystatic void clearToTextureInitialValue (PixelBufferAccess access)
10085a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry{
10095a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	const bool hasDepth		= access.getFormat().order == tcu::TextureFormat::D || access.getFormat().order == tcu::TextureFormat::DS;
10105a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	const bool hasStencil	= access.getFormat().order == tcu::TextureFormat::S || access.getFormat().order == tcu::TextureFormat::DS;
10115a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	const bool hasColor		= !hasDepth && !hasStencil;
10125a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry
10135a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	if (hasDepth)
10145a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		tcu::clearDepth(access, 0.0f);
10155a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	if (hasStencil)
10165a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		tcu::clearStencil(access, 0u);
10175a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	if (hasColor)
10185a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		tcu::clear(access, Vec4(0.0f, 0.0f, 0.0f, 1.0f));
10195a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry}
10205a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texImage3D (deUint32 target, int level, deUint32 internalFormat, int width, int height, int depth, int border, deUint32 format, deUint32 type, const void* data)
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&		unit					= m_textureUnits[m_activeTexture];
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const void*			unpackPtr				= getPixelUnpackPtr(data);
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			isDstFloatDepthFormat	= (internalFormat == GL_DEPTH_COMPONENT32F || internalFormat == GL_DEPTH32F_STENCIL8); // depth components are limited to [0,1] range
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat		storageFmt;
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat		transferFmt;
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(border != 0, GL_INVALID_VALUE, RC_RET_VOID);
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0 || height < 0 || depth < 0 || level < 0, GL_INVALID_VALUE, RC_RET_VOID);
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map storage format.
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	storageFmt = mapInternalFormat(internalFormat);
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(storageFmt.order	== TextureFormat::CHANNELORDER_LAST ||
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				storageFmt.type		== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map transfer format.
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	transferFmt = glu::mapGLTransferFormat(format, type);
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(transferFmt.order	== TextureFormat::CHANNELORDER_LAST ||
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				transferFmt.type	== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_1D && glu::isContextTypeGLCore(m_limits.contextType))
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width > m_limits.maxTexture2DSize || height != 1 || depth != 1, GL_INVALID_VALUE, RC_RET_VOID);
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture1D* texture = unit.tex1DBinding ? unit.tex1DBinding : &unit.default1DTex;
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getLevel(level));
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth(), GL_INVALID_OPERATION, RC_RET_VOID);
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocLevel(level, storageFmt, width);
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unpackPtr)
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess	src		= getUnpack2DAccess(transferFmt, width, 1, unpackPtr);
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess		dst		(texture->getLevel(level));
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDstFloatDepthFormat)
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				depthValueFloatClampCopy(dst, src);
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::copy(dst, src);
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10735a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			// No data supplied, clear to initial
10745a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			clearToTextureInitialValue(texture->getLevel(level));
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_2D)
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width > m_limits.maxTexture2DSize || height > m_limits.maxTexture2DSize || depth != 1, GL_INVALID_VALUE, RC_RET_VOID);
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2D* texture = unit.tex2DBinding ? unit.tex2DBinding : &unit.default2DTex;
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getLevel(level));
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth()	||
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						height		!= dst.getHeight(), GL_INVALID_OPERATION, RC_RET_VOID);
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocLevel(level, storageFmt, width, height);
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unpackPtr)
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess	src		= getUnpack2DAccess(transferFmt, width, height, unpackPtr);
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess		dst		(texture->getLevel(level));
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDstFloatDepthFormat)
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				depthValueFloatClampCopy(dst, src);
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::copy(dst, src);
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11095a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			// No data supplied, clear to initial
11105a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			clearToTextureInitialValue(texture->getLevel(level));
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ||
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z)
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width != height || width > m_limits.maxTextureCubeSize || depth != 1, GL_INVALID_VALUE, RC_RET_VOID);
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTextureCubeSize), GL_INVALID_VALUE, RC_RET_VOID);
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCube*	texture	= unit.texCubeBinding ? unit.texCubeBinding : &unit.defaultCubeTex;
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::CubeFace	face	= mapGLCubeFace(target);
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasFace(level, face), GL_INVALID_OPERATION, RC_RET_VOID);
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getFace(level, face));
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth()	||
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						height		!= dst.getHeight(), GL_INVALID_OPERATION, RC_RET_VOID);
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocFace(level, face, storageFmt, width, height);
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unpackPtr)
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess	src		= getUnpack2DAccess(transferFmt, width, height, unpackPtr);
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess		dst		(texture->getFace(level, face));
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDstFloatDepthFormat)
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				depthValueFloatClampCopy(dst, src);
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::copy(dst, src);
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11515a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			// No data supplied, clear to initial
11525a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			clearToTextureInitialValue(texture->getFace(level, face));
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_2D_ARRAY)
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width	> m_limits.maxTexture2DSize ||
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					height	> m_limits.maxTexture2DSize ||
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth	> m_limits.maxTexture2DArrayLayers, GL_INVALID_VALUE, RC_RET_VOID);
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2DArray* texture = unit.tex2DArrayBinding ? unit.tex2DArrayBinding : &unit.default2DArrayTex;
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getLevel(level));
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth()	||
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						height		!= dst.getHeight()	||
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						depth		!= dst.getDepth(), GL_INVALID_OPERATION, RC_RET_VOID);
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocLevel(level, storageFmt, width, height, depth);
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unpackPtr)
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess	src		= getUnpack3DAccess(transferFmt, width, height, depth, unpackPtr);
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess		dst		(texture->getLevel(level));
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDstFloatDepthFormat)
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				depthValueFloatClampCopy(dst, src);
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::copy(dst, src);
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11905a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			// No data supplied, clear to initial
11915a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			clearToTextureInitialValue(texture->getLevel(level));
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_3D)
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width	> m_limits.maxTexture3DSize ||
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					height	> m_limits.maxTexture3DSize ||
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth	> m_limits.maxTexture3DSize, GL_INVALID_VALUE, RC_RET_VOID);
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture3DSize), GL_INVALID_VALUE, RC_RET_VOID);
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture3D* texture = unit.tex3DBinding ? unit.tex3DBinding : &unit.default3DTex;
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getLevel(level));
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth()	||
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						height		!= dst.getHeight()	||
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						depth		!= dst.getDepth(), GL_INVALID_OPERATION, RC_RET_VOID);
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocLevel(level, storageFmt, width, height, depth);
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unpackPtr)
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess	src		= getUnpack3DAccess(transferFmt, width, height, depth, unpackPtr);
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess		dst		(texture->getLevel(level));
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDstFloatDepthFormat)
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				depthValueFloatClampCopy(dst, src);
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::copy(dst, src);
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12295a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			// No data supplied, clear to initial
12305a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			clearToTextureInitialValue(texture->getLevel(level));
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width		!= height						||
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					width		 > m_limits.maxTexture2DSize	||
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth % 6	!= 0							||
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth		 > m_limits.maxTexture2DArrayLayers, GL_INVALID_VALUE, RC_RET_VOID);
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCubeArray* texture = unit.texCubeArrayBinding ? unit.texCubeArrayBinding : &unit.defaultCubeArrayTex;
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getLevel(level));
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth()	||
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						height		!= dst.getHeight()	||
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						depth		!= dst.getDepth(), GL_INVALID_OPERATION, RC_RET_VOID);
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocLevel(level, storageFmt, width, height, depth);
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unpackPtr)
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess	src		= getUnpack3DAccess(transferFmt, width, height, depth, unpackPtr);
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess		dst		(texture->getLevel(level));
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDstFloatDepthFormat)
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				depthValueFloatClampCopy(dst, src);
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::copy(dst, src);
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12695a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			// No data supplied, clear to initial
12705a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			clearToTextureInitialValue(texture->getLevel(level));
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texSubImage1D (deUint32 target, int level, int xoffset, int width, deUint32 format, deUint32 type, const void* data)
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	texSubImage2D(target, level, xoffset, 0, width, 1, format, type, data);
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texSubImage2D (deUint32 target, int level, int xoffset, int yoffset, int width, int height, deUint32 format, deUint32 type, const void* data)
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	texSubImage3D(target, level, xoffset, yoffset, 0, width, height, 1, format, type, data);
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid 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)
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit& unit = m_textureUnits[m_activeTexture];
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(xoffset < 0 || yoffset < 0 || zoffset < 0,	GL_INVALID_VALUE, RC_RET_VOID);
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0 || height < 0 || depth < 0,		GL_INVALID_VALUE, RC_RET_VOID);
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat transferFmt = glu::mapGLTransferFormat(format, type);
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(transferFmt.order	== TextureFormat::CHANNELORDER_LAST ||
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				transferFmt.type	== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstPixelBufferAccess src = getUnpack3DAccess(transferFmt, width, height, depth, getPixelUnpackPtr(data));
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_1D && glu::isContextTypeGLCore(m_limits.contextType))
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture1D& texture = unit.tex1DBinding ? *unit.tex1DBinding : unit.default1DTex;
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getLevel(level);
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight()	||
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					zoffset + depth		> dst.getDepth(),
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// depth components are limited to [0,1] range
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_2D)
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2D& texture = unit.tex2DBinding ? *unit.tex2DBinding : unit.default2DTex;
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getLevel(level);
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight()	||
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					zoffset + depth		> dst.getDepth(),
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// depth components are limited to [0,1] range
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ||
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z)
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCube&	texture		= unit.texCubeBinding ? *unit.texCubeBinding : unit.defaultCubeTex;
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::CubeFace	face		= mapGLCubeFace(target);
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasFace(level, face), GL_INVALID_VALUE, RC_RET_VOID);
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getFace(level, face);
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight()	||
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					zoffset + depth		> dst.getDepth(),
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// depth components are limited to [0,1] range
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_3D)
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture3D& texture = unit.tex3DBinding ? *unit.tex3DBinding : unit.default3DTex;
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getLevel(level);
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight()	||
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					zoffset + depth		> dst.getDepth(),
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// depth components are limited to [0,1] range
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_2D_ARRAY)
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2DArray& texture = unit.tex2DArrayBinding ? *unit.tex2DArrayBinding : unit.default2DArrayTex;
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getLevel(level);
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight()	||
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					zoffset + depth		> dst.getDepth(),
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// depth components are limited to [0,1] range
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCubeArray& texture = unit.texCubeArrayBinding ? *unit.texCubeArrayBinding : unit.defaultCubeArrayTex;
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getLevel(level);
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight()	||
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					zoffset + depth		> dst.getDepth(),
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// depth components are limited to [0,1] range
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::copyTexImage1D (deUint32 target, int level, deUint32 internalFormat, int x, int y, int width, int border)
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&							unit		= m_textureUnits[m_activeTexture];
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat							storageFmt;
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisampleConstPixelBufferAccess	src			= getReadColorbuffer();
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(border != 0, GL_INVALID_VALUE, RC_RET_VOID);
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0 || level < 0, GL_INVALID_VALUE, RC_RET_VOID);
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(isEmpty(src), GL_INVALID_OPERATION, RC_RET_VOID);
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map storage format.
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	storageFmt = mapInternalFormat(internalFormat);
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(storageFmt.order	== TextureFormat::CHANNELORDER_LAST ||
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				storageFmt.type		== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_1D)
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width > m_limits.maxTexture2DSize, GL_INVALID_VALUE, RC_RET_VOID);
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture1D* texture = unit.tex1DBinding ? unit.tex1DBinding : &unit.default1DTex;
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getLevel(level));
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth(), GL_INVALID_OPERATION, RC_RET_VOID);
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocLevel(level, storageFmt, width);
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Copy from current framebuffer.
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture->getLevel(level);
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int xo = 0; xo < width; xo++)
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::inBounds(x+xo, 0, src.raw().getHeight()))
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue; // Undefined pixel.
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y), xo, 0);
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::copyTexImage2D (deUint32 target, int level, deUint32 internalFormat, int x, int y, int width, int height, int border)
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&							unit		= m_textureUnits[m_activeTexture];
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat							storageFmt;
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisampleConstPixelBufferAccess	src			= getReadColorbuffer();
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(border != 0, GL_INVALID_VALUE, RC_RET_VOID);
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0 || height < 0 || level < 0, GL_INVALID_VALUE, RC_RET_VOID);
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(isEmpty(src), GL_INVALID_OPERATION, RC_RET_VOID);
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map storage format.
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	storageFmt = mapInternalFormat(internalFormat);
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(storageFmt.order	== TextureFormat::CHANNELORDER_LAST ||
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				storageFmt.type		== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_2D)
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width > m_limits.maxTexture2DSize || height > m_limits.maxTexture2DSize, GL_INVALID_VALUE, RC_RET_VOID);
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2D* texture = unit.tex2DBinding ? unit.tex2DBinding : &unit.default2DTex;
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getLevel(level));
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth()	||
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						height		!= dst.getHeight(), GL_INVALID_OPERATION, RC_RET_VOID);
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocLevel(level, storageFmt, width, height);
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Copy from current framebuffer.
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture->getLevel(level);
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int yo = 0; yo < height; yo++)
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int xo = 0; xo < width; xo++)
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::inBounds(x+xo, 0, src.raw().getHeight()) || !de::inBounds(y+yo, 0, src.raw().getDepth()))
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue; // Undefined pixel.
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y+yo), xo, yo);
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ||
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z)
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width != height || width > m_limits.maxTextureCubeSize, GL_INVALID_VALUE, RC_RET_VOID);
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTextureCubeSize), GL_INVALID_VALUE, RC_RET_VOID);
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCube*	texture	= unit.texCubeBinding ? unit.texCubeBinding : &unit.defaultCubeTex;
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::CubeFace	face	= mapGLCubeFace(target);
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasFace(level, face), GL_INVALID_OPERATION, RC_RET_VOID);
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getFace(level, face));
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth()	||
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						height		!= dst.getHeight(), GL_INVALID_OPERATION, RC_RET_VOID);
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocFace(level, face, storageFmt, width, height);
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Copy from current framebuffer.
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture->getFace(level, face);
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int yo = 0; yo < height; yo++)
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int xo = 0; xo < width; xo++)
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::inBounds(x+xo, 0, src.raw().getHeight()) || !de::inBounds(y+yo, 0, src.raw().getDepth()))
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue; // Undefined pixel.
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y+yo), xo, yo);
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::copyTexSubImage1D (deUint32 target, int level, int xoffset, int x, int y, int width)
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&							unit	= m_textureUnits[m_activeTexture];
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisampleConstPixelBufferAccess	src		= getReadColorbuffer();
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(xoffset < 0,	GL_INVALID_VALUE,		RC_RET_VOID);
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0,		GL_INVALID_VALUE,		RC_RET_VOID);
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(isEmpty(src),	GL_INVALID_OPERATION,	RC_RET_VOID);
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_1D)
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture1D& texture = unit.tex1DBinding ? *unit.tex1DBinding : unit.default1DTex;
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getLevel(level);
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width > dst.getWidth(), GL_INVALID_VALUE, RC_RET_VOID);
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int xo = 0; xo < width; xo++)
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::inBounds(x+xo, 0, src.raw().getHeight()))
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue;
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y), xo+xoffset, 0);
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::copyTexSubImage2D (deUint32 target, int level, int xoffset, int yoffset, int x, int y, int width, int height)
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&							unit	= m_textureUnits[m_activeTexture];
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisampleConstPixelBufferAccess	src		= getReadColorbuffer();
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(xoffset < 0 || yoffset < 0,					GL_INVALID_VALUE, RC_RET_VOID);
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0 || height < 0,					GL_INVALID_VALUE, RC_RET_VOID);
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(isEmpty(src),								GL_INVALID_OPERATION, RC_RET_VOID);
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_2D)
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2D& texture = unit.tex2DBinding ? *unit.tex2DBinding : unit.default2DTex;
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getLevel(level);
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth() ||
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight(),
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int yo = 0; yo < height; yo++)
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int xo = 0; xo < width; xo++)
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::inBounds(x+xo, 0, src.raw().getHeight()) || !de::inBounds(y+yo, 0, src.raw().getDepth()))
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue;
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y+yo), xo+xoffset, yo+yoffset);
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ||
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z)
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCube&	texture		= unit.texCubeBinding ? *unit.texCubeBinding : unit.defaultCubeTex;
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::CubeFace	face		= mapGLCubeFace(target);
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasFace(level, face), GL_INVALID_VALUE, RC_RET_VOID);
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getFace(level, face);
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth() ||
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight(),
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int yo = 0; yo < height; yo++)
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int xo = 0; xo < width; xo++)
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::inBounds(x+xo, 0, src.raw().getHeight()) || !de::inBounds(y+yo, 0, src.raw().getDepth()))
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue;
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y+yo), xo+xoffset, yo+yoffset);
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::copyTexSubImage3D (deUint32 target, int level, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height)
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(target && level && xoffset && yoffset && zoffset && x && y && width && height);
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texStorage2D (deUint32 target, int levels, deUint32 internalFormat, int width, int height)
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&		unit		= m_textureUnits[m_activeTexture];
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat		storageFmt;
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width <= 0 || height <= 0, GL_INVALID_VALUE, RC_RET_VOID);
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!de::inRange(levels, 1, (int)deLog2Floor32(de::max(width, height))+1), GL_INVALID_VALUE, RC_RET_VOID);
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map storage format.
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	storageFmt = mapInternalFormat(internalFormat);
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(storageFmt.order	== TextureFormat::CHANNELORDER_LAST ||
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				storageFmt.type		== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_2D)
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2D& texture = unit.tex2DBinding ? *unit.tex2DBinding : unit.default2DTex;
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width > m_limits.maxTexture2DSize || height >= m_limits.maxTexture2DSize, GL_INVALID_VALUE, RC_RET_VOID);
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(texture.isImmutable(), GL_INVALID_OPERATION, RC_RET_VOID);
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.clearLevels();
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.setImmutable();
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int level = 0; level < levels; level++)
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelW = de::max(1, width >> level);
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelH = de::max(1, height >> level);
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture.allocLevel(level, storageFmt, levelW, levelH);
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP)
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCube& texture = unit.texCubeBinding ? *unit.texCubeBinding : unit.defaultCubeTex;
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width > m_limits.maxTextureCubeSize || height > m_limits.maxTextureCubeSize, GL_INVALID_VALUE, RC_RET_VOID);
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(texture.isImmutable(), GL_INVALID_OPERATION, RC_RET_VOID);
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.clearLevels();
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.setImmutable();
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int level = 0; level < levels; level++)
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelW = de::max(1, width >> level);
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelH = de::max(1, height >> level);
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				texture.allocFace(level, (tcu::CubeFace)face, storageFmt, levelW, levelH);
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texStorage3D (deUint32 target, int levels, deUint32 internalFormat, int width, int height, int depth)
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&		unit		= m_textureUnits[m_activeTexture];
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat		storageFmt;
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width <= 0 || height <= 0, GL_INVALID_VALUE, RC_RET_VOID);
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!de::inRange(levels, 1, (int)deLog2Floor32(de::max(width, height))+1), GL_INVALID_VALUE, RC_RET_VOID);
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map storage format.
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	storageFmt = mapInternalFormat(internalFormat);
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(storageFmt.order	== TextureFormat::CHANNELORDER_LAST ||
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				storageFmt.type		== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_2D_ARRAY)
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2DArray& texture = unit.tex2DArrayBinding ? *unit.tex2DArrayBinding : unit.default2DArrayTex;
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width	>	m_limits.maxTexture2DSize	||
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					height	>=	m_limits.maxTexture2DSize	||
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth	>=	m_limits.maxTexture2DArrayLayers, GL_INVALID_VALUE, RC_RET_VOID);
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(texture.isImmutable(), GL_INVALID_OPERATION, RC_RET_VOID);
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.clearLevels();
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.setImmutable();
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int level = 0; level < levels; level++)
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelW = de::max(1, width >> level);
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelH = de::max(1, height >> level);
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture.allocLevel(level, storageFmt, levelW, levelH, depth);
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_3D)
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture3D& texture = unit.tex3DBinding ? *unit.tex3DBinding : unit.default3DTex;
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width	> m_limits.maxTexture3DSize	||
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					height	> m_limits.maxTexture3DSize	||
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth	> m_limits.maxTexture3DSize, GL_INVALID_VALUE, RC_RET_VOID);
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(texture.isImmutable(), GL_INVALID_OPERATION, RC_RET_VOID);
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.clearLevels();
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.setImmutable();
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int level = 0; level < levels; level++)
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelW = de::max(1, width		>> level);
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelH = de::max(1, height	>> level);
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelD = de::max(1, depth		>> level);
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture.allocLevel(level, storageFmt, levelW, levelH, levelD);
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCubeArray& texture = unit.texCubeArrayBinding ? *unit.texCubeArrayBinding : unit.defaultCubeArrayTex;
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width		!=	height								||
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth % 6	!= 0									||
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					width		>	m_limits.maxTexture2DSize			||
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth		>=	m_limits.maxTexture2DArrayLayers, GL_INVALID_VALUE, RC_RET_VOID);
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(texture.isImmutable(), GL_INVALID_OPERATION, RC_RET_VOID);
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.clearLevels();
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.setImmutable();
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int level = 0; level < levels; level++)
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelW = de::max(1, width >> level);
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelH = de::max(1, height >> level);
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture.allocLevel(level, storageFmt, levelW, levelH, depth);
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2014-02-19 pyry] Duplicated with code in gluTextureUtil.hpp
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::Sampler::WrapMode mapGLWrapMode (int value)
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (value)
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_CLAMP_TO_EDGE:		return tcu::Sampler::CLAMP_TO_EDGE;
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_REPEAT:				return tcu::Sampler::REPEAT_GL;
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MIRRORED_REPEAT:	return tcu::Sampler::MIRRORED_REPEAT_GL;
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:					return tcu::Sampler::WRAPMODE_LAST;
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::Sampler::FilterMode mapGLFilterMode (int value)
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (value)
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_NEAREST:				return tcu::Sampler::NEAREST;
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LINEAR:					return tcu::Sampler::LINEAR;
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_NEAREST_MIPMAP_NEAREST:	return tcu::Sampler::NEAREST_MIPMAP_NEAREST;
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_NEAREST_MIPMAP_LINEAR:	return tcu::Sampler::NEAREST_MIPMAP_LINEAR;
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LINEAR_MIPMAP_NEAREST:	return tcu::Sampler::LINEAR_MIPMAP_NEAREST;
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LINEAR_MIPMAP_LINEAR:	return tcu::Sampler::LINEAR_MIPMAP_LINEAR;
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:						return tcu::Sampler::FILTERMODE_LAST;
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texParameteri (deUint32 target, deUint32 pname, int value)
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&	unit		= m_textureUnits[m_activeTexture];
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture*		texture		= DE_NULL;
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (target)
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_1D:				texture = unit.tex1DBinding			? unit.tex1DBinding			: &unit.default1DTex;			break;
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_2D:				texture = unit.tex2DBinding			? unit.tex2DBinding			: &unit.default2DTex;			break;
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP:		texture = unit.texCubeBinding		? unit.texCubeBinding		: &unit.defaultCubeTex;			break;
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_2D_ARRAY:		texture = unit.tex2DArrayBinding	? unit.tex2DArrayBinding	: &unit.default2DArrayTex;		break;
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_3D:				texture = unit.tex3DBinding			? unit.tex3DBinding			: &unit.default3DTex;			break;
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_ARRAY:	texture = unit.texCubeArrayBinding	? unit.texCubeArrayBinding	: &unit.defaultCubeArrayTex;	break;
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:					RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (pname)
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_WRAP_S:
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Sampler::WrapMode wrapS = mapGLWrapMode(value);
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(wrapS == tcu::Sampler::WRAPMODE_LAST, GL_INVALID_VALUE, RC_RET_VOID);
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->getSampler().wrapS = wrapS;
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_WRAP_T:
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Sampler::WrapMode wrapT = mapGLWrapMode(value);
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(wrapT == tcu::Sampler::WRAPMODE_LAST, GL_INVALID_VALUE, RC_RET_VOID);
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->getSampler().wrapT = wrapT;
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_WRAP_R:
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Sampler::WrapMode wrapR = mapGLWrapMode(value);
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(wrapR == tcu::Sampler::WRAPMODE_LAST, GL_INVALID_VALUE, RC_RET_VOID);
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->getSampler().wrapR = wrapR;
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_MIN_FILTER:
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Sampler::FilterMode minMode = mapGLFilterMode(value);
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(minMode == tcu::Sampler::FILTERMODE_LAST, GL_INVALID_VALUE, RC_RET_VOID);
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->getSampler().minFilter = minMode;
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_MAG_FILTER:
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Sampler::FilterMode magMode = mapGLFilterMode(value);
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(magMode != tcu::Sampler::LINEAR && magMode != tcu::Sampler::NEAREST,
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						GL_INVALID_VALUE, RC_RET_VOID);
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->getSampler().magFilter = magMode;
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_MAX_LEVEL:
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(value < 0, GL_INVALID_VALUE, RC_RET_VOID);
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->setMaxLevel(value);
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Framebuffer::AttachmentPoint mapGLAttachmentPoint (deUint32 attachment)
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (attachment)
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_COLOR_ATTACHMENT0:	return Framebuffer::ATTACHMENTPOINT_COLOR0;
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DEPTH_ATTACHMENT:	return Framebuffer::ATTACHMENTPOINT_DEPTH;
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_STENCIL_ATTACHMENT:	return Framebuffer::ATTACHMENTPOINT_STENCIL;
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:					return Framebuffer::ATTACHMENTPOINT_LAST;
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Framebuffer::TexTarget mapGLFboTexTarget (deUint32 target)
19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (target)
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_2D:						return Framebuffer::TEXTARGET_2D;
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:	return Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_X;
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:	return Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_Y;
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:	return Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_Z;
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:	return Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_X;
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:	return Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Y;
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:	return Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Z;
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:								return Framebuffer::TEXTARGET_LAST;
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::acquireFboAttachmentReference (const Framebuffer::Attachment& attachment)
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (attachment.type)
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::ATTACHMENTTYPE_TEXTURE:
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(attachment.name != 0);
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Texture* texture = m_textures.find(attachment.name);
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(texture);
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.acquireReference(texture);
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::ATTACHMENTTYPE_RENDERBUFFER:
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(attachment.name != 0);
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Renderbuffer* rbo = m_renderbuffers.find(attachment.name);
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(rbo);
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_renderbuffers.acquireReference(rbo);
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break; // Silently ignore
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::releaseFboAttachmentReference (const Framebuffer::Attachment& attachment)
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (attachment.type)
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::ATTACHMENTTYPE_TEXTURE:
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(attachment.name != 0);
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Texture* texture = m_textures.find(attachment.name);
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(texture);
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.releaseReference(texture);
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::ATTACHMENTTYPE_RENDERBUFFER:
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(attachment.name != 0);
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Renderbuffer* rbo = m_renderbuffers.find(attachment.name);
19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(rbo);
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_renderbuffers.releaseReference(rbo);
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break; // Silently ignore
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::framebufferTexture2D (deUint32 target, deUint32 attachment, deUint32 textarget, deUint32 texture, int level)
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Attach to both depth and stencil.
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferTexture2D(target, GL_DEPTH_ATTACHMENT,	textarget, texture, level);
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferTexture2D(target, GL_STENCIL_ATTACHMENT,	textarget, texture, level);
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Framebuffer::AttachmentPoint	point			= mapGLAttachmentPoint(attachment);
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture*						texObj			= DE_NULL;
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Framebuffer::TexTarget			fboTexTarget	= mapGLFboTexTarget(textarget);
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(target != GL_FRAMEBUFFER		&&
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					target != GL_DRAW_FRAMEBUFFER	&&
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					target != GL_READ_FRAMEBUFFER,				GL_INVALID_ENUM,		RC_RET_VOID);
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(point == Framebuffer::ATTACHMENTPOINT_LAST,	GL_INVALID_ENUM,		RC_RET_VOID);
19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Select binding point.
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rc::Framebuffer* framebufferBinding = (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) ? m_drawFramebufferBinding : m_readFramebufferBinding;
19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!framebufferBinding, GL_INVALID_OPERATION, RC_RET_VOID);
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// If framebuffer object is bound for both reading and writing then we need to acquire/release multiple references.
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bindingRefCount = (framebufferBinding == m_drawFramebufferBinding ? 1 : 0)
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							+ (framebufferBinding == m_readFramebufferBinding ? 1 : 0);
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture != 0)
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texObj = m_textures.find(texture);
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texObj,		GL_INVALID_OPERATION,	RC_RET_VOID);
20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(level != 0,		GL_INVALID_VALUE,		RC_RET_VOID); // \todo [2012-03-19 pyry] We should allow other levels as well.
20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (texObj->getType() == Texture::TYPE_2D)
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				RC_IF_ERROR(fboTexTarget != Framebuffer::TEXTARGET_2D, GL_INVALID_OPERATION, RC_RET_VOID);
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TCU_CHECK(texObj->getType() == Texture::TYPE_CUBE_MAP);
20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!deInRange32(fboTexTarget, Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_X, Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Z))
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					RC_ERROR_RET(GL_INVALID_OPERATION, RC_RET_VOID);
20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Framebuffer::Attachment& fboAttachment = framebufferBinding->getAttachment(point);
20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < bindingRefCount; ndx++)
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			releaseFboAttachmentReference(fboAttachment);
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fboAttachment = Framebuffer::Attachment();
20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texObj)
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.type			= Framebuffer::ATTACHMENTTYPE_TEXTURE;
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.name			= texObj->getName();
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.texTarget		= fboTexTarget;
20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.level			= level;
20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < bindingRefCount; ndx++)
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				acquireFboAttachmentReference(fboAttachment);
20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::framebufferTextureLayer (deUint32 target, deUint32 attachment, deUint32 texture, int level, int layer)
20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Attach to both depth and stencil.
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferTextureLayer(target, GL_DEPTH_ATTACHMENT,	texture, level, layer);
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferTextureLayer(target, GL_STENCIL_ATTACHMENT,	texture, level, layer);
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Framebuffer::AttachmentPoint	point			= mapGLAttachmentPoint(attachment);
20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture*						texObj			= DE_NULL;
20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(target != GL_FRAMEBUFFER		&&
20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					target != GL_DRAW_FRAMEBUFFER	&&
20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					target != GL_READ_FRAMEBUFFER,				GL_INVALID_ENUM,		RC_RET_VOID);
20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(point == Framebuffer::ATTACHMENTPOINT_LAST,	GL_INVALID_ENUM,		RC_RET_VOID);
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Select binding point.
20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rc::Framebuffer* framebufferBinding = (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) ? m_drawFramebufferBinding : m_readFramebufferBinding;
20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!framebufferBinding, GL_INVALID_OPERATION, RC_RET_VOID);
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// If framebuffer object is bound for both reading and writing then we need to acquire/release multiple references.
20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bindingRefCount = (framebufferBinding == m_drawFramebufferBinding ? 1 : 0)
20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							+ (framebufferBinding == m_readFramebufferBinding ? 1 : 0);
20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture != 0)
20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texObj = m_textures.find(texture);
20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texObj,		GL_INVALID_OPERATION,	RC_RET_VOID);
20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(level != 0,		GL_INVALID_VALUE,		RC_RET_VOID); // \todo [2012-03-19 pyry] We should allow other levels as well.
20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			RC_IF_ERROR(texObj->getType() != Texture::TYPE_2D_ARRAY			&&
20658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry						texObj->getType() != Texture::TYPE_3D				&&
20668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry						texObj->getType() != Texture::TYPE_CUBE_MAP_ARRAY,				GL_INVALID_OPERATION,	RC_RET_VOID);
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			if (texObj->getType() == Texture::TYPE_2D_ARRAY || texObj->getType() == Texture::TYPE_CUBE_MAP_ARRAY)
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				RC_IF_ERROR((layer < 0) || (layer >= GL_MAX_ARRAY_TEXTURE_LAYERS),		GL_INVALID_VALUE,		RC_RET_VOID);
2071674ddbb09a7bb6b16f839e129d5f0f2ac6dc9e74Pyry Haulos				RC_IF_ERROR((level < 0) || (level > deLog2Floor32(GL_MAX_TEXTURE_SIZE)),GL_INVALID_VALUE,		RC_RET_VOID);
20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if	(texObj->getType() == Texture::TYPE_3D)
20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
2075a97ab3992c6122a4fa325523d1ec4a2f1062c45cJarkko Pöyry				RC_IF_ERROR((layer < 0) || (layer >= GL_MAX_3D_TEXTURE_SIZE),				GL_INVALID_VALUE,		RC_RET_VOID);
2076674ddbb09a7bb6b16f839e129d5f0f2ac6dc9e74Pyry Haulos				RC_IF_ERROR((level < 0) || (level > deLog2Floor32(GL_MAX_3D_TEXTURE_SIZE)),	GL_INVALID_VALUE,		RC_RET_VOID);
20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Framebuffer::Attachment& fboAttachment = framebufferBinding->getAttachment(point);
20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < bindingRefCount; ndx++)
20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			releaseFboAttachmentReference(fboAttachment);
20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fboAttachment = Framebuffer::Attachment();
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texObj)
20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.type			= Framebuffer::ATTACHMENTTYPE_TEXTURE;
20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.name			= texObj->getName();
20898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			fboAttachment.texTarget		= texLayeredTypeToTarget(texObj->getType());
20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.level			= level;
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.layer			= layer;
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			DE_ASSERT(fboAttachment.texTarget != Framebuffer::TEXTARGET_LAST);
20948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < bindingRefCount; ndx++)
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				acquireFboAttachmentReference(fboAttachment);
20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::framebufferRenderbuffer (deUint32 target, deUint32 attachment, deUint32 renderbuffertarget, deUint32 renderbuffer)
21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Attach both to depth and stencil.
21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT,	renderbuffertarget, renderbuffer);
21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT,	renderbuffertarget, renderbuffer);
21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Framebuffer::AttachmentPoint	point			= mapGLAttachmentPoint(attachment);
21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Renderbuffer*					rbo				= DE_NULL;
21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(target != GL_FRAMEBUFFER		&&
21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					target != GL_DRAW_FRAMEBUFFER	&&
21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					target != GL_READ_FRAMEBUFFER,				GL_INVALID_ENUM,		RC_RET_VOID);
21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(point == Framebuffer::ATTACHMENTPOINT_LAST,	GL_INVALID_ENUM,		RC_RET_VOID);
21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Select binding point.
21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rc::Framebuffer* framebufferBinding = (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) ? m_drawFramebufferBinding : m_readFramebufferBinding;
21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!framebufferBinding, GL_INVALID_OPERATION, RC_RET_VOID);
21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// If framebuffer object is bound for both reading and writing then we need to acquire/release multiple references.
21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bindingRefCount = (framebufferBinding == m_drawFramebufferBinding ? 1 : 0)
21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							+ (framebufferBinding == m_readFramebufferBinding ? 1 : 0);
21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (renderbuffer != 0)
21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rbo = m_renderbuffers.find(renderbuffer);
21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(renderbuffertarget != GL_RENDERBUFFER,	GL_INVALID_ENUM,		RC_RET_VOID);
21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!rbo,									GL_INVALID_OPERATION,	RC_RET_VOID);
21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Framebuffer::Attachment& fboAttachment = framebufferBinding->getAttachment(point);
21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < bindingRefCount; ndx++)
21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			releaseFboAttachmentReference(fboAttachment);
21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fboAttachment = Framebuffer::Attachment();
21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (rbo)
21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.type	= Framebuffer::ATTACHMENTTYPE_RENDERBUFFER;
21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.name	= rbo->getName();
21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < bindingRefCount; ndx++)
21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				acquireFboAttachmentReference(fboAttachment);
21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21513c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 ReferenceContext::checkFramebufferStatus (deUint32 target)
21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(target != GL_FRAMEBUFFER		&&
21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				target != GL_DRAW_FRAMEBUFFER	&&
21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				target != GL_READ_FRAMEBUFFER, GL_INVALID_ENUM, 0);
21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Select binding point.
21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::Framebuffer* framebufferBinding = (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) ? m_drawFramebufferBinding : m_readFramebufferBinding;
21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Default framebuffer is always complete.
21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!framebufferBinding)
21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return GL_FRAMEBUFFER_COMPLETE;
21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		width				= -1;
21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		height				= -1;
21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	hasAttachment		= false;
21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	attachmentComplete	= true;
21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	dimensionsOk		= true;
21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int point = 0; point < Framebuffer::ATTACHMENTPOINT_LAST; point++)
21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Framebuffer::Attachment&	attachment			= framebufferBinding->getAttachment((Framebuffer::AttachmentPoint)point);
21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int								attachmentWidth		= 0;
21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int								attachmentHeight	= 0;
21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureFormat				attachmentFormat;
21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (attachment.type == Framebuffer::ATTACHMENTTYPE_TEXTURE)
21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Texture*					texture	= m_textures.find(attachment.name);
21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::ConstPixelBufferAccess		level;
21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(texture);
21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (attachment.texTarget == Framebuffer::TEXTARGET_2D)
21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(texture->getType() == Texture::TYPE_2D);
21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const Texture2D* tex2D = static_cast<const Texture2D*>(texture);
21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex2D->hasLevel(attachment.level))
21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					level = tex2D->getLevel(attachment.level);
21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (deInRange32(attachment.texTarget, Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_X,
21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													   Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Z))
21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(texture->getType() == Texture::TYPE_CUBE_MAP);
21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const TextureCube*	texCube	= static_cast<const TextureCube*>(texture);
21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::CubeFace	face	= texTargetToFace(attachment.texTarget);
21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TCU_CHECK(de::inBounds<int>(face, 0, tcu::CUBEFACE_LAST));
21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (texCube->hasFace(attachment.level, face))
22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					level = texCube->getFace(attachment.level, face);
22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (attachment.texTarget == Framebuffer::TEXTARGET_2D_ARRAY)
22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(texture->getType() == Texture::TYPE_2D_ARRAY);
22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const Texture2DArray* tex2DArr = static_cast<const Texture2DArray*>(texture);
22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex2DArr->hasLevel(attachment.level))
22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					level = tex2DArr->getLevel(attachment.level); // \note Slice doesn't matter here.
22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (attachment.texTarget == Framebuffer::TEXTARGET_3D)
22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(texture->getType() == Texture::TYPE_3D);
22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const Texture3D* tex3D = static_cast<const Texture3D*>(texture);
22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex3D->hasLevel(attachment.level))
22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					level = tex3D->getLevel(attachment.level); // \note Slice doesn't matter here.
22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
22198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			else if (attachment.texTarget == Framebuffer::TEXTARGET_CUBE_MAP_ARRAY)
22208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			{
22218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				DE_ASSERT(texture->getType() == Texture::TYPE_CUBE_MAP_ARRAY);
22228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				const TextureCubeArray* texCubeArr = static_cast<const TextureCubeArray*>(texture);
22238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
22248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				if (texCubeArr->hasLevel(attachment.level))
22258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry					level = texCubeArr->getLevel(attachment.level); // \note Slice doesn't matter here.
22268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			}
22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TCU_FAIL("Framebuffer attached to a texture but no valid target specified");
22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attachmentWidth		= level.getWidth();
22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attachmentHeight	= level.getHeight();
22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attachmentFormat	= level.getFormat();
22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (attachment.type == Framebuffer::ATTACHMENTTYPE_RENDERBUFFER)
22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Renderbuffer* renderbuffer = m_renderbuffers.find(attachment.name);
22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(renderbuffer);
22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attachmentWidth		= renderbuffer->getWidth();
22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attachmentHeight	= renderbuffer->getHeight();
22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attachmentFormat	= renderbuffer->getFormat();
22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(attachment.type == Framebuffer::ATTACHMENTTYPE_LAST);
22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue; // Skip rest of checks.
22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasAttachment && attachmentWidth > 0 && attachmentHeight > 0)
22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			width			= attachmentWidth;
22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			height			= attachmentHeight;
22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			hasAttachment	= true;
22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (attachmentWidth != width || attachmentHeight != height)
22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dimensionsOk = false;
22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate attachment point compatibility.
22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (attachmentFormat.order)
22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::R:
22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::RG:
22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::RGB:
22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::RGBA:
22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::sRGB:
22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::sRGBA:
22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (point != Framebuffer::ATTACHMENTPOINT_COLOR0)
22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					attachmentComplete = false;
22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::D:
22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (point != Framebuffer::ATTACHMENTPOINT_DEPTH)
22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					attachmentComplete = false;
22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::S:
22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (point != Framebuffer::ATTACHMENTPOINT_STENCIL)
22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					attachmentComplete = false;
22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::DS:
22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (point != Framebuffer::ATTACHMENTPOINT_DEPTH &&
22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					point != Framebuffer::ATTACHMENTPOINT_STENCIL)
22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					attachmentComplete = false;
22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TCU_FAIL("Unsupported attachment channel order");
22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!attachmentComplete)
22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (!hasAttachment)
22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (!dimensionsOk)
22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return GL_FRAMEBUFFER_COMPLETE;
23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::getFramebufferAttachmentParameteriv (deUint32 target, deUint32 attachment, deUint32 pname, int* params)
23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(target && attachment && pname && params);
23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK(false); // \todo [pyry] Implement
23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::renderbufferStorage (deUint32 target, deUint32 internalformat, int width, int height)
23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat format = glu::mapGLInternalFormat(internalformat);
23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(target != GL_RENDERBUFFER, GL_INVALID_ENUM, RC_RET_VOID);
23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!m_renderbufferBinding, GL_INVALID_OPERATION, RC_RET_VOID);
23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!deInRange32(width, 0, m_limits.maxRenderbufferSize) ||
23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!deInRange32(height, 0, m_limits.maxRenderbufferSize),
23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_INVALID_OPERATION, RC_RET_VOID);
23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(format.order == TextureFormat::CHANNELORDER_LAST ||
23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				format.type == TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderbufferBinding->setStorage(format, (int)width, (int)height);
23213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::renderbufferStorageMultisample (deUint32 target, int samples, deUint32 internalFormat, int width, int height)
23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2012-04-07 pyry] Implement MSAA support.
23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(samples);
23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderbufferStorage(target, internalFormat, width, height);
23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::PixelBufferAccess ReferenceContext::getFboAttachment (const rc::Framebuffer& framebuffer, rc::Framebuffer::AttachmentPoint point)
23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Framebuffer::Attachment& attachment = framebuffer.getAttachment(point);
23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (attachment.type)
23353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::ATTACHMENTTYPE_TEXTURE:
23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Texture* texture = m_textures.find(attachment.name);
23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(texture);
23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (texture->getType() == Texture::TYPE_2D)
23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return dynamic_cast<Texture2D*>(texture)->getLevel(attachment.level);
23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (texture->getType() == Texture::TYPE_CUBE_MAP)
23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return dynamic_cast<TextureCube*>(texture)->getFace(attachment.level, texTargetToFace(attachment.texTarget));
23458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			else if (texture->getType() == Texture::TYPE_2D_ARRAY	||
23468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry					 texture->getType() == Texture::TYPE_3D			||
23478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry					 texture->getType() == Texture::TYPE_CUBE_MAP_ARRAY)
23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
23498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				tcu::PixelBufferAccess level;
23508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
23518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				if (texture->getType() == Texture::TYPE_2D_ARRAY)
23528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry					level = dynamic_cast<Texture2DArray*>(texture)->getLevel(attachment.level);
23538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				else if (texture->getType() == Texture::TYPE_3D)
23548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry					level = dynamic_cast<Texture3D*>(texture)->getLevel(attachment.level);
23558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				else if (texture->getType() == Texture::TYPE_CUBE_MAP_ARRAY)
23568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry					level = dynamic_cast<TextureCubeArray*>(texture)->getLevel(attachment.level);
23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				void* layerData = static_cast<deUint8*>(level.getDataPtr()) + level.getSlicePitch() * attachment.layer;
23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return tcu::PixelBufferAccess(level.getFormat(), level.getWidth(), level.getHeight(), 1, level.getRowPitch(), 0, layerData);
23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return nullAccess();
23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::ATTACHMENTTYPE_RENDERBUFFER:
23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Renderbuffer* rbo = m_renderbuffers.find(attachment.name);
23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(rbo);
23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return rbo->getAccess();
23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return nullAccess();
23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst Texture2D& ReferenceContext::getTexture2D (int unitNdx) const
23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TextureUnit& unit = m_textureUnits[unitNdx];
23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return unit.tex2DBinding ? *unit.tex2DBinding : unit.default2DTex;
23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst TextureCube& ReferenceContext::getTextureCube (int unitNdx) const
23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TextureUnit& unit = m_textureUnits[unitNdx];
23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return unit.texCubeBinding ? *unit.texCubeBinding : unit.defaultCubeTex;
23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isValidBufferTarget (deUint32 target)
23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (target)
23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ARRAY_BUFFER:
23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_COPY_READ_BUFFER:
23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_COPY_WRITE_BUFFER:
23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DRAW_INDIRECT_BUFFER:
23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ELEMENT_ARRAY_BUFFER:
24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PIXEL_PACK_BUFFER:
24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PIXEL_UNPACK_BUFFER:
24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TRANSFORM_FEEDBACK_BUFFER:
24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_UNIFORM_BUFFER:
24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::setBufferBinding (deUint32 target, DataBuffer* buffer)
24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DataBuffer** bindingPoint = DE_NULL;
24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VertexArray* vertexArrayObject = (m_vertexArrayBinding) ? (m_vertexArrayBinding) : (&m_clientVertexArray);
24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (target)
24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ARRAY_BUFFER:				bindingPoint = &m_arrayBufferBinding;								break;
24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_COPY_READ_BUFFER:			bindingPoint = &m_copyReadBufferBinding;							break;
24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_COPY_WRITE_BUFFER:			bindingPoint = &m_copyWriteBufferBinding;							break;
24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DRAW_INDIRECT_BUFFER:		bindingPoint = &m_drawIndirectBufferBinding;						break;
24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ELEMENT_ARRAY_BUFFER:		bindingPoint = &vertexArrayObject->m_elementArrayBufferBinding;		break;
24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PIXEL_PACK_BUFFER:			bindingPoint = &m_pixelPackBufferBinding;							break;
24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PIXEL_UNPACK_BUFFER:		bindingPoint = &m_pixelUnpackBufferBinding;							break;
24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TRANSFORM_FEEDBACK_BUFFER:	bindingPoint = &m_transformFeedbackBufferBinding;					break;
24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_UNIFORM_BUFFER:				bindingPoint = &m_uniformBufferBinding;								break;
24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (*bindingPoint)
24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffers.releaseReference(*bindingPoint);
24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*bindingPoint = DE_NULL;
24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (buffer)
24393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffers.acquireReference(buffer);
24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	*bindingPoint = buffer;
24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24443c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDataBuffer* ReferenceContext::getBufferBinding (deUint32 target) const
24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VertexArray* vertexArrayObject = (m_vertexArrayBinding) ? (m_vertexArrayBinding) : (&m_clientVertexArray);
24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (target)
24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ARRAY_BUFFER:				return m_arrayBufferBinding;
24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_COPY_READ_BUFFER:			return m_copyReadBufferBinding;
24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_COPY_WRITE_BUFFER:			return m_copyWriteBufferBinding;
24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DRAW_INDIRECT_BUFFER:		return m_drawIndirectBufferBinding;
24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ELEMENT_ARRAY_BUFFER:		return vertexArrayObject->m_elementArrayBufferBinding;
24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PIXEL_PACK_BUFFER:			return m_pixelPackBufferBinding;
24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PIXEL_UNPACK_BUFFER:		return m_pixelUnpackBufferBinding;
24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TRANSFORM_FEEDBACK_BUFFER:	return m_transformFeedbackBufferBinding;
24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_UNIFORM_BUFFER:				return m_uniformBufferBinding;
24593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::bindBuffer (deUint32 target, deUint32 buffer)
24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidBufferTarget(target), GL_INVALID_ENUM, RC_RET_VOID);
24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::DataBuffer*	bufObj	= DE_NULL;
24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (buffer != 0)
24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bufObj = m_buffers.find(buffer);
24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!bufObj)
24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bufObj = new DataBuffer(buffer);
24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_buffers.insert(bufObj);
24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setBufferBinding(target, bufObj);
24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::genBuffers (int numBuffers, deUint32* buffers)
24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!buffers, GL_INVALID_VALUE, RC_RET_VOID);
24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < numBuffers; ndx++)
24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buffers[ndx] = m_buffers.allocateName();
24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteBuffers (int numBuffers, const deUint32* buffers)
24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(numBuffers < 0, GL_INVALID_VALUE, RC_RET_VOID);
24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < numBuffers; ndx++)
24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	buffer	= buffers[ndx];
24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DataBuffer*	bufObj	= DE_NULL;
25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (buffer == 0)
25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bufObj = m_buffers.find(buffer);
25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (bufObj)
25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deleteBuffer(bufObj);
25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteBuffer (DataBuffer* buffer)
25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 bindingPoints[] =
25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_ARRAY_BUFFER,
25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_COPY_READ_BUFFER,
25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_COPY_WRITE_BUFFER,
25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_DRAW_INDIRECT_BUFFER,
25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_ELEMENT_ARRAY_BUFFER,
25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_PIXEL_PACK_BUFFER,
25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_PIXEL_UNPACK_BUFFER,
25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_TRANSFORM_FEEDBACK_BUFFER,
25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_UNIFORM_BUFFER
25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bindingNdx = 0; bindingNdx < DE_LENGTH_OF_ARRAY(bindingPoints); bindingNdx++)
25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (getBufferBinding(bindingPoints[bindingNdx]) == buffer)
25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setBufferBinding(bindingPoints[bindingNdx], DE_NULL);
25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VertexArray*> vertexArrays;
25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_vertexArrays.getAll(vertexArrays);
25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexArrays.push_back(&m_clientVertexArray);
25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<VertexArray*>::iterator i = vertexArrays.begin(); i != vertexArrays.end(); i++)
25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((*i)->m_elementArrayBufferBinding == buffer)
25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_buffers.releaseReference(buffer);
25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(*i)->m_elementArrayBufferBinding = DE_NULL;
25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (size_t vertexAttribNdx = 0; vertexAttribNdx < (*i)->m_arrays.size(); ++vertexAttribNdx)
25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if ((*i)->m_arrays[vertexAttribNdx].bufferBinding == buffer)
25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_buffers.releaseReference(buffer);
25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					(*i)->m_arrays[vertexAttribNdx].bufferDeleted = true;
25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					(*i)->m_arrays[vertexAttribNdx].bufferBinding = DE_NULL;
25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(buffer->getRefCount() == 1);
25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_buffers.releaseReference(buffer);
25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::bufferData (deUint32 target, deIntptr size, const void* data, deUint32 usage)
25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidBufferTarget(target), GL_INVALID_ENUM, RC_RET_VOID);
25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(size < 0, GL_INVALID_VALUE, RC_RET_VOID);
25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(usage);
25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DataBuffer* buffer = getBufferBinding(target);
25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!buffer, GL_INVALID_OPERATION, RC_RET_VOID);
25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((deIntptr)(int)size == size);
25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buffer->setStorage((int)size);
25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (data)
25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMemcpy(buffer->getData(), data, (int)size);
25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::bufferSubData (deUint32 target, deIntptr offset, deIntptr size, const void* data)
25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidBufferTarget(target), GL_INVALID_ENUM, RC_RET_VOID);
25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(offset < 0 || size < 0, GL_INVALID_VALUE, RC_RET_VOID);
25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DataBuffer* buffer = getBufferBinding(target);
25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!buffer, GL_INVALID_OPERATION, RC_RET_VOID);
25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((int)(offset+size) > buffer->getSize(), GL_INVALID_VALUE, RC_RET_VOID);
25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMemcpy(buffer->getData()+offset, data, (int)size);
25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clearColor (float red, float green, float blue, float alpha)
25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_clearColor = Vec4(de::clamp(red,	0.0f, 1.0f),
25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::clamp(green,	0.0f, 1.0f),
25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::clamp(blue,	0.0f, 1.0f),
25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::clamp(alpha,	0.0f, 1.0f));
25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clearDepthf (float depth)
25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_clearDepth = de::clamp(depth, 0.0f, 1.0f);
26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clearStencil (int stencil)
26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_clearStencil = stencil;
26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::scissor (int x, int y, int width, int height)
26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0 || height < 0, GL_INVALID_VALUE, RC_RET_VOID);
26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_scissorBox = IVec4(x, y, width, height);
26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::enable (deUint32 cap)
26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (cap)
26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_BLEND:					m_blendEnabled				= true;	break;
26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SCISSOR_TEST:			m_scissorEnabled			= true;	break;
26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DEPTH_TEST:				m_depthTestEnabled			= true;	break;
26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_STENCIL_TEST:			m_stencilTestEnabled		= true;	break;
26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_POLYGON_OFFSET_FILL:	m_polygonOffsetFillEnabled	= true;	break;
26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_FRAMEBUFFER_SRGB:
26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isContextTypeGLCore(getType()))
26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_sRGBUpdateEnabled = true;
26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DEPTH_CLAMP:
26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isContextTypeGLCore(getType()))
26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_depthClampEnabled = true;
26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DITHER:
26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Not implemented - just ignored.
26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PRIMITIVE_RESTART_FIXED_INDEX:
26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!glu::isContextTypeGLCore(getType()))
26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_primitiveRestartFixedIndex = true;
26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PRIMITIVE_RESTART:
26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isContextTypeGLCore(getType()))
26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_primitiveRestartSettableIndex = true;
26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::disable (deUint32 cap)
26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (cap)
26733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_BLEND:					m_blendEnabled				= false;	break;
26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SCISSOR_TEST:			m_scissorEnabled			= false;	break;
26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DEPTH_TEST:				m_depthTestEnabled			= false;	break;
26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_STENCIL_TEST:			m_stencilTestEnabled		= false;	break;
26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_POLYGON_OFFSET_FILL:	m_polygonOffsetFillEnabled	= false;	break;
26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_FRAMEBUFFER_SRGB:
26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isContextTypeGLCore(getType()))
26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_sRGBUpdateEnabled = false;
26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
26853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DEPTH_CLAMP:
26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isContextTypeGLCore(getType()))
26913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_depthClampEnabled = false;
26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DITHER:
26993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PRIMITIVE_RESTART_FIXED_INDEX:
27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!glu::isContextTypeGLCore(getType()))
27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
27043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_primitiveRestartFixedIndex = false;
27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
27073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
27093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PRIMITIVE_RESTART:
27113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isContextTypeGLCore(getType()))
27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_primitiveRestartSettableIndex = false;
27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
27183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
27203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isValidCompareFunc (deUint32 func)
27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (func)
27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_NEVER:
27303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LESS:
27313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LEQUAL:
27323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_GREATER:
27333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_GEQUAL:
27343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_EQUAL:
27353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_NOTEQUAL:
27363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ALWAYS:
27373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
27383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
27403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
27413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isValidStencilOp (deUint32 op)
27453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (op)
27473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_KEEP:
27493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ZERO:
27503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_REPLACE:
27513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_INCR:
27523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_INCR_WRAP:
27533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DECR:
27543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DECR_WRAP:
27553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_INVERT:
27563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
27573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
27593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
27603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::stencilFunc (deUint32 func, int ref, deUint32 mask)
27643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
27663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::stencilFuncSeparate (deUint32 face, deUint32 func, int ref, deUint32 mask)
27693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	setFront	= face == GL_FRONT || face == GL_FRONT_AND_BACK;
27713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	setBack		= face == GL_BACK || face == GL_FRONT_AND_BACK;
27723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidCompareFunc(func), GL_INVALID_ENUM, RC_RET_VOID);
27743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!setFront && !setBack, GL_INVALID_ENUM, RC_RET_VOID);
27753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int type = 0; type < rr::FACETYPE_LAST; ++type)
27773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((type == rr::FACETYPE_FRONT && setFront) ||
27793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(type == rr::FACETYPE_BACK && setBack))
27803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_stencil[type].func	= func;
27823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_stencil[type].ref		= ref;
27833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_stencil[type].opMask	= mask;
27843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::stencilOp (deUint32 sfail, deUint32 dpfail, deUint32 dppass)
27893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stencilOpSeparate(GL_FRONT_AND_BACK, sfail, dpfail, dppass);
27913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::stencilOpSeparate (deUint32 face, deUint32 sfail, deUint32 dpfail, deUint32 dppass)
27943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	setFront	= face == GL_FRONT || face == GL_FRONT_AND_BACK;
27963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	setBack		= face == GL_BACK || face == GL_FRONT_AND_BACK;
27973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidStencilOp(sfail)	||
27993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!isValidStencilOp(dpfail)	||
28003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!isValidStencilOp(dppass),
28013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_INVALID_ENUM, RC_RET_VOID);
28023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!setFront && !setBack, GL_INVALID_ENUM, RC_RET_VOID);
28033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int type = 0; type < rr::FACETYPE_LAST; ++type)
28053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
28063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((type == rr::FACETYPE_FRONT && setFront) ||
28073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(type == rr::FACETYPE_BACK && setBack))
28083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_stencil[type].opStencilFail	= sfail;
28103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_stencil[type].opDepthFail		= dpfail;
28113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_stencil[type].opDepthPass		= dppass;
28123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
28133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
28143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::depthFunc (deUint32 func)
28173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidCompareFunc(func), GL_INVALID_ENUM, RC_RET_VOID);
28193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_depthFunc = func;
28203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::depthRangef (float n, float f)
28233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_depthRangeNear = de::clamp(n, 0.0f, 1.0f);
28253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_depthRangeFar = de::clamp(f, 0.0f, 1.0f);
28263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::depthRange (double n, double f)
28293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	depthRangef((float)n, (float)f);
28313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::polygonOffset (float factor, float units)
28343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_polygonOffsetFactor = factor;
28363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_polygonOffsetUnits = units;
28373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::provokingVertex (deUint32 convention)
28403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// only in core
28423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isContextTypeGLCore(getType()));
28433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (convention)
28453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
28463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_FIRST_VERTEX_CONVENTION:	m_provokingFirstVertexConvention = true; break;
28473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LAST_VERTEX_CONVENTION:		m_provokingFirstVertexConvention = false; break;
28483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
28503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
28513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
28523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::primitiveRestartIndex (deUint32 index)
28553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// only in core
28573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isContextTypeGLCore(getType()));
28583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_primitiveRestartIndex = index;
28593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool isValidBlendEquation (deUint32 mode)
28623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return mode == GL_FUNC_ADD				||
28643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   mode == GL_FUNC_SUBTRACT			||
28653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   mode == GL_FUNC_REVERSE_SUBTRACT	||
28663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   mode == GL_MIN					||
28673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   mode == GL_MAX;
28683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isValidBlendFactor (deUint32 factor)
28713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (factor)
28733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
28743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ZERO:
28753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ONE:
28763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SRC_COLOR:
28773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ONE_MINUS_SRC_COLOR:
28783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DST_COLOR:
28793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ONE_MINUS_DST_COLOR:
28803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SRC_ALPHA:
28813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ONE_MINUS_SRC_ALPHA:
28823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DST_ALPHA:
28833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ONE_MINUS_DST_ALPHA:
28843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_CONSTANT_COLOR:
28853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ONE_MINUS_CONSTANT_COLOR:
28863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_CONSTANT_ALPHA:
28873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ONE_MINUS_CONSTANT_ALPHA:
28883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SRC_ALPHA_SATURATE:
28893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
28903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
28923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
28933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
28943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::blendEquation (deUint32 mode)
28973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidBlendEquation(mode), GL_INVALID_ENUM, RC_RET_VOID);
28993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendModeRGB		= mode;
29013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendModeAlpha	= mode;
29023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::blendEquationSeparate (deUint32 modeRGB, deUint32 modeAlpha)
29053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidBlendEquation(modeRGB) ||
29073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!isValidBlendEquation(modeAlpha),
29083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_INVALID_ENUM, RC_RET_VOID);
29093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendModeRGB		= modeRGB;
29113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendModeAlpha	= modeAlpha;
29123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::blendFunc (deUint32 src, deUint32 dst)
29153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidBlendFactor(src) ||
29173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!isValidBlendFactor(dst),
29183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_INVALID_ENUM, RC_RET_VOID);
29193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorSrcRGB		= src;
29213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorSrcAlpha	= src;
29223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorDstRGB		= dst;
29233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorDstAlpha	= dst;
29243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::blendFuncSeparate (deUint32 srcRGB, deUint32 dstRGB, deUint32 srcAlpha, deUint32 dstAlpha)
29273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidBlendFactor(srcRGB)		||
29293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!isValidBlendFactor(dstRGB)		||
29303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!isValidBlendFactor(srcAlpha)	||
29313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!isValidBlendFactor(dstAlpha),
29323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_INVALID_ENUM, RC_RET_VOID);
29333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorSrcRGB		= srcRGB;
29353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorSrcAlpha	= srcAlpha;
29363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorDstRGB		= dstRGB;
29373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorDstAlpha	= dstAlpha;
29383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::blendColor (float red, float green, float blue, float alpha)
29413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendColor = Vec4(de::clamp(red,	0.0f, 1.0f),
29433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::clamp(green,	0.0f, 1.0f),
29443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::clamp(blue,	0.0f, 1.0f),
29453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::clamp(alpha,	0.0f, 1.0f));
29463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::colorMask (deBool r, deBool g, deBool b, deBool a)
29493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colorMask = tcu::BVec4(!!r, !!g, !!b, !!a);
29513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::depthMask (deBool mask)
29543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_depthMask = !!mask;
29563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::stencilMask (deUint32 mask)
29593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
29613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::stencilMaskSeparate (deUint32 face, deUint32 mask)
29643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	setFront	= face == GL_FRONT || face == GL_FRONT_AND_BACK;
29663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	setBack		= face == GL_BACK || face == GL_FRONT_AND_BACK;
29673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!setFront && !setBack, GL_INVALID_ENUM, RC_RET_VOID);
29693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (setFront)	m_stencil[rr::FACETYPE_FRONT].writeMask	= mask;
29713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (setBack)	m_stencil[rr::FACETYPE_BACK].writeMask	= mask;
29723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumStencilBits (const tcu::TextureFormat& format)
29753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (format.order)
29773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::TextureFormat::S:
29793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (format.type)
29803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case tcu::TextureFormat::UNSIGNED_INT8:		return 8;
29823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case tcu::TextureFormat::UNSIGNED_INT16:	return 16;
29833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case tcu::TextureFormat::UNSIGNED_INT32:	return 32;
29843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
29853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
29863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return 0;
29873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::TextureFormat::DS:
29903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (format.type)
29913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case tcu::TextureFormat::UNSIGNED_INT_24_8:				return 8;
29933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:	return 8;
29943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
29953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
29963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return 0;
29973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
30003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
30013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
30023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
30033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3005b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyrystatic inline deUint32 maskStencil (int numBits, deUint32 s)
3006b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry{
3007b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry	return s & deBitMask32(0, numBits);
3008b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry}
30093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3010b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyrystatic inline void writeMaskedStencil (const rr::MultisamplePixelBufferAccess& access, int s, int x, int y, deUint32 stencil, deUint32 writeMask)
30113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3012b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry	DE_ASSERT(access.raw().getFormat().order == tcu::TextureFormat::S);
3013b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry
3014b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry	const deUint32 oldVal = access.raw().getPixelUint(s, x, y).x();
3015b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry	const deUint32 newVal = (oldVal & ~writeMask) | (stencil & writeMask);
3016b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry	access.raw().setPixel(tcu::UVec4(newVal, 0u, 0u, 0u), s, x, y);
30173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline void writeDepthOnly (const rr::MultisamplePixelBufferAccess& access, int s, int x, int y, float depth)
30203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	access.raw().setPixDepth(depth, s, x, y);
30223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3024b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyrystatic rr::MultisamplePixelBufferAccess getDepthMultisampleAccess (const rr::MultisamplePixelBufferAccess& combinedDSaccess)
3025b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry{
3026b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry	return rr::MultisamplePixelBufferAccess::fromMultisampleAccess(tcu::getEffectiveDepthStencilAccess(combinedDSaccess.raw(), tcu::Sampler::MODE_DEPTH));
3027b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry}
3028b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry
3029b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyrystatic rr::MultisamplePixelBufferAccess getStencilMultisampleAccess (const rr::MultisamplePixelBufferAccess& combinedDSaccess)
3030b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry{
3031b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry	return rr::MultisamplePixelBufferAccess::fromMultisampleAccess(tcu::getEffectiveDepthStencilAccess(combinedDSaccess.raw(), tcu::Sampler::MODE_STENCIL));
3032b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry}
3033b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry
30343c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 ReferenceContext::blitResolveMultisampleFramebuffer (deUint32 mask, const IVec4& srcRect, const IVec4& dstRect, bool flipX, bool flipY)
30353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (mask & GL_COLOR_BUFFER_BIT)
30373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
30383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisampleConstPixelBufferAccess	src			= rr::getSubregion(getReadColorbuffer(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w());
30393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::PixelBufferAccess					dst			= tcu::getSubregion(getDrawColorbuffer().toSinglesampleAccess(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w());
30403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureChannelClass				dstClass	= tcu::getTextureChannelClass(dst.getFormat().type);
30413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool									dstIsFloat	= dstClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT		||
30423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															  dstClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT	||
30433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															  dstClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
304489a729134d6a1880d2b59426dfe14d615381e314Jarkko Pöyry		bool									srcIsSRGB	= tcu::isSRGB(src.raw().getFormat());
304589a729134d6a1880d2b59426dfe14d615381e314Jarkko Pöyry		bool									dstIsSRGB	= tcu::isSRGB(dst.getFormat());
30463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool								convertSRGB	= m_sRGBUpdateEnabled && glu::isContextTypeES(getType());
30473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!convertSRGB)
30493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::ConstPixelBufferAccess	srcRaw	= src.raw();
30513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TextureFormat			srcFmt	= toNonSRGBFormat(srcRaw.getFormat());
30523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			srcRaw	= tcu::ConstPixelBufferAccess(srcFmt, srcRaw.getWidth(), srcRaw.getHeight(), srcRaw.getDepth(), srcRaw.getRowPitch(), srcRaw.getSlicePitch(), srcRaw.getDataPtr());
30543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			src		= rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(srcRaw);
30553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst		= tcu::PixelBufferAccess(toNonSRGBFormat(dst.getFormat()), dst.getWidth(), dst.getHeight(), dst.getDepth(), dst.getRowPitch(), dst.getSlicePitch(), dst.getDataPtr());
30573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < dstRect.z(); ++x)
30603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < dstRect.w(); ++y)
30613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int srcX = (flipX) ? (srcRect.z() - x - 1) : (x);
30633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int srcY = (flipY) ? (srcRect.z() - y - 1) : (y);
30643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (dstIsFloat || srcIsSRGB)
30663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
30673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Vec4 p = src.raw().getPixel(0, srcX,srcY);
30683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst.setPixel((dstIsSRGB && convertSRGB) ? tcu::linearToSRGB(p) : p, x, y);
30693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
30703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
30713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst.setPixel(src.raw().getPixelInt(0, srcX, srcY), x, y);
30723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
30743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (mask & GL_DEPTH_BUFFER_BIT)
30763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3077b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry		rr::MultisampleConstPixelBufferAccess	src	= rr::getSubregion(getReadDepthbuffer(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w());
30783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess		dst	= rr::getSubregion(getDrawDepthbuffer(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w());
30793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < dstRect.z(); ++x)
30813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < dstRect.w(); ++y)
30823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int srcX = (flipX) ? (srcRect.z() - x - 1) : (x);
30843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int srcY = (flipY) ? (srcRect.z() - y - 1) : (y);
30853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			writeDepthOnly(dst, 0, x, y, src.raw().getPixel(0, srcX, srcY).x());
30873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
30893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (mask & GL_STENCIL_BUFFER_BIT)
30913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3092b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry		rr::MultisampleConstPixelBufferAccess	src	= getStencilMultisampleAccess(rr::getSubregion(getReadStencilbuffer(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w()));
3093b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry		rr::MultisamplePixelBufferAccess		dst	= getStencilMultisampleAccess(rr::getSubregion(getDrawStencilbuffer(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w()));
30943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < dstRect.z(); ++x)
30963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < dstRect.w(); ++y)
30973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3098b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry			int			srcX		= (flipX) ? (srcRect.z() - x - 1) : (x);
3099b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry			int			srcY		= (flipY) ? (srcRect.z() - y - 1) : (y);
3100b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry			deUint32	srcStencil	= src.raw().getPixelUint(0, srcX, srcY).x();
31013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3102b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry			writeMaskedStencil(dst, 0, x, y, srcStencil, m_stencil[rr::FACETYPE_FRONT].writeMask);
31033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
31043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
31053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return GL_NO_ERROR;
31073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::blitFramebuffer (int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, deUint32 mask, deUint32 filter)
31103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
31113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// p0 in inclusive, p1 exclusive.
31123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Negative width/height means swap.
31133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	swapSrcX	= srcX1 < srcX0;
31143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	swapSrcY	= srcY1 < srcY0;
31153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	swapDstX	= dstX1 < dstX0;
31163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	swapDstY	= dstY1 < dstY0;
31173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		srcW		= de::abs(srcX1-srcX0);
31183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		srcH		= de::abs(srcY1-srcY0);
31193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		dstW		= de::abs(dstX1-dstX0);
31203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		dstH		= de::abs(dstY1-dstY0);
31213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	scale		= srcW != dstW || srcH != dstH;
31223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		srcOriginX	= swapSrcX ? srcX1 : srcX0;
31233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		srcOriginY	= swapSrcY ? srcY1 : srcY0;
31243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		dstOriginX	= swapDstX ? dstX1 : dstX0;
31253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		dstOriginY	= swapDstY ? dstY1 : dstY0;
31263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec4	srcRect		= IVec4(srcOriginX, srcOriginY, srcW, srcH);
31273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec4	dstRect		= IVec4(dstOriginX, dstOriginY, dstW, dstH);
31283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(filter != GL_NEAREST && filter != GL_LINEAR, GL_INVALID_ENUM, RC_RET_VOID);
31303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((mask & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) != 0 && filter != GL_NEAREST, GL_INVALID_OPERATION, RC_RET_VOID);
31313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Validate that both targets are complete.
31333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE ||
31343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				checkFramebufferStatus(GL_READ_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_OPERATION, RC_RET_VOID);
31353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check samples count is valid
31373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(getDrawColorbuffer().getNumSamples() != 1, GL_INVALID_OPERATION, RC_RET_VOID);
31383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check size restrictions of multisampled case
31403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (getReadColorbuffer().getNumSamples() != 1)
31413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
31423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Src and Dst rect dimensions must be the same
31433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(srcW != dstW || srcH != dstH, GL_INVALID_OPERATION, RC_RET_VOID);
31443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Framebuffer formats must match
31463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mask & GL_COLOR_BUFFER_BIT)		RC_IF_ERROR(getReadColorbuffer().raw().getFormat()   != getDrawColorbuffer().raw().getFormat(),   GL_INVALID_OPERATION, RC_RET_VOID);
31473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mask & GL_DEPTH_BUFFER_BIT)		RC_IF_ERROR(getReadDepthbuffer().raw().getFormat()   != getDrawDepthbuffer().raw().getFormat(),   GL_INVALID_OPERATION, RC_RET_VOID);
31483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mask & GL_STENCIL_BUFFER_BIT)	RC_IF_ERROR(getReadStencilbuffer().raw().getFormat() != getDrawStencilbuffer().raw().getFormat(), GL_INVALID_OPERATION, RC_RET_VOID);
31493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
31503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute actual source rect.
31523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	srcRect = (mask & GL_COLOR_BUFFER_BIT)		? intersect(srcRect, getBufferRect(getReadColorbuffer()))	: srcRect;
31533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	srcRect = (mask & GL_DEPTH_BUFFER_BIT)		? intersect(srcRect, getBufferRect(getReadDepthbuffer()))	: srcRect;
31543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	srcRect = (mask & GL_STENCIL_BUFFER_BIT)	? intersect(srcRect, getBufferRect(getReadStencilbuffer()))	: srcRect;
31553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute destination rect.
31573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dstRect = (mask & GL_COLOR_BUFFER_BIT)		? intersect(dstRect, getBufferRect(getDrawColorbuffer()))	: dstRect;
31583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dstRect = (mask & GL_DEPTH_BUFFER_BIT)		? intersect(dstRect, getBufferRect(getDrawDepthbuffer()))	: dstRect;
31593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dstRect = (mask & GL_STENCIL_BUFFER_BIT)	? intersect(dstRect, getBufferRect(getDrawStencilbuffer()))	: dstRect;
31603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dstRect = m_scissorEnabled					? intersect(dstRect, m_scissorBox)							: dstRect;
31613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isEmpty(srcRect) || isEmpty(dstRect))
31633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return; // Don't attempt copy.
31643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Multisampled read buffer is a special case
31663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (getReadColorbuffer().getNumSamples() != 1)
31673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
31683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 error = blitResolveMultisampleFramebuffer(mask, srcRect, dstRect, swapSrcX ^ swapDstX, swapSrcY ^ swapDstY);
31693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (error != GL_NO_ERROR)
31713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(error);
31723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
31743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
31753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Multisample pixel buffers can now be accessed like non-multisampled because multisample read buffer case is already handled. => sample count must be 1
31773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Coordinate transformation:
31793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Dst offset space -> dst rectangle space -> src rectangle space -> src offset space.
31803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat3 transform = tcu::translationMatrix(Vec2((float)(srcX0 - srcRect.x()), (float)(srcY0 - srcRect.y())))
31813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						* tcu::Mat3(Vec3((float)(srcX1-srcX0) / (float)(dstX1-dstX0),
31823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 (float)(srcY1-srcY0) / (float)(dstY1-dstY0),
31833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 1.0f))
31843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						* tcu::translationMatrix(Vec2((float)(dstRect.x() - dstX0), (float)(dstRect.y() - dstY0)));
31853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (mask & GL_COLOR_BUFFER_BIT)
31873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
31883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::ConstPixelBufferAccess		src			= tcu::getSubregion(getReadColorbuffer().toSinglesampleAccess(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w());
31893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::PixelBufferAccess			dst			= tcu::getSubregion(getDrawColorbuffer().toSinglesampleAccess(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w());
31903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureChannelClass		dstClass	= tcu::getTextureChannelClass(dst.getFormat().type);
31913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool							dstIsFloat	= dstClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT		||
31923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													  dstClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT	||
31933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													  dstClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
31943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Sampler::FilterMode		sFilter		= (scale && filter == GL_LINEAR) ? tcu::Sampler::LINEAR : tcu::Sampler::NEAREST;
31953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Sampler					sampler		(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
31963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 sFilter, sFilter, 0.0f /* lod threshold */, false /* non-normalized coords */);
319789a729134d6a1880d2b59426dfe14d615381e314Jarkko Pöyry		bool							srcIsSRGB	= tcu::isSRGB(src.getFormat());
319889a729134d6a1880d2b59426dfe14d615381e314Jarkko Pöyry		bool							dstIsSRGB	= tcu::isSRGB(dst.getFormat());
31993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool						convertSRGB	= m_sRGBUpdateEnabled && glu::isContextTypeES(getType());
32003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!convertSRGB)
32023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
32033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			src	= tcu::ConstPixelBufferAccess	(toNonSRGBFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth(), src.getRowPitch(), src.getSlicePitch(), src.getDataPtr());
32043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst	= tcu::PixelBufferAccess		(toNonSRGBFormat(dst.getFormat()), dst.getWidth(), dst.getHeight(), dst.getDepth(), dst.getRowPitch(), dst.getSlicePitch(), dst.getDataPtr());
32053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
32063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note We don't check for unsupported conversions, unlike spec requires.
32083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int yo = 0; yo < dstRect.w(); yo++)
32103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
32113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int xo = 0; xo < dstRect.z(); xo++)
32123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
32133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	dX	= (float)xo + 0.5f;
32143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	dY	= (float)yo + 0.5f;
32153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \note Only affine part is used.
32173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	sX	= transform(0, 0)*dX + transform(0, 1)*dY + transform(0, 2);
32183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	sY	= transform(1, 0)*dX + transform(1, 1)*dY + transform(1, 2);
32193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// do not copy pixels outside the modified source region (modified by buffer intersection)
32213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (sX < 0.0f || sX >= (float)srcRect.z() ||
32223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sY < 0.0f || sY >= (float)srcRect.w())
32233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
32243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (dstIsFloat || srcIsSRGB || filter == tcu::Sampler::LINEAR)
32263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
32273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					Vec4 p = src.sample2D(sampler, sampler.minFilter, sX, sY, 0);
32283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					dst.setPixel((dstIsSRGB && convertSRGB) ? tcu::linearToSRGB(p) : p, xo, yo);
32293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
32303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
32313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					dst.setPixel(src.getPixelInt(deFloorFloatToInt32(sX), deFloorFloatToInt32(sY)), xo, yo);
32323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
32333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
32343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
32353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((mask & GL_DEPTH_BUFFER_BIT) && m_depthMask)
32373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
32385a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		rr::MultisampleConstPixelBufferAccess	src		= getDepthMultisampleAccess(rr::getSubregion(getReadDepthbuffer(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w()));
32395a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		rr::MultisamplePixelBufferAccess		dst		= getDepthMultisampleAccess(rr::getSubregion(getDrawDepthbuffer(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w()));
32403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int yo = 0; yo < dstRect.w(); yo++)
32423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
32433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int xo = 0; xo < dstRect.z(); xo++)
32443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
32453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int sampleNdx = 0; // multisample read buffer case is already handled
32463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	dX	= (float)xo + 0.5f;
32483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	dY	= (float)yo + 0.5f;
32493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	sX	= transform(0, 0)*dX + transform(0, 1)*dY + transform(0, 2);
32503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	sY	= transform(1, 0)*dX + transform(1, 1)*dY + transform(1, 2);
32513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32525a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry				writeDepthOnly(dst, sampleNdx, xo, yo, src.raw().getPixDepth(sampleNdx, deFloorFloatToInt32(sX), deFloorFloatToInt32(sY)));
32533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
32543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
32553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
32563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (mask & GL_STENCIL_BUFFER_BIT)
32583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3259b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry		rr::MultisampleConstPixelBufferAccess	src	= getStencilMultisampleAccess(rr::getSubregion(getReadStencilbuffer(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w()));
3260b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry		rr::MultisamplePixelBufferAccess		dst	= getStencilMultisampleAccess(rr::getSubregion(getDrawStencilbuffer(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w()));
32613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int yo = 0; yo < dstRect.w(); yo++)
32633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
32643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int xo = 0; xo < dstRect.z(); xo++)
32653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
3266b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry				const int	sampleNdx = 0; // multisample read buffer case is already handled
32673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3268b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry				float		dX			= (float)xo + 0.5f;
3269b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry				float		dY			= (float)yo + 0.5f;
3270b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry				float		sX			= transform(0, 0)*dX + transform(0, 1)*dY + transform(0, 2);
3271b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry				float		sY			= transform(1, 0)*dX + transform(1, 1)*dY + transform(1, 2);
3272b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry				deUint32	srcStencil	= src.raw().getPixelUint(sampleNdx, deFloorFloatToInt32(sX), deFloorFloatToInt32(sY)).x();
32733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3274b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry				writeMaskedStencil(dst, sampleNdx, xo, yo, srcStencil, m_stencil[rr::FACETYPE_FRONT].writeMask);
32753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
32763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
32773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
32783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::invalidateSubFramebuffer (deUint32 target, int numAttachments, const deUint32* attachments, int x, int y, int width, int height)
32813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(target != GL_FRAMEBUFFER, GL_INVALID_ENUM, RC_RET_VOID);
32833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((numAttachments < 0) || (numAttachments > 1 && attachments == DE_NULL), GL_INVALID_VALUE, RC_RET_VOID);
32843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0 || height < 0, GL_INVALID_VALUE, RC_RET_VOID);
32853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2012-07-17 pyry] Support multiple color attachments.
32873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4		colorClearValue		(0.0f);
32893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		depthClearValue		= 1.0f;
32903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		stencilClearValue	= 0;
32913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool			isFboBound			= m_drawFramebufferBinding != DE_NULL;
32933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool			discardBuffers[3]	= { false, false, false }; // Color, depth, stencil
32943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int attNdx = 0; attNdx < numAttachments; attNdx++)
32963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
32973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool	isColor			= attachments[attNdx] == (isFboBound ? GL_COLOR_ATTACHMENT0		: GL_COLOR);
32983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool	isDepth			= attachments[attNdx] == (isFboBound ? GL_DEPTH_ATTACHMENT		: GL_DEPTH);
32993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool	isStencil		= attachments[attNdx] == (isFboBound ? GL_STENCIL_ATTACHMENT	: GL_STENCIL);
33003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool	isDepthStencil	= isFboBound && attachments[attNdx] == GL_DEPTH_STENCIL_ATTACHMENT;
33013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!isColor && !isDepth && !isStencil && !isDepthStencil, GL_INVALID_VALUE, RC_RET_VOID);
33033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isColor)						discardBuffers[0] = true;
33053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isDepth || isDepthStencil)		discardBuffers[1] = true;
33063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isStencil || isDepthStencil)	discardBuffers[2] = true;
33073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < 3; ndx++)
33103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!discardBuffers[ndx])
33123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
33133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								isColor					= ndx == 0;
33153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								isDepth					= ndx == 1;
33163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								isStencil				= ndx == 2;
3317b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry		rr::MultisamplePixelBufferAccess	buf						= isColor ? getDrawColorbuffer()								:
3318b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry																	  isDepth ? getDepthMultisampleAccess(getDrawDepthbuffer())		:
3319b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry																				getStencilMultisampleAccess(getDrawStencilbuffer());
33203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isEmpty(buf))
33223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
33233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::IVec4							area					= intersect(tcu::IVec4(0, 0, buf.raw().getHeight(), buf.raw().getDepth()), tcu::IVec4(x, y, width, height));
33253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess	access					= rr::getSubregion(buf, area.x(), area.y(), area.z(), area.w());
33263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3327b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry		if (isColor)
3328b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry			rr::clear(access, colorClearValue);
3329b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry		else if (isDepth)
3330b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry			rr::clear(access, tcu::Vec4(depthClearValue));
3331b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry		else if (isStencil)
3332b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry			rr::clear(access, tcu::IVec4(stencilClearValue));
33333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::invalidateFramebuffer (deUint32 target, int numAttachments, const deUint32* attachments)
33373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2012-07-17 pyry] Support multiple color attachments.
33393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisampleConstPixelBufferAccess	colorBuf0	= getDrawColorbuffer();
33403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisampleConstPixelBufferAccess	depthBuf	= getDrawDepthbuffer();
33413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisampleConstPixelBufferAccess	stencilBuf	= getDrawStencilbuffer();
33423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int										width		= 0;
33433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int										height		= 0;
33443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	width = de::max(width, colorBuf0.raw().getHeight());
33463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	width = de::max(width, depthBuf.raw().getHeight());
33473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	width = de::max(width, stencilBuf.raw().getHeight());
33483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	height = de::max(height, colorBuf0.raw().getDepth());
33503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	height = de::max(height, depthBuf.raw().getDepth());
33513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	height = de::max(height, stencilBuf.raw().getDepth());
33523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	invalidateSubFramebuffer(target, numAttachments, attachments, 0, 0, width, height);
33543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clear (deUint32 buffers)
33573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((buffers & ~(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) != 0, GL_INVALID_VALUE, RC_RET_VOID);
33593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisamplePixelBufferAccess	colorBuf0	= getDrawColorbuffer();
33613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisamplePixelBufferAccess	depthBuf	= getDrawDepthbuffer();
33623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisamplePixelBufferAccess	stencilBuf	= getDrawStencilbuffer();
33633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec4								baseArea	= m_scissorEnabled ? m_scissorBox : IVec4(0, 0, 0x7fffffff, 0x7fffffff);
3364eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi	IVec4								colorArea	= intersect(baseArea, getBufferRect(colorBuf0));
3365eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi	IVec4								depthArea	= intersect(baseArea, getBufferRect(depthBuf));
3366eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi	IVec4								stencilArea	= intersect(baseArea, getBufferRect(stencilBuf));
3367eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi	bool								hasColor0	= !isEmpty(colorArea);
3368eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi	bool								hasDepth	= !isEmpty(depthArea);
3369eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi	bool								hasStencil	= !isEmpty(stencilArea);
33703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasColor0 && (buffers & GL_COLOR_BUFFER_BIT) != 0)
33723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(colorBuf0, colorArea.x(), colorArea.y(), colorArea.z(), colorArea.w());
337489a729134d6a1880d2b59426dfe14d615381e314Jarkko Pöyry		bool								isSRGB		= tcu::isSRGB(colorBuf0.raw().getFormat());
33753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4								c			= (isSRGB && m_sRGBUpdateEnabled) ? tcu::linearToSRGB(m_clearColor) : m_clearColor;
33763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskUsed	= !m_colorMask[0] || !m_colorMask[1] || !m_colorMask[2] || !m_colorMask[3];
33773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskZero	= !m_colorMask[0] && !m_colorMask[1] && !m_colorMask[2] && !m_colorMask[3];
33783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!maskUsed)
33803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::clear(access, c);
33813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (!maskZero)
33823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
33833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < access.raw().getDepth(); y++)
33843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int x = 0; x < access.raw().getHeight(); x++)
33853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int s = 0; s < access.getNumSamples(); s++)
33863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						access.raw().setPixel(tcu::select(c, access.raw().getPixel(s, x, y), m_colorMask), s, x, y);
33873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
33883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// else all channels masked out
33893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasDepth && (buffers & GL_DEPTH_BUFFER_BIT) != 0 && m_depthMask)
33923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3393b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry		rr::MultisamplePixelBufferAccess access = getDepthMultisampleAccess(rr::getSubregion(depthBuf, depthArea.x(), depthArea.y(), depthArea.z(), depthArea.w()));
3394b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry		rr::clearDepth(access, m_clearDepth);
33953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasStencil && (buffers & GL_STENCIL_BUFFER_BIT) != 0)
33983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3399b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry		rr::MultisamplePixelBufferAccess	access					= getStencilMultisampleAccess(rr::getSubregion(stencilBuf, stencilArea.x(), stencilArea.y(), stencilArea.z(), stencilArea.w()));
34003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int									stencilBits				= getNumStencilBits(stencilBuf.raw().getFormat());
34013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int									stencil					= maskStencil(stencilBits, m_clearStencil);
34023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3403b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry		if ((m_stencil[rr::FACETYPE_FRONT].writeMask & ((1u<<stencilBits)-1u)) != ((1u<<stencilBits)-1u))
34043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
34053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Slow path where depth or stencil is masked out in write.
34063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < access.raw().getDepth(); y++)
34073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int x = 0; x < access.raw().getHeight(); x++)
34083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int s = 0; s < access.getNumSamples(); s++)
3409b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry						writeMaskedStencil(access, s, x, y, stencil, m_stencil[rr::FACETYPE_FRONT].writeMask);
34103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
34113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
3412b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry			rr::clearStencil(access, stencil);
34133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
34143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clearBufferiv (deUint32 buffer, int drawbuffer, const int* value)
34173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(buffer != GL_COLOR && buffer != GL_STENCIL, GL_INVALID_ENUM, RC_RET_VOID);
34193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(drawbuffer != 0, GL_INVALID_VALUE, RC_RET_VOID); // \todo [2012-04-06 pyry] MRT support.
34203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec4 baseArea = m_scissorEnabled ? m_scissorBox : IVec4(0, 0, 0x7fffffff, 0x7fffffff);
34223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (buffer == GL_COLOR)
34243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
34253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess	colorBuf	= getDrawColorbuffer();
34263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskUsed	= !m_colorMask[0] || !m_colorMask[1] || !m_colorMask[2] || !m_colorMask[3];
34273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskZero	= !m_colorMask[0] && !m_colorMask[1] && !m_colorMask[2] && !m_colorMask[3];
3428eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi		IVec4								area		= intersect(baseArea, getBufferRect(colorBuf));
34293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3430eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi		if (!isEmpty(area) && !maskZero)
34313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
34323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(colorBuf, area.x(), area.y(), area.z(), area.w());
34333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			IVec4								color		(value[0], value[1], value[2], value[3]);
34343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!maskUsed)
34363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::clear(access, color);
34373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
34383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
34393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int y = 0; y < access.raw().getDepth(); y++)
34403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int x = 0; x < access.raw().getHeight(); x++)
34413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int s = 0; s < access.getNumSamples(); s++)
34423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							access.raw().setPixel(tcu::select(color, access.raw().getPixelInt(s, x, y), m_colorMask), s, x, y);
34433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
34443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
34453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
34463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
34473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
34483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_INTERNAL(buffer == GL_STENCIL);
34493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3450eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi		rr::MultisamplePixelBufferAccess	stencilBuf	= getDrawStencilbuffer();
3451eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi		IVec4								area		= intersect(baseArea, getBufferRect(stencilBuf));
34523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3453eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi		if (!isEmpty(area) && m_stencil[rr::FACETYPE_FRONT].writeMask != 0)
34543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3455b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry			rr::MultisamplePixelBufferAccess	access		= getStencilMultisampleAccess(rr::getSubregion(stencilBuf, area.x(), area.y(), area.z(), area.w()));
34563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int									stencil		= value[0];
34573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < access.raw().getDepth(); y++)
34593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int x = 0; x < access.raw().getHeight(); x++)
34603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int s = 0; s < access.getNumSamples(); s++)
3461b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry						writeMaskedStencil(access, s, x, y, stencil, m_stencil[rr::FACETYPE_FRONT].writeMask);
34623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
34633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
34643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clearBufferfv (deUint32 buffer, int drawbuffer, const float* value)
34673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(buffer != GL_COLOR && buffer != GL_DEPTH, GL_INVALID_ENUM, RC_RET_VOID);
34693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(drawbuffer != 0, GL_INVALID_VALUE, RC_RET_VOID); // \todo [2012-04-06 pyry] MRT support.
34703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec4 baseArea = m_scissorEnabled ? m_scissorBox : IVec4(0, 0, 0x7fffffff, 0x7fffffff);
34723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (buffer == GL_COLOR)
34743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
34753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess	colorBuf	= getDrawColorbuffer();
34763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskUsed	= !m_colorMask[0] || !m_colorMask[1] || !m_colorMask[2] || !m_colorMask[3];
34773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskZero	= !m_colorMask[0] && !m_colorMask[1] && !m_colorMask[2] && !m_colorMask[3];
3478eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi		IVec4								area		= intersect(baseArea, getBufferRect(colorBuf));
34793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3480eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi		if (!isEmpty(area) && !maskZero)
34813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
34823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(colorBuf, area.x(), area.y(), area.z(), area.w());
34833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4								color		(value[0], value[1], value[2], value[3]);
34843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
348589a729134d6a1880d2b59426dfe14d615381e314Jarkko Pöyry			if (m_sRGBUpdateEnabled && tcu::isSRGB(access.raw().getFormat()))
34863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				color = tcu::linearToSRGB(color);
34873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!maskUsed)
34893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::clear(access, color);
34903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
34913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
34923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int y = 0; y < access.raw().getDepth(); y++)
34933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int x = 0; x < access.raw().getHeight(); x++)
34943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int s = 0; s < access.getNumSamples(); s++)
34953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							access.raw().setPixel(tcu::select(color, access.raw().getPixel(s, x, y), m_colorMask), s, x, y);
34963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
34973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
34983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
34993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
35003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
35013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_INTERNAL(buffer == GL_DEPTH);
35023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3503eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi		rr::MultisamplePixelBufferAccess	depthBuf	= getDrawDepthbuffer();
3504eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi		IVec4								area		= intersect(baseArea, getBufferRect(depthBuf));
35053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3506eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi		if (!isEmpty(area) && m_depthMask)
35073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
35083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(depthBuf, area.x(), area.y(), area.z(), area.w());
35093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float								depth		= value[0];
35103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3511b635ce20ea1e5305fe69095f0741916f66f182aeJarkko Pöyry			rr::clearDepth(access, depth);
35123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
35133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
35143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clearBufferuiv (deUint32 buffer, int drawbuffer, const deUint32* value)
35173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(buffer != GL_COLOR, GL_INVALID_ENUM, RC_RET_VOID);
35193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(drawbuffer != 0, GL_INVALID_VALUE, RC_RET_VOID); // \todo [2012-04-06 pyry] MRT support.
35203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec4 baseArea = m_scissorEnabled ? m_scissorBox : IVec4(0, 0, 0x7fffffff, 0x7fffffff);
35223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_INTERNAL(buffer == GL_COLOR);
35243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
35253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess	colorBuf	= getDrawColorbuffer();
35263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskUsed	= !m_colorMask[0] || !m_colorMask[1] || !m_colorMask[2] || !m_colorMask[3];
35273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskZero	= !m_colorMask[0] && !m_colorMask[1] && !m_colorMask[2] && !m_colorMask[3];
3528eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi		IVec4								area		= intersect(baseArea, getBufferRect(colorBuf));
35293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3530eeb48fcdd86d0f712cae3b5e0792f4d957fbebf4Mika Isojärvi		if (!isEmpty(area) && !maskZero)
35313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
35323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(colorBuf, area.x(), area.y(), area.z(), area.w());
35333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::UVec4							color		(value[0], value[1], value[2], value[3]);
35343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!maskUsed)
35363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::clear(access, color.asInt());
35373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
35383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
35393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int y = 0; y < access.raw().getDepth(); y++)
35403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int x = 0; x < access.raw().getHeight(); x++)
35413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int s = 0; s < access.getNumSamples(); s++)
35423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							access.raw().setPixel(tcu::select(color, access.raw().getPixelUint(s, x, y), m_colorMask), s, x, y);
35433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
35443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
35453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
35463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clearBufferfi (deUint32 buffer, int drawbuffer, float depth, int stencil)
35493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(buffer != GL_DEPTH_STENCIL, GL_INVALID_ENUM, RC_RET_VOID);
35513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clearBufferfv(GL_DEPTH, drawbuffer, &depth);
35523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clearBufferiv(GL_STENCIL, drawbuffer, &stencil);
35533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::bindVertexArray (deUint32 array)
35563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::VertexArray* vertexArrayObject = DE_NULL;
35583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (array != 0)
35603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
35613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexArrayObject = m_vertexArrays.find(array);
35623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!vertexArrayObject)
35633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
35643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vertexArrayObject = new rc::VertexArray(array, m_limits.maxVertexAttribs);
35653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_vertexArrays.insert(vertexArrayObject);
35663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
35673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
35683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create new references
35703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (vertexArrayObject)
35713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_vertexArrays.acquireReference(vertexArrayObject);
35723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Remove old references
35743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_vertexArrayBinding)
35753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_vertexArrays.releaseReference(m_vertexArrayBinding);
35763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertexArrayBinding = vertexArrayObject;
35783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::genVertexArrays (int numArrays, deUint32* vertexArrays)
35813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!vertexArrays, GL_INVALID_VALUE, RC_RET_VOID);
35833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < numArrays; ndx++)
35853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexArrays[ndx] = m_vertexArrays.allocateName();
35863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteVertexArrays (int numArrays, const deUint32* vertexArrays)
35893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numArrays; i++)
35913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
35923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		name		= vertexArrays[i];
35933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VertexArray*	vertexArray	= name ? m_vertexArrays.find(name) : DE_NULL;
35943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vertexArray)
35963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deleteVertexArray(vertexArray);
35973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
35983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttribPointer (deUint32 index, int rawSize, deUint32 type, deBool normalized, int stride, const void *pointer)
36013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool allowBGRA	= !glu::isContextTypeES(getType());
36033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int effectiveSize	= (allowBGRA && rawSize == GL_BGRA) ? (4) : (rawSize);
36043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
36063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(effectiveSize <= 0 || effectiveSize > 4, GL_INVALID_VALUE, RC_RET_VOID);
36073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(type != GL_BYTE					&&	type != GL_UNSIGNED_BYTE	&&
36083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_SHORT				&&	type != GL_UNSIGNED_SHORT	&&
36093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_INT					&&	type != GL_UNSIGNED_INT		&&
36103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_FIXED				&&	type != GL_DOUBLE			&&
36113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_FLOAT				&&	type != GL_HALF_FLOAT		&&
36123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_INT_2_10_10_10_REV	&&	type != GL_UNSIGNED_INT_2_10_10_10_REV, GL_INVALID_ENUM, RC_RET_VOID);
36133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(normalized != GL_TRUE && normalized != GL_FALSE, GL_INVALID_ENUM, RC_RET_VOID);
36143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(stride < 0, GL_INVALID_VALUE, RC_RET_VOID);
36153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	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);
36163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(m_vertexArrayBinding != DE_NULL && m_arrayBufferBinding == DE_NULL && pointer != DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
36173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	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);
36183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(allowBGRA && rawSize == GL_BGRA && normalized == GL_FALSE, GL_INVALID_OPERATION, RC_RET_VOID);
36193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
36213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].size			= rawSize;
36233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].stride			= stride;
36243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].type			= type;
36253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].normalized		= normalized == GL_TRUE;
36263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].integer			= false;
36273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].pointer			= pointer;
36283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// acquire new reference
36303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_arrayBufferBinding)
36313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffers.acquireReference(m_arrayBufferBinding);
36323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// release old reference
36343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (vao.m_arrays[index].bufferBinding)
36353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffers.releaseReference(vao.m_arrays[index].bufferBinding);
36363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].bufferDeleted	= false;
36383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].bufferBinding	= m_arrayBufferBinding;
36393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttribIPointer (deUint32 index, int size, deUint32 type, int stride, const void *pointer)
36423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
36443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(size <= 0 || size > 4, GL_INVALID_VALUE, RC_RET_VOID);
36453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(type != GL_BYTE					&&	type != GL_UNSIGNED_BYTE	&&
36463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_SHORT				&&	type != GL_UNSIGNED_SHORT	&&
36473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_INT					&&	type != GL_UNSIGNED_INT, GL_INVALID_ENUM, RC_RET_VOID);
36483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(stride < 0, GL_INVALID_VALUE, RC_RET_VOID);
36493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(m_vertexArrayBinding != DE_NULL && m_arrayBufferBinding == DE_NULL && pointer != DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
36503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
36523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].size			= size;
36543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].stride			= stride;
36553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].type			= type;
36563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].normalized		= false;
36573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].integer			= true;
36583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].pointer			= pointer;
36593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// acquire new reference
36613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_arrayBufferBinding)
36623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffers.acquireReference(m_arrayBufferBinding);
36633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// release old reference
36653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (vao.m_arrays[index].bufferBinding)
36663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffers.releaseReference(vao.m_arrays[index].bufferBinding);
36673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].bufferDeleted	= false;
36693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].bufferBinding	= m_arrayBufferBinding;
36703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::enableVertexAttribArray (deUint32 index)
36733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
36753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
36773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].enabled = true;
36783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::disableVertexAttribArray (deUint32 index)
36813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
36833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
36853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].enabled = false;
36863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttribDivisor (deUint32 index, deUint32 divisor)
36893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
36913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
36933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].divisor = divisor;
36943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttrib1f (deUint32 index, float x)
36973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
36993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentAttribs[index] = rr::GenericVec4(tcu::Vec4(x, 0, 0, 1));
37013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttrib2f (deUint32 index, float x, float y)
37043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
37063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentAttribs[index] = rr::GenericVec4(tcu::Vec4(x, y, 0, 1));
37083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttrib3f (deUint32 index, float x, float y, float z)
37113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
37133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentAttribs[index] = rr::GenericVec4(tcu::Vec4(x, y, z, 1));
37153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttrib4f (deUint32 index, float x, float y, float z, float w)
37183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
37203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentAttribs[index] = rr::GenericVec4(tcu::Vec4(x, y, z, w));
37223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttribI4i (deUint32 index, deInt32 x, deInt32 y, deInt32 z, deInt32 w)
37253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
37273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentAttribs[index] = rr::GenericVec4(tcu::IVec4(x, y, z, w));
37293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttribI4ui (deUint32 index, deUint32 x, deUint32 y, deUint32 z, deUint32 w)
37323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
37343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentAttribs[index] = rr::GenericVec4(tcu::UVec4(x, y, z, w));
37363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37383c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeInt32 ReferenceContext::getAttribLocation (deUint32 program, const char *name)
37393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderProgramObjectContainer* shaderProg = m_programs.find(program);
37413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(shaderProg == DE_NULL, GL_INVALID_OPERATION, -1);
37433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (name)
37453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
37463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::string nameString(name);
37473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (size_t ndx = 0; ndx < shaderProg->m_program->m_attributeNames.size(); ++ndx)
37493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (shaderProg->m_program->m_attributeNames[ndx] == nameString)
37503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return (int)ndx;
37513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
37523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return -1;
37543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniformv (deInt32 location, glu::DataType type, deInt32 count, const void* v)
37573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(m_currentProgram == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
37593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<sglr::UniformSlot>& uniforms = m_currentProgram->m_program->m_uniforms;
37613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (location == -1)
37633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
37643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(location < 0 || (size_t)location >= uniforms.size(), GL_INVALID_OPERATION, RC_RET_VOID);
37663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(uniforms[location].type != type, GL_INVALID_OPERATION, RC_RET_VOID);
37673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(count != 1, GL_INVALID_OPERATION, RC_RET_VOID); // \todo [2013-12-13 pyry] Array uniforms.
37683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
37703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int scalarSize = glu::getDataTypeScalarSize(type);
37713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(scalarSize*sizeof(deUint32) <= sizeof(uniforms[location].value));
37723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMemcpy(&uniforms[location].value, v, scalarSize*(int)sizeof(deUint32));
37733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
37743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform1iv (deInt32 location, deInt32 count, const deInt32* v)
37773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(m_currentProgram == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
37793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<sglr::UniformSlot>& uniforms = m_currentProgram->m_program->m_uniforms;
37813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (location == -1)
37833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
37843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(location < 0 || (size_t)location >= uniforms.size(), GL_INVALID_OPERATION, RC_RET_VOID);
37863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(count != 1, GL_INVALID_OPERATION, RC_RET_VOID); // \todo [2013-12-13 pyry] Array uniforms.
37873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (uniforms[location].type)
37893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
37903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT:		uniforms[location].value.i = *v;	return;
37913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note texture unit is stored to value
37933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D:
37943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_2D:
37953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_2D:
37963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_CUBE:
37973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_CUBE:
37983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_CUBE:
37993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D_ARRAY:
38003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
38013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_2D_ARRAY:
38023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_3D:
38033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_3D:
38043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_3D:
38058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		case glu::TYPE_SAMPLER_CUBE_ARRAY:
38068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_CUBE_ARRAY:
38078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		case glu::TYPE_INT_SAMPLER_CUBE_ARRAY:
38083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			uniforms[location].value.i = *v;
38093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
38103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
38123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_OPERATION);
38133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
38143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
38153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform1f (deInt32 location, const float v0)
38183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniform1fv(location, 1, &v0);
38203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform1i (deInt32 location, deInt32 v0)
38233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniform1iv(location, 1, &v0);
38253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform1fv (deInt32 location, deInt32 count, const float* v)
38283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniformv(location, glu::TYPE_FLOAT, count, v);
38303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform2fv (deInt32 location, deInt32 count, const float* v)
38333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniformv(location, glu::TYPE_FLOAT_VEC2, count, v);
38353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform3fv (deInt32 location, deInt32 count, const float* v)
38383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniformv(location, glu::TYPE_FLOAT_VEC3, count, v);
38403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform4fv (deInt32 location, deInt32 count, const float* v)
38433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniformv(location, glu::TYPE_FLOAT_VEC4, count, v);
38453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform2iv (deInt32 location, deInt32 count, const deInt32* v)
38483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniformv(location, glu::TYPE_INT_VEC2, count, v);
38503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform3iv (deInt32 location, deInt32 count, const deInt32* v)
38533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniformv(location, glu::TYPE_INT_VEC3, count, v);
38553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform4iv (deInt32 location, deInt32 count, const deInt32* v)
38583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniformv(location, glu::TYPE_INT_VEC4, count, v);
38603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3862b0a384bf9b6816d4e3e594b37955d220d66ac7d1Jarkko Pöyryvoid ReferenceContext::uniformMatrix3fv (deInt32 location, deInt32 count, deBool transpose, const float *value)
38633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(m_currentProgram == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
38653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<sglr::UniformSlot>& uniforms = m_currentProgram->m_program->m_uniforms;
38673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (location == -1)
38693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
38703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(location < 0 || (size_t)location >= uniforms.size(), GL_INVALID_OPERATION, RC_RET_VOID);
38723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (count == 0)
38743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
38753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(transpose != GL_TRUE && transpose != GL_FALSE, GL_INVALID_ENUM, RC_RET_VOID);
38773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (uniforms[location].type)
38793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
38803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_FLOAT_MAT3:
38813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(count > 1, GL_INVALID_OPERATION, RC_RET_VOID);
38823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (transpose == GL_FALSE) // input is column major => transpose from column major to internal row major
38843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int row = 0; row < 3; ++row)
38853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int col = 0; col < 3; ++col)
38863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					uniforms[location].value.m3[row*3+col] = value[col*3+row];
38873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else // input is row major
38883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int row = 0; row < 3; ++row)
38893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int col = 0; col < 3; ++col)
38903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					uniforms[location].value.m3[row*3+col] = value[row*3+col];
38913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
38933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
38953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_OPERATION);
38963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
38973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
38983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3900b0a384bf9b6816d4e3e594b37955d220d66ac7d1Jarkko Pöyryvoid ReferenceContext::uniformMatrix4fv (deInt32 location, deInt32 count, deBool transpose, const float *value)
39013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
39023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(m_currentProgram == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
39033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<sglr::UniformSlot>& uniforms = m_currentProgram->m_program->m_uniforms;
39053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (location == -1)
39073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
39083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(location < 0 || (size_t)location >= uniforms.size(), GL_INVALID_OPERATION, RC_RET_VOID);
39103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (count == 0)
39123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
39133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(transpose != GL_TRUE && transpose != GL_FALSE, GL_INVALID_ENUM, RC_RET_VOID);
39153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (uniforms[location].type)
39173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
39183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_FLOAT_MAT4:
39193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(count > 1, GL_INVALID_OPERATION, RC_RET_VOID);
39203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (transpose == GL_FALSE) // input is column major => transpose from column major to internal row major
39223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int row = 0; row < 4; ++row)
39233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int col = 0; col < 4; ++col)
39243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					uniforms[location].value.m4[row*3+col] = value[col*3+row];
39253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else // input is row major
39263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int row = 0; row < 4; ++row)
39273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int col = 0; col < 4; ++col)
39283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					uniforms[location].value.m4[row*3+col] = value[row*3+col];
39293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
39313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
39333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_OPERATION);
39343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
39353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
39363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
39373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39383c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeInt32 ReferenceContext::getUniformLocation (deUint32 program, const char *name)
39393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
39403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderProgramObjectContainer* shaderProg = m_programs.find(program);
39413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(shaderProg == DE_NULL, GL_INVALID_OPERATION, -1);
39423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<sglr::UniformSlot>& uniforms = shaderProg->m_program->m_uniforms;
39443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t i = 0; i < uniforms.size(); ++i)
39463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (name && deStringEqual(uniforms[i].name.c_str(), name))
39473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (int)i;
39483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return -1;
39503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
39513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::lineWidth (float w)
39533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
39543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(w < 0.0f, GL_INVALID_VALUE, RC_RET_VOID);
39553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_lineWidth = w;
39563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
39573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteVertexArray (rc::VertexArray* vertexArray)
39593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
39603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_vertexArrayBinding == vertexArray)
39613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bindVertexArray(0);
39623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (vertexArray->m_elementArrayBufferBinding)
39643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffers.releaseReference(vertexArray->m_elementArrayBufferBinding);
39653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t ndx = 0; ndx < vertexArray->m_arrays.size(); ++ndx)
39673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vertexArray->m_arrays[ndx].bufferBinding)
39683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_buffers.releaseReference(vertexArray->m_arrays[ndx].bufferBinding);
39693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(vertexArray->getRefCount() == 1);
39713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertexArrays.releaseReference(vertexArray);
39723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
39733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteProgramObject (rc::ShaderProgramObjectContainer* sp)
39753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
39763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Unbinding program will delete it
39773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentProgram == sp && sp->m_deleteFlag)
39783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
39793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		useProgram(0);
39803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
39813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
39823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Unbinding program will NOT delete it
39843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentProgram == sp)
39853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		useProgram(0);
39863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sp->getRefCount() == 1);
39883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_programs.releaseReference(sp);
39893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
39903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawArrays (deUint32 mode, int first, int count)
39923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
39933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawArraysInstanced(mode, first, count, 1);
39943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
39953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawArraysInstanced (deUint32 mode, int first, int count, int instanceCount)
39973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
39983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Error conditions
39993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
40003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(first < 0 || count < 0 || instanceCount < 0, GL_INVALID_VALUE, RC_RET_VOID);
40013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!predrawErrorChecks(mode))
40033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
40043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
40053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// All is ok
40073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
40083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const rr::PrimitiveType primitiveType = sglr::rr_util::mapGLPrimitiveType(mode);
40093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawWithReference(rr::PrimitiveList(primitiveType, count, first), instanceCount);
40113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
40123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawElements (deUint32 mode, int count, deUint32 type, const void *indices)
40153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawElementsInstanced(mode, count, type, indices, 1);
40173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawElementsBaseVertex (deUint32 mode, int count, deUint32 type, const void *indices, int baseVertex)
40203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawElementsInstancedBaseVertex(mode, count, type, indices, 1, baseVertex);
40223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40243c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawElementsInstanced (deUint32 mode, int count, deUint32 type, const void *indices, int instanceCount)
40253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawElementsInstancedBaseVertex(mode, count, type, indices, instanceCount, 0);
40273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40293c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawElementsInstancedBaseVertex (deUint32 mode, int count, deUint32 type, const void *indices, int instanceCount, int baseVertex)
40303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
40323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Error conditions
40343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
40353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(type != GL_UNSIGNED_BYTE &&
40363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					type != GL_UNSIGNED_SHORT &&
40373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					type != GL_UNSIGNED_INT, GL_INVALID_ENUM, RC_RET_VOID);
40383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(count < 0 || instanceCount < 0, GL_INVALID_VALUE, RC_RET_VOID);
40393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!predrawErrorChecks(mode))
40413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
40423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
40433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// All is ok
40453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
40463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const rr::PrimitiveType primitiveType	= sglr::rr_util::mapGLPrimitiveType(mode);
40473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const void*				indicesPtr		= (vao.m_elementArrayBufferBinding) ? (vao.m_elementArrayBufferBinding->getData() + ((const deUint8*)indices - (const deUint8*)DE_NULL)) : (indices);
40483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawWithReference(rr::PrimitiveList(primitiveType, count, rr::DrawIndices(indicesPtr, sglr::rr_util::mapGLIndexType(type), baseVertex)), instanceCount);
40503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
40513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawRangeElements (deUint32 mode, deUint32 start, deUint32 end, int count, deUint32 type, const void *indices)
40543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(end < start, GL_INVALID_VALUE, RC_RET_VOID);
40563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawElements(mode, count, type, indices);
40583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawRangeElementsBaseVertex (deUint32 mode, deUint32 start, deUint32 end, int count, deUint32 type, const void *indices, int baseVertex)
40613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(end < start, GL_INVALID_VALUE, RC_RET_VOID);
40633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawElementsBaseVertex(mode, count, type, indices, baseVertex);
40653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawArraysIndirect (deUint32 mode, const void *indirect)
40683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct DrawArraysIndirectCommand
40703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
40713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 count;
40723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 primCount;
40733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 first;
40743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 reservedMustBeZero;
40753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
40763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const DrawArraysIndirectCommand* command;
40783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check errors
40803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!predrawErrorChecks(mode))
40823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
40833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check pointer validity
40853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(m_drawIndirectBufferBinding == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
40873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!deIsAlignedPtr(indirect, 4), GL_INVALID_OPERATION, RC_RET_VOID);
40883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note watch for overflows, indirect might be close to 0xFFFFFFFF and indirect+something might overflow
40903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((size_t)((const char*)indirect - (const char*)DE_NULL)                                     > (size_t)m_drawIndirectBufferBinding->getSize(), GL_INVALID_OPERATION, RC_RET_VOID);
40913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((size_t)((const char*)indirect - (const char*)DE_NULL) + sizeof(DrawArraysIndirectCommand) > (size_t)m_drawIndirectBufferBinding->getSize(), GL_INVALID_OPERATION, RC_RET_VOID);
40923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check values
40943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	command = (const DrawArraysIndirectCommand*)(m_drawIndirectBufferBinding->getData() + ((const char*)indirect - (const char*)DE_NULL));
40963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(command->reservedMustBeZero != 0, GL_INVALID_OPERATION, RC_RET_VOID);
40973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// draw
40993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawArraysInstanced(mode, command->first, command->count, command->primCount);
41003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
41013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawElementsIndirect	(deUint32 mode, deUint32 type, const void *indirect)
41033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
41043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct DrawElementsIndirectCommand
41053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
41063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 count;
41073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 primCount;
41083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 firstIndex;
41093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt32  baseVertex;
41103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 reservedMustBeZero;
41113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
41123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const DrawElementsIndirectCommand* command;
41143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check errors
41163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!predrawErrorChecks(mode))
41183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
41193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(type != GL_UNSIGNED_BYTE &&
41213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_UNSIGNED_SHORT &&
41223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_UNSIGNED_INT, GL_INVALID_ENUM, RC_RET_VOID);
41233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!getBufferBinding(GL_ELEMENT_ARRAY_BUFFER), GL_INVALID_OPERATION, RC_RET_VOID);
41253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check pointer validity
41273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(m_drawIndirectBufferBinding == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
41293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!deIsAlignedPtr(indirect, 4), GL_INVALID_OPERATION, RC_RET_VOID);
41303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note watch for overflows, indirect might be close to 0xFFFFFFFF and indirect+something might overflow
41323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((size_t)((const char*)indirect - (const char*)DE_NULL)                                       > (size_t)m_drawIndirectBufferBinding->getSize(), GL_INVALID_OPERATION, RC_RET_VOID);
41333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((size_t)((const char*)indirect - (const char*)DE_NULL) + sizeof(DrawElementsIndirectCommand) > (size_t)m_drawIndirectBufferBinding->getSize(), GL_INVALID_OPERATION, RC_RET_VOID);
41343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check values
41363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	command = (const DrawElementsIndirectCommand*)(m_drawIndirectBufferBinding->getData() + ((const char*)indirect - (const char*)DE_NULL));
41383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(command->reservedMustBeZero != 0, GL_INVALID_OPERATION, RC_RET_VOID);
41393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check command error conditions
41413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((int)command->count < 0 || (int)command->primCount < 0, GL_INVALID_VALUE, RC_RET_VOID);
41423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw
41443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
41453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const size_t			sizeOfType		= (type == GL_UNSIGNED_BYTE) ?  (1) : ((type == GL_UNSIGNED_SHORT) ? (2) : (4));
41463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const void*				indicesPtr		= (deUint8*)DE_NULL + (command->firstIndex * sizeOfType);
41473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawElementsInstancedBaseVertex(mode, (int)command->count, type, indicesPtr, (int)command->primCount, command->baseVertex);
41493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
41503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
41513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::multiDrawArrays (deUint32 mode, const int* first, const int* count, int primCount)
41533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
41543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(mode);
41553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(first);
41563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(count);
41573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(primCount);
41583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// not supported in gles, prevent accidental use
41603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
41613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
41623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::multiDrawElements (deUint32 mode, const int* count, deUint32 type, const void** indices, int primCount)
41643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
41653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(mode);
41663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(count);
41673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(type);
41683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(indices);
41693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(primCount);
41703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// not supported in gles, prevent accidental use
41723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
41733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
41743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::multiDrawElementsBaseVertex (deUint32 mode, const int* count, deUint32 type, const void** indices, int primCount, const int* baseVertex)
41763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
41773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(mode);
41783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(count);
41793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(type);
41803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(indices);
41813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(primCount);
41823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(baseVertex);
41833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// not supported in gles, prevent accidental use
41853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
41863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
41873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ReferenceContext::predrawErrorChecks (deUint32 mode)
41893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
41903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(mode != GL_POINTS &&
41913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				mode != GL_LINE_STRIP && mode != GL_LINE_LOOP && mode != GL_LINES &&
41923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				mode != GL_TRIANGLE_STRIP && mode != GL_TRIANGLE_FAN && mode != GL_TRIANGLES &&
41933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				mode != GL_LINES_ADJACENCY && mode != GL_LINE_STRIP_ADJACENCY &&
41943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				mode != GL_TRIANGLES_ADJACENCY && mode != GL_TRIANGLE_STRIP_ADJACENCY,
41953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_INVALID_ENUM, false);
41963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [jarkko] Uncomment following code when the buffer mapping support is added
41983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//for (size_t ndx = 0; ndx < vao.m_arrays.size(); ++ndx)
41993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//	if (vao.m_arrays[ndx].enabled && vao.m_arrays[ndx].bufferBinding && vao.m_arrays[ndx].bufferBinding->isMapped)
42003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		RC_ERROR_RET(GL_INVALID_OPERATION, RC_RET_VOID);
42013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION, false);
42033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Geometry shader checks
42053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentProgram && m_currentProgram->m_program->m_hasGeometryShader)
42063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
42073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(m_currentProgram->m_program->rr::GeometryShader::getInputType() == rr::GEOMETRYSHADERINPUTTYPE_POINTS && mode != GL_POINTS, GL_INVALID_OPERATION, false);
42083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(m_currentProgram->m_program->rr::GeometryShader::getInputType() == rr::GEOMETRYSHADERINPUTTYPE_LINES &&
42103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(mode != GL_LINES &&
42113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 mode != GL_LINE_STRIP &&
42123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 mode != GL_LINE_LOOP),
42133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 GL_INVALID_OPERATION, false);
42143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(m_currentProgram->m_program->rr::GeometryShader::getInputType() == rr::GEOMETRYSHADERINPUTTYPE_TRIANGLES &&
42163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(mode != GL_TRIANGLES &&
42173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 mode != GL_TRIANGLE_STRIP &&
42183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 mode != GL_TRIANGLE_FAN),
42193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 GL_INVALID_OPERATION, false);
42203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(m_currentProgram->m_program->rr::GeometryShader::getInputType() == rr::GEOMETRYSHADERINPUTTYPE_LINES_ADJACENCY &&
42223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(mode != GL_LINES_ADJACENCY &&
42233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 mode != GL_LINE_STRIP_ADJACENCY),
42243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 GL_INVALID_OPERATION, false);
42253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(m_currentProgram->m_program->rr::GeometryShader::getInputType() == rr::GEOMETRYSHADERINPUTTYPE_TRIANGLES_ADJACENCY &&
42273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(mode != GL_TRIANGLES_ADJACENCY &&
42283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 mode != GL_TRIANGLE_STRIP_ADJACENCY),
42293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 GL_INVALID_OPERATION, false);
42303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
42313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
42333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
42343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic rr::PrimitiveType getPrimitiveBaseType (rr::PrimitiveType derivedType)
42363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
42373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (derivedType)
42383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
42393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_TRIANGLES:
42403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_TRIANGLE_STRIP:
42413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_TRIANGLE_FAN:
42423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY:
42433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY:
42443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return rr::PRIMITIVETYPE_TRIANGLES;
42453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_LINES:
42473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_LINE_STRIP:
42483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_LINE_LOOP:
42493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_LINES_ADJACENCY:
42503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY:
42513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return rr::PRIMITIVETYPE_LINES;
42523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_POINTS:
42543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return rr::PRIMITIVETYPE_POINTS;
42553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
42573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
42583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return rr::PRIMITIVETYPE_LAST;
42593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
42603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
42613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deUint32 getFixedRestartIndex (rr::IndexType indexType)
42633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
42643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (indexType)
42653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
42663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::INDEXTYPE_UINT8:		return 0xFF;
42673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::INDEXTYPE_UINT16:		return 0xFFFF;
42683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::INDEXTYPE_UINT32:		return 0xFFFFFFFFul;
42693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::INDEXTYPE_LAST:
42713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
42723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
42733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
42743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
42753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
42763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawWithReference (const rr::PrimitiveList& primitives, int instanceCount)
42783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
42793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// undefined results
42803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentProgram == DE_NULL)
42813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
42823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisamplePixelBufferAccess	colorBuf0	= getDrawColorbuffer();
42845a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	rr::MultisamplePixelBufferAccess	depthBuf	= getDepthMultisampleAccess(getDrawDepthbuffer());
42855a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	rr::MultisamplePixelBufferAccess	stencilBuf	= getStencilMultisampleAccess(getDrawStencilbuffer());
42863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool							hasStencil	= !isEmpty(stencilBuf);
42873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int							stencilBits	= (hasStencil) ? (getNumStencilBits(stencilBuf.raw().getFormat())) : (0);
42883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4289f0ed58441d167a6f524cc9ba2e71d220a20d8384Jarkko Pöyry	const rr::RenderTarget				renderTarget(colorBuf0, depthBuf, stencilBuf);
42903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const rr::Program					program		(m_currentProgram->m_program->getVertexShader(),
42913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 m_currentProgram->m_program->getFragmentShader(),
42923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 (m_currentProgram->m_program->m_hasGeometryShader) ? (m_currentProgram->m_program->getGeometryShader()) : (DE_NULL));
42933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::RenderState						state		((rr::ViewportState)(colorBuf0));
42943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const rr::Renderer					referenceRenderer;
42963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<rr::VertexAttrib>		vertexAttribs;
42973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Gen state
42993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
43003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const rr::PrimitiveType	baseType							= getPrimitiveBaseType(primitives.getPrimitiveType());
43013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				polygonOffsetEnabled				= (baseType == rr::PRIMITIVETYPE_TRIANGLES) ? (m_polygonOffsetFillEnabled) : (false);
43023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//state.cullMode											= m_cullMode
43043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.scissorTestEnabled							= m_scissorEnabled;
43063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.scissorRectangle								= rr::WindowRectangle(m_scissorBox.x(), m_scissorBox.y(), m_scissorBox.z(), m_scissorBox.w());
43073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.numStencilBits								= stencilBits;
43093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.stencilTestEnabled							= m_stencilTestEnabled;
43103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int faceType = 0; faceType < rr::FACETYPE_LAST; faceType++)
43123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
43133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.fragOps.stencilStates[faceType].compMask	= m_stencil[faceType].opMask;
43143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.fragOps.stencilStates[faceType].writeMask	= m_stencil[faceType].writeMask;
43153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.fragOps.stencilStates[faceType].ref		= m_stencil[faceType].ref;
43163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.fragOps.stencilStates[faceType].func		= sglr::rr_util::mapGLTestFunc(m_stencil[faceType].func);
43173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.fragOps.stencilStates[faceType].sFail		= sglr::rr_util::mapGLStencilOp(m_stencil[faceType].opStencilFail);
43183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.fragOps.stencilStates[faceType].dpFail	= sglr::rr_util::mapGLStencilOp(m_stencil[faceType].opDepthFail);
43193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.fragOps.stencilStates[faceType].dpPass	= sglr::rr_util::mapGLStencilOp(m_stencil[faceType].opDepthPass);
43203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
43213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.depthTestEnabled								= m_depthTestEnabled;
43233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.depthFunc										= sglr::rr_util::mapGLTestFunc(m_depthFunc);
43243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.depthMask										= m_depthMask;
43253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendMode										= m_blendEnabled ? rr::BLENDMODE_STANDARD : rr::BLENDMODE_NONE;
43273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendRGBState.equation						= sglr::rr_util::mapGLBlendEquation(m_blendModeRGB);
43283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendRGBState.srcFunc							= sglr::rr_util::mapGLBlendFunc(m_blendFactorSrcRGB);
43293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendRGBState.dstFunc							= sglr::rr_util::mapGLBlendFunc(m_blendFactorDstRGB);
43303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendAState.equation							= sglr::rr_util::mapGLBlendEquation(m_blendModeAlpha);
43313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendAState.srcFunc							= sglr::rr_util::mapGLBlendFunc(m_blendFactorSrcAlpha);
43323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendAState.dstFunc							= sglr::rr_util::mapGLBlendFunc(m_blendFactorDstAlpha);
43333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendColor									= m_blendColor;
43343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.sRGBEnabled									= m_sRGBUpdateEnabled;
43363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.colorMask										= m_colorMask;
43383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.depthClampEnabled								= m_depthClampEnabled;
43403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.viewport.rect											= rr::WindowRectangle(m_viewport.x(), m_viewport.y(), m_viewport.z(), m_viewport.w());
43423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.viewport.zn											= m_depthRangeNear;
43433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.viewport.zf											= m_depthRangeFar;
43443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//state.point.pointSize										= m_pointSize;
43463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.line.lineWidth										= m_lineWidth;
43473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.polygonOffsetEnabled							= polygonOffsetEnabled;
43493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.polygonOffsetFactor							= m_polygonOffsetFactor;
43503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.polygonOffsetUnits							= m_polygonOffsetUnits;
43513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
43533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const rr::IndexType indexType = primitives.getIndexType();
43543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_primitiveRestartFixedIndex && indexType != rr::INDEXTYPE_LAST)
43563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
43573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.restart.enabled = true;
43583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.restart.restartIndex = getFixedRestartIndex(indexType);
43593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
43603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (m_primitiveRestartSettableIndex)
43613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
43623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \note PRIMITIVE_RESTART is active for non-indexed (DrawArrays) operations too.
43633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.restart.enabled = true;
43643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.restart.restartIndex = m_primitiveRestartIndex;
43653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
43663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
43673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
43683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.restart.enabled = false;
43693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
43703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
43713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.provokingVertexConvention								= (m_provokingFirstVertexConvention) ? (rr::PROVOKINGVERTEX_FIRST) : (rr::PROVOKINGVERTEX_LAST);
43733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
43743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// gen attributes
43763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
43773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
43783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexAttribs.resize(vao.m_arrays.size());
43803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (size_t ndx = 0; ndx < vao.m_arrays.size(); ++ndx)
43813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
43823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!vao.m_arrays[ndx].enabled)
43833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
43843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].type = rr::VERTEXATTRIBTYPE_DONT_CARE; // reading with wrong type is allowed, but results are undefined
43853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].generic = m_currentAttribs[ndx];
43863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
43873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (vao.m_arrays[ndx].bufferDeleted)
43883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
43893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].type = rr::VERTEXATTRIBTYPE_DONT_CARE; // reading from deleted buffer, output zeros
43903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].generic = tcu::Vec4(0, 0, 0, 0);
43913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
43923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
43933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
43943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].type				= (vao.m_arrays[ndx].integer) ?
43953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														(sglr::rr_util::mapGLPureIntegerVertexAttributeType(vao.m_arrays[ndx].type)) :
43963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														(sglr::rr_util::mapGLFloatVertexAttributeType(vao.m_arrays[ndx].type, vao.m_arrays[ndx].normalized, vao.m_arrays[ndx].size, this->getType()));
43973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].size				= sglr::rr_util::mapGLSize(vao.m_arrays[ndx].size);
43983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].stride			= vao.m_arrays[ndx].stride;
43993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].instanceDivisor	= vao.m_arrays[ndx].divisor;
44003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].pointer			= (vao.m_arrays[ndx].bufferBinding) ? (vao.m_arrays[ndx].bufferBinding->getData() + ((const deUint8*)vao.m_arrays[ndx].pointer - (const deUint8*)DE_NULL)) : (vao.m_arrays[ndx].pointer);
44013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
44023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
44033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
44043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Set shader samplers
44063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t uniformNdx = 0; uniformNdx < m_currentProgram->m_program->m_uniforms.size(); ++uniformNdx)
44073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
44085a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		const tcu::Sampler::DepthStencilMode	depthStencilMode	= tcu::Sampler::MODE_DEPTH; // \todo[jarkko] support sampler state
44095a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		const int								texNdx				= m_currentProgram->m_program->m_uniforms[uniformNdx].value.i;
44103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (m_currentProgram->m_program->m_uniforms[uniformNdx].type)
44123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
44133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_SAMPLER_1D:
44143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_UINT_SAMPLER_1D:
44153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_INT_SAMPLER_1D:
44163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
44173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rc::Texture1D* tex = DE_NULL;
44183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
44203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex = (m_textureUnits[texNdx].tex1DBinding) ? (m_textureUnits[texNdx].tex1DBinding) : (&m_textureUnits[texNdx].default1DTex);
44213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex && tex->isComplete())
44233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
44245a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry					tex->updateView(depthStencilMode);
44253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex1D = tex;
44263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
44273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
44283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex1D = &m_emptyTex1D;
44293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
44313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
44323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_SAMPLER_2D:
44333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_UINT_SAMPLER_2D:
44343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_INT_SAMPLER_2D:
44353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
44363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rc::Texture2D* tex = DE_NULL;
44373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
44393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex = (m_textureUnits[texNdx].tex2DBinding) ? (m_textureUnits[texNdx].tex2DBinding) : (&m_textureUnits[texNdx].default2DTex);
44403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex && tex->isComplete())
44423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
44435a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry					tex->updateView(depthStencilMode);
44443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex2D = tex;
44453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
44463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
44473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex2D = &m_emptyTex2D;
44483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
44503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
44513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_SAMPLER_CUBE:
44523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_UINT_SAMPLER_CUBE:
44533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_INT_SAMPLER_CUBE:
44543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
44553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rc::TextureCube* tex = DE_NULL;
44563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
44583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex = (m_textureUnits[texNdx].texCubeBinding) ? (m_textureUnits[texNdx].texCubeBinding) : (&m_textureUnits[texNdx].defaultCubeTex);
44593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex && tex->isComplete())
44613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
44625a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry					tex->updateView(depthStencilMode);
44633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.texCube = tex;
44643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
44653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
44663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.texCube = &m_emptyTexCube;
44673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
44693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
44703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_SAMPLER_2D_ARRAY:
44713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
44723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_INT_SAMPLER_2D_ARRAY:
44733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
44743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rc::Texture2DArray* tex = DE_NULL;
44753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
44773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex = (m_textureUnits[texNdx].tex2DArrayBinding) ? (m_textureUnits[texNdx].tex2DArrayBinding) : (&m_textureUnits[texNdx].default2DArrayTex);
44783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex && tex->isComplete())
44803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
44815a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry					tex->updateView(depthStencilMode);
44823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex2DArray = tex;
44833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
44843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
44853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex2DArray = &m_emptyTex2DArray;
44863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
44883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
44893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_SAMPLER_3D:
44903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_UINT_SAMPLER_3D:
44913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_INT_SAMPLER_3D:
44923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
44933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rc::Texture3D* tex = DE_NULL;
44943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
44963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex = (m_textureUnits[texNdx].tex3DBinding) ? (m_textureUnits[texNdx].tex3DBinding) : (&m_textureUnits[texNdx].default3DTex);
44973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex && tex->isComplete())
44993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
45005a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry					tex->updateView(depthStencilMode);
45013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex3D = tex;
45023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
45033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
45043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex3D = &m_emptyTex3D;
45053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
45073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
45083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_SAMPLER_CUBE_ARRAY:
45093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_UINT_SAMPLER_CUBE_ARRAY:
45103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_INT_SAMPLER_CUBE_ARRAY:
45113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
45123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rc::TextureCubeArray* tex = DE_NULL;
45133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
45153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex = (m_textureUnits[texNdx].texCubeArrayBinding) ? (m_textureUnits[texNdx].texCubeArrayBinding) : (&m_textureUnits[texNdx].defaultCubeArrayTex);
45163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex && tex->isComplete())
45183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
45195a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry					tex->updateView(depthStencilMode);
45203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.texCubeArray = tex;
45213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
45223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
45233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.texCubeArray = &m_emptyTexCubeArray;
45243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
45263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
45273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
45283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// nothing
45293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
45303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
45313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
45323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	referenceRenderer.drawInstanced(rr::DrawCommand(state, renderTarget, program, (int)vertexAttribs.size(), &vertexAttribs[0], primitives), instanceCount);
45343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
45353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45363c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 ReferenceContext::createProgram (ShaderProgram* program)
45373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
45383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int name = m_programs.allocateName();
45393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_programs.insert(new rc::ShaderProgramObjectContainer(name, program));
45413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return name;
45433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
45443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::useProgram (deUint32 program)
45463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
45473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::ShaderProgramObjectContainer* shaderProg			= DE_NULL;
45483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::ShaderProgramObjectContainer* programToBeDeleted	= DE_NULL;
45493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (program)
45513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
45523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaderProg = m_programs.find(program);
45533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// shader has not been linked
45553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!shaderProg || shaderProg->m_deleteFlag)
45563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_ERROR_RET(GL_INVALID_OPERATION, RC_RET_VOID);
45573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
45583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentProgram && m_currentProgram->m_deleteFlag)
45603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		programToBeDeleted = m_currentProgram;
45613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentProgram = shaderProg;
45633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (programToBeDeleted)
45653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
45663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(programToBeDeleted->getRefCount() == 1);
45673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deleteProgramObject(programToBeDeleted);
45683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
45693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
45703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteProgram (deUint32 program)
45723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
45733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!program)
45743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
45753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::ShaderProgramObjectContainer* shaderProg = m_programs.find(program);
45773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (shaderProg)
45783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
45793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (shaderProg == m_currentProgram)
45803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
45813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_currentProgram->m_deleteFlag = true;
45823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
45833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
45843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
45853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(shaderProg->getRefCount() == 1);
45863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_programs.releaseReference(shaderProg);
45873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
45883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
45893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
45903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::readPixels (int x, int y, int width, int height, deUint32 format, deUint32 type, void* data)
45923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
45933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisamplePixelBufferAccess	src = getReadColorbuffer();
45943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat						transferFmt;
45953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map transfer format.
45973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	transferFmt = glu::mapGLTransferFormat(format, type);
45983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(transferFmt.order	== TextureFormat::CHANNELORDER_LAST ||
45993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				transferFmt.type	== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
46003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clamp input values
46023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int copyX			= deClamp32(x,		0, src.raw().getHeight());
46033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int copyY			= deClamp32(y,		0, src.raw().getDepth());
46043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int copyWidth		= deClamp32(width,	0, src.raw().getHeight()-x);
46053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int copyHeight	= deClamp32(height,	0, src.raw().getDepth()-y);
46063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	PixelBufferAccess dst(transferFmt, width, height, 1, deAlign32(width*transferFmt.getPixelSize(), m_pixelPackAlignment), 0, getPixelPackPtr(data));
46083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::resolveMultisampleColorBuffer(tcu::getSubregion(dst, 0, 0, copyWidth, copyHeight), rr::getSubregion(src, copyX, copyY, copyWidth, copyHeight));
46093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46113c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 ReferenceContext::getError (void)
46123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 err = m_lastError;
46143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_lastError = GL_NO_ERROR;
46153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return err;
46163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::finish (void)
46193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void ReferenceContext::setError (deUint32 error)
46233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_lastError == GL_NO_ERROR)
46253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_lastError = error;
46263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::getIntegerv (deUint32 pname, int* param)
46293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (pname)
46313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
46323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MAX_TEXTURE_SIZE:			*param = m_limits.maxTexture2DSize;			break;
46333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MAX_CUBE_MAP_TEXTURE_SIZE:	*param = m_limits.maxTextureCubeSize;		break;
46343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MAX_ARRAY_TEXTURE_LAYERS:	*param = m_limits.maxTexture2DArrayLayers;	break;
46353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MAX_3D_TEXTURE_SIZE:		*param = m_limits.maxTexture3DSize;			break;
46363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MAX_RENDERBUFFER_SIZE:		*param = m_limits.maxRenderbufferSize;		break;
46373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MAX_TEXTURE_IMAGE_UNITS:	*param = m_limits.maxTextureImageUnits;		break;
46383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MAX_VERTEX_ATTRIBS:			*param = m_limits.maxVertexAttribs;			break;
46393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
46413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
46423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
46433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
46443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* ReferenceContext::getString (deUint32 pname)
46473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (pname)
46493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
46503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_EXTENSIONS:		return m_limits.extensionStr.c_str();
46513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
46533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
46543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
46553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
46563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace rc
46593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelArray::TextureLevelArray (void)
46623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46653c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelArray::~TextureLevelArray (void)
46663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clear();
46683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelArray::clear (void)
46713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(m_data) == DE_LENGTH_OF_ARRAY(m_access));
46733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(m_data); ndx++)
46753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
46765e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry		m_data[ndx].clear();
46775e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry		m_access[ndx] = PixelBufferAccess();
46783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
46793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelArray::allocLevel (int level, const tcu::TextureFormat& format, int width, int height, int depth)
46823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46835e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry	const int dataSize = format.getPixelSize()*width*height*depth;
46843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46855e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry	DE_ASSERT(deInBounds32(level, 0, DE_LENGTH_OF_ARRAY(m_data)));
46863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(level))
46883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		clearLevel(level);
46893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46905e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry	m_data[level].setStorage(dataSize);
46915e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry	m_access[level] = PixelBufferAccess(format, width, height, depth, m_data[level].getPtr());
46923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelArray::clearLevel (int level)
46953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46965e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry	DE_ASSERT(deInBounds32(level, 0, DE_LENGTH_OF_ARRAY(m_data)));
46973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46985e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry	m_data[level].clear();
46995e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry	m_access[level] = PixelBufferAccess();
47003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
47013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47025a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyryvoid TextureLevelArray::updateSamplerMode (tcu::Sampler::DepthStencilMode mode)
47035a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry{
47045a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry	for (int levelNdx = 0; hasLevel(levelNdx); ++levelNdx)
47055a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		m_effectiveAccess[levelNdx] = tcu::getEffectiveDepthStencilAccess(m_access[levelNdx], mode);
47065a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry}
47075a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry
47083c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture::Texture (deUint32 name, Type type)
47093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: NamedObject	(name)
47103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_type		(type)
47113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_immutable	(false)
47123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_sampler		(tcu::Sampler::REPEAT_GL,
47133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 tcu::Sampler::REPEAT_GL,
47143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 tcu::Sampler::REPEAT_GL,
47153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 tcu::Sampler::NEAREST_MIPMAP_LINEAR,
47163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 tcu::Sampler::LINEAR,
47173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 0.0f,				// LOD threshold
47183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 true,				// normalized coords
47193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 tcu::Sampler::COMPAREMODE_NONE,
47203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 0,					// cmp channel ndx
47213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 tcu::Vec4(0.0f),	// border color
47223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 true				// seamless cube map \todo [2014-02-19 pyry] Default value ok?
47233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 )
47243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_baseLevel	(0)
47253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_maxLevel	(1000)
47263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
47273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
47283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47293c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::Texture1D (deUint32 name)
47303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: Texture	(name, TYPE_1D)
47313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view	(0, DE_NULL)
47323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
47333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
47343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::~Texture1D (void)
47363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
47373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
47383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1D::allocLevel (int level, const tcu::TextureFormat& format, int width)
47403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
47413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_levels.allocLevel(level, format, width, 1, 1);
47423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
47433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool Texture1D::isComplete (void) const
47453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
47463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	baseLevel	= getBaseLevel();
47473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel))
47493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
47503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::ConstPixelBufferAccess&	level0		= getLevel(baseLevel);
47513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool							mipmap		= isMipmapFilter(getSampler().minFilter);
47523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mipmap)
47543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
47553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const TextureFormat&	format		= level0.getFormat();
47563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				w			= level0.getWidth();
47573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLevels	= de::min(getMaxLevel()-baseLevel+1, getNumMipLevels1D(w));
47583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
47603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
47613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (hasLevel(baseLevel+levelNdx))
47623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
47633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const tcu::ConstPixelBufferAccess&	level		= getLevel(baseLevel+levelNdx);
47643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedW	= getMipLevelSize(w, levelNdx);
47653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (level.getWidth()	!= expectedW	||
47673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getFormat()	!= format)
47683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						return false;
47693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
47703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
47713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
47723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
47733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
47743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
47763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
47773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
47783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
47793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
47803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 Texture1D::sample (float s, float lod) const
47823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
47833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_view.sample(getSampler(), s, 0.0f, lod);
47843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
47853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1D::sample4 (tcu::Vec4 output[4], const float packetTexcoords[4], float lodBias) const
47873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4788b0a384bf9b6816d4e3e594b37955d220d66ac7d1Jarkko Pöyry	const float texWidth = (float)m_view.getWidth();
47893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dFdx0 = packetTexcoords[1] - packetTexcoords[0];
47913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dFdx1 = packetTexcoords[3] - packetTexcoords[2];
47923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dFdy0 = packetTexcoords[2] - packetTexcoords[0];
47933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dFdy1 = packetTexcoords[3] - packetTexcoords[1];
47943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
47963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
47973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float& dFdx = (fragNdx > 2) ? dFdx1 : dFdx0;
47983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float& dFdy = (fragNdx % 2) ? dFdy1 : dFdy0;
47993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mu = de::max(de::abs(dFdx), de::abs(dFdy));
48013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float p = mu * texWidth;
48023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lod = deFloatLog2(p) + lodBias;
48043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		output[fragNdx] = sample(packetTexcoords[fragNdx], lod);
48063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
48073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
48083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48095a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyryvoid Texture1D::updateView (tcu::Sampler::DepthStencilMode mode)
48103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
48113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int baseLevel	= getBaseLevel();
48123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel) && !isEmpty(getLevel(baseLevel)))
48143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
48153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	width		= getLevel(baseLevel).getWidth();
48163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
48173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels1D(width)) : 1;
48183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48195a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		m_levels.updateSamplerMode(mode);
48205a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		m_view = tcu::Texture2DView(numLevels, m_levels.getEffectiveLevels() + baseLevel);
48213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
48223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
48233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::Texture2DView(0, DE_NULL);
48243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
48253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48263c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::Texture2D (deUint32 name)
48273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: Texture	(name, TYPE_2D)
48283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view	(0, DE_NULL)
48293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
48303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
48313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48323c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::~Texture2D (void)
48333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
48343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
48353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2D::allocLevel (int level, const tcu::TextureFormat& format, int width, int height)
48373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
48383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_levels.allocLevel(level, format, width, height, 1);
48393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
48403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool Texture2D::isComplete (void) const
48423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
48433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	baseLevel	= getBaseLevel();
48443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel))
48463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
48473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::ConstPixelBufferAccess&	level0		= getLevel(baseLevel);
48483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool							mipmap		= isMipmapFilter(getSampler().minFilter);
48493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mipmap)
48513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
48523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const TextureFormat&	format		= level0.getFormat();
48533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				w			= level0.getWidth();
48543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				h			= level0.getHeight();
48553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLevels	= de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(w, h));
48563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
48583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
48593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (hasLevel(baseLevel+levelNdx))
48603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
48613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const tcu::ConstPixelBufferAccess&	level		= getLevel(baseLevel+levelNdx);
48623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedW	= getMipLevelSize(w, levelNdx);
48633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedH	= getMipLevelSize(h, levelNdx);
48643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (level.getWidth()	!= expectedW	||
48663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getHeight()	!= expectedH	||
48673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getFormat()	!= format)
48683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						return false;
48693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
48703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
48713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
48723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
48733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
48743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
48763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
48773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
48783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
48793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
48803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48815a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyryvoid Texture2D::updateView (tcu::Sampler::DepthStencilMode mode)
48823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
48833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int baseLevel	= getBaseLevel();
48843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel) && !isEmpty(getLevel(baseLevel)))
48863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
48873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Update number of levels in mipmap pyramid.
48883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	width		= getLevel(baseLevel).getWidth();
48893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	height		= getLevel(baseLevel).getHeight();
48903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
48913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(width, height)) : 1;
48923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48935a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		m_levels.updateSamplerMode(mode);
48945a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		m_view = tcu::Texture2DView(numLevels, m_levels.getEffectiveLevels() + baseLevel);
48953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
48963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
48973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::Texture2DView(0, DE_NULL);
48983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
48993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 Texture2D::sample (float s, float t, float lod) const
49013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
49023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_view.sample(getSampler(), s, t, lod);
49033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
49043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2D::sample4 (tcu::Vec4 output[4], const tcu::Vec2 packetTexcoords[4], float lodBias) const
49063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4907b0a384bf9b6816d4e3e594b37955d220d66ac7d1Jarkko Pöyry	const float texWidth  = (float)m_view.getWidth();
4908b0a384bf9b6816d4e3e594b37955d220d66ac7d1Jarkko Pöyry	const float texHeight = (float)m_view.getHeight();
49093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec2 dFdx0 = packetTexcoords[1] - packetTexcoords[0];
49113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec2 dFdx1 = packetTexcoords[3] - packetTexcoords[2];
49123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec2 dFdy0 = packetTexcoords[2] - packetTexcoords[0];
49133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec2 dFdy1 = packetTexcoords[3] - packetTexcoords[1];
49143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
49163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
49173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2& dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
49183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2& dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;
49193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mu = de::max(de::abs(dFdx.x()), de::abs(dFdy.x()));
49213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mv = de::max(de::abs(dFdx.y()), de::abs(dFdy.y()));
49223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float p = de::max(mu * texWidth, mv * texHeight);
49233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lod = deFloatLog2(p) + lodBias;
49253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		output[fragNdx] = sample(packetTexcoords[fragNdx].x(), packetTexcoords[fragNdx].y(), lod);
49273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
49283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
49293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49303c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::TextureCube (deUint32 name)
49313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: Texture(name, TYPE_CUBE_MAP)
49323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
49333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
49343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::~TextureCube (void)
49363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
49373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
49383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::clearLevels (void)
49403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
49413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
49423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_levels[face].clear();
49433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
49443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::allocFace (int level, tcu::CubeFace face, const tcu::TextureFormat& format, int width, int height)
49463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
49473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_levels[face].allocLevel(level, format, width, height, 1);
49483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
49493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool TextureCube::isComplete (void) const
49513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
49523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	baseLevel	= getBaseLevel();
49533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasFace(baseLevel, tcu::CUBEFACE_NEGATIVE_X))
49553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
49563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int					width		= getFace(baseLevel, tcu::CUBEFACE_NEGATIVE_X).getWidth();
49573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int					height		= getFace(baseLevel, tcu::CUBEFACE_NEGATIVE_X).getHeight();
49583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::TextureFormat&	format		= getFace(baseLevel, tcu::CUBEFACE_NEGATIVE_X).getFormat();
49593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool					mipmap		= isMipmapFilter(getSampler().minFilter);
49603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int					numLevels	= mipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(width, height)) : 1;
49613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (width != height)
49633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false; // Non-square is not supported.
49643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note Level 0 is always checked for consistency
49663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
49673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
49683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int levelW	= getMipLevelSize(width,	levelNdx);
49693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int levelH	= getMipLevelSize(height,	levelNdx);
49703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
49723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
49733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (hasFace(baseLevel+levelNdx, (tcu::CubeFace)face))
49743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
49753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const tcu::ConstPixelBufferAccess& level = getFace(baseLevel+levelNdx, (tcu::CubeFace)face);
49763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (level.getWidth()	!= levelW	||
49783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getHeight()	!= levelH	||
49793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getFormat()	!= format)
49803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						return false;
49813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
49823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
49833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
49843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
49853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
49863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
49883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
49893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
49903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
49913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
49923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49935a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyryvoid TextureCube::updateView (tcu::Sampler::DepthStencilMode mode)
49943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
49953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int							baseLevel	= getBaseLevel();
49963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::ConstPixelBufferAccess*	faces[tcu::CUBEFACE_LAST];
49973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMemset(&faces[0], 0, sizeof(faces));
49993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isComplete())
50013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
50023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	size		= getFace(baseLevel, tcu::CUBEFACE_NEGATIVE_X).getWidth();
50033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
50043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels1D(size)) : 1;
50053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
50075a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		{
50085a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			m_levels[face].updateSamplerMode(mode);
50095a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry			faces[face] = m_levels[face].getEffectiveLevels() + baseLevel;
50105a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		}
50113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::TextureCubeView(numLevels, faces);
50133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
50143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
50153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::TextureCubeView(0, faces);
50163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
50173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCube::sample (float s, float t, float p, float lod) const
50193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
50203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_view.sample(getSampler(), s, t, p, lod);
50213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
50223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::sample4 (tcu::Vec4 output[4], const tcu::Vec3 packetTexcoords[4], float lodBias) const
50243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5025b0a384bf9b6816d4e3e594b37955d220d66ac7d1Jarkko Pöyry	const float cubeSide = (float)m_view.getSize();
50263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Each tex coord might be in a different face.
50283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
50303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
50313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::CubeFace face		= tcu::selectCubeFace(packetTexcoords[fragNdx]);
50323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2		coords[4]	=
50333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
50343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, packetTexcoords[0]),
50353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, packetTexcoords[1]),
50363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, packetTexcoords[2]),
50373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, packetTexcoords[3]),
50383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
50393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdx0 = coords[1] - coords[0];
50413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdx1 = coords[3] - coords[2];
50423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdy0 = coords[2] - coords[0];
50433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdy1 = coords[3] - coords[1];
50443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2& dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
50463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2& dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;
50473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mu = de::max(de::abs(dFdx.x()), de::abs(dFdy.x()));
50493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mv = de::max(de::abs(dFdx.y()), de::abs(dFdy.y()));
50503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float p = de::max(mu * cubeSide, mv * cubeSide);
50513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lod = deFloatLog2(p) + lodBias;
50533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		output[fragNdx] = sample(packetTexcoords[fragNdx].x(), packetTexcoords[fragNdx].y(), packetTexcoords[fragNdx].z(), lod);
50553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
50563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
50573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::Texture2DArray (deUint32 name)
50593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: Texture	(name, TYPE_2D_ARRAY)
50603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view	(0, DE_NULL)
50613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
50623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
50633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50643c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::~Texture2DArray (void)
50653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
50663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
50673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DArray::allocLevel (int level, const tcu::TextureFormat& format, int width, int height, int numLayers)
50693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
50703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_levels.allocLevel(level, format, width, height, numLayers);
50713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
50723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool Texture2DArray::isComplete (void) const
50743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
50753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	baseLevel	= getBaseLevel();
50763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel))
50783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
50793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::ConstPixelBufferAccess&	level0		= getLevel(baseLevel);
50803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool							mipmap		= isMipmapFilter(getSampler().minFilter);
50813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mipmap)
50833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
50843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const TextureFormat&	format		= level0.getFormat();
50853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				w			= level0.getWidth();
50863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				h			= level0.getHeight();
50873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLayers	= level0.getDepth();
50883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLevels	= de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(w, h));
50893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
50913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
50923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (hasLevel(baseLevel+levelNdx))
50933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
50943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const tcu::ConstPixelBufferAccess&	level		= getLevel(baseLevel+levelNdx);
50953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedW	= getMipLevelSize(w, levelNdx);
50963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedH	= getMipLevelSize(h, levelNdx);
50973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (level.getWidth()	!= expectedW	||
50993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getHeight()	!= expectedH	||
51003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getDepth()	!= numLayers	||
51013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getFormat()	!= format)
51023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						return false;
51033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
51043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
51053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
51063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
51073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
51083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
51103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
51113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
51123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
51133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
51143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51155a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyryvoid Texture2DArray::updateView (tcu::Sampler::DepthStencilMode mode)
51163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
51173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int baseLevel	= getBaseLevel();
51183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel) && !isEmpty(getLevel(baseLevel)))
51203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
51213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	width		= getLevel(baseLevel).getWidth();
51223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	height		= getLevel(baseLevel).getHeight();
51233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
51243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(width, height)) : 1;
51253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51265a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		m_levels.updateSamplerMode(mode);
51275a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		m_view = tcu::Texture2DArrayView(numLevels, m_levels.getEffectiveLevels() + baseLevel);
51283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
51293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
51303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::Texture2DArrayView(0, DE_NULL);
51313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
51323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51333c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 Texture2DArray::sample (float s, float t, float r, float lod) const
51343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
51353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_view.sample(getSampler(), s, t, r, lod);
51363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
51373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DArray::sample4 (tcu::Vec4 output[4], const tcu::Vec3 packetTexcoords[4], float lodBias) const
51393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5140b0a384bf9b6816d4e3e594b37955d220d66ac7d1Jarkko Pöyry	const float texWidth  = (float)m_view.getWidth();
5141b0a384bf9b6816d4e3e594b37955d220d66ac7d1Jarkko Pöyry	const float texHeight = (float)m_view.getHeight();
51423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdx0 = packetTexcoords[1] - packetTexcoords[0];
51443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdx1 = packetTexcoords[3] - packetTexcoords[2];
51453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdy0 = packetTexcoords[2] - packetTexcoords[0];
51463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdy1 = packetTexcoords[3] - packetTexcoords[1];
51473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
51493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
51503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec3& dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
51513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec3& dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;
51523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mu = de::max(de::abs(dFdx.x()), de::abs(dFdy.x()));
51543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mv = de::max(de::abs(dFdx.y()), de::abs(dFdy.y()));
51553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float p = de::max(mu * texWidth, mv * texHeight);
51563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lod = deFloatLog2(p) + lodBias;
51583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		output[fragNdx] = sample(packetTexcoords[fragNdx].x(), packetTexcoords[fragNdx].y(), packetTexcoords[fragNdx].z(), lod);
51603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
51613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
51623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::TextureCubeArray (deUint32 name)
51643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: Texture	(name, TYPE_CUBE_MAP_ARRAY)
51653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view	(0, DE_NULL)
51663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
51673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
51683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51693c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::~TextureCubeArray (void)
51703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
51713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
51723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeArray::allocLevel (int level, const tcu::TextureFormat& format, int width, int height, int numLayers)
51743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
51753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(numLayers % 6 == 0);
51763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_levels.allocLevel(level, format, width, height, numLayers);
51773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
51783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool TextureCubeArray::isComplete (void) const
51803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
51813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	baseLevel	= getBaseLevel();
51823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel))
51843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
51853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::ConstPixelBufferAccess&	level0		= getLevel(baseLevel);
51863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool							mipmap		= isMipmapFilter(getSampler().minFilter);
51873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mipmap)
51893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
51903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const TextureFormat&	format		= level0.getFormat();
51913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				w			= level0.getWidth();
51923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				h			= level0.getHeight();
51933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLayers	= level0.getDepth();
51943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLevels	= de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(w, h));
51953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
51973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
51983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (hasLevel(baseLevel+levelNdx))
51993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
52003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const tcu::ConstPixelBufferAccess&	level		= getLevel(baseLevel+levelNdx);
52013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedW	= getMipLevelSize(w, levelNdx);
52023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedH	= getMipLevelSize(h, levelNdx);
52033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (level.getWidth()	!= expectedW	||
52053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getHeight()	!= expectedH	||
52063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getDepth()	!= numLayers	||
52073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getFormat()	!= format)
52083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						return false;
52093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
52103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
52113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
52123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
52133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
52143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
52163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
52173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
52183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
52193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
52203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52215a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyryvoid TextureCubeArray::updateView (tcu::Sampler::DepthStencilMode mode)
52223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
52233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int baseLevel	= getBaseLevel();
52243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel) && !isEmpty(getLevel(baseLevel)))
52263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
52273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	width		= getLevel(baseLevel).getWidth();
52283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	height		= getLevel(baseLevel).getHeight();
52293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
52303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(width, height)) : 1;
52313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52325a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		m_levels.updateSamplerMode(mode);
52335a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		m_view = tcu::TextureCubeArrayView(numLevels, m_levels.getEffectiveLevels() + baseLevel);
52343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
52353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
52363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::TextureCubeArrayView(0, DE_NULL);
52373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
52383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCubeArray::sample (float s, float t, float r, float q, float lod) const
52403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
52413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_view.sample(getSampler(), s, t, r, q, lod);
52423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
52433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeArray::sample4 (tcu::Vec4 output[4], const tcu::Vec4 packetTexcoords[4], float lodBias) const
52453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5246b0a384bf9b6816d4e3e594b37955d220d66ac7d1Jarkko Pöyry	const float		cubeSide		= (float)m_view.getSize();
52473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3	cubeCoords[4]	=
52483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
52493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		packetTexcoords[0].toWidth<3>(),
52503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		packetTexcoords[1].toWidth<3>(),
52513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		packetTexcoords[2].toWidth<3>(),
52523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		packetTexcoords[3].toWidth<3>()
52533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
52543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
52563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
52573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::CubeFace face			= tcu::selectCubeFace(cubeCoords[fragNdx]);
52583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2		faceCoords[4]	=
52593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
52603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, cubeCoords[0]),
52613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, cubeCoords[1]),
52623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, cubeCoords[2]),
52633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, cubeCoords[3]),
52643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
52653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdx0 = faceCoords[1] - faceCoords[0];
52673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdx1 = faceCoords[3] - faceCoords[2];
52683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdy0 = faceCoords[2] - faceCoords[0];
52693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdy1 = faceCoords[3] - faceCoords[1];
52703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2& dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
52723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2& dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;
52733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mu = de::max(de::abs(dFdx.x()), de::abs(dFdy.x()));
52753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mv = de::max(de::abs(dFdx.y()), de::abs(dFdy.y()));
52763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float p = de::max(mu * cubeSide, mv * cubeSide);
52773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lod = deFloatLog2(p) + lodBias;
52793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		output[fragNdx] = sample(packetTexcoords[fragNdx].x(), packetTexcoords[fragNdx].y(), packetTexcoords[fragNdx].z(), packetTexcoords[fragNdx].w(), lod);
52813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
52823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
52833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::Texture3D (deUint32 name)
52853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: Texture	(name, TYPE_3D)
52863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view	(0, DE_NULL)
52873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
52883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
52893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::~Texture3D (void)
52913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
52923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
52933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3D::allocLevel (int level, const tcu::TextureFormat& format, int width, int height, int depth)
52953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
52963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_levels.allocLevel(level, format, width, height, depth);
52973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
52983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool Texture3D::isComplete (void) const
53003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
53013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	baseLevel	= getBaseLevel();
53023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel))
53043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
53053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::ConstPixelBufferAccess&	level0		= getLevel(baseLevel);
53063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool							mipmap		= isMipmapFilter(getSampler().minFilter);
53073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mipmap)
53093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
53103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const TextureFormat&	format		= level0.getFormat();
53113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				w			= level0.getWidth();
53123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				h			= level0.getHeight();
53133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				d			= level0.getDepth();
53143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLevels	= de::min(getMaxLevel()-baseLevel+1, getNumMipLevels3D(w, h, d));
53153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
53173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
53183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (hasLevel(baseLevel+levelNdx))
53193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
53203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const tcu::ConstPixelBufferAccess&	level		= getLevel(baseLevel+levelNdx);
53213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedW	= getMipLevelSize(w, levelNdx);
53223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedH	= getMipLevelSize(h, levelNdx);
53233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedD	= getMipLevelSize(d, levelNdx);
53243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (level.getWidth()	!= expectedW	||
53263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getHeight()	!= expectedH	||
53273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getDepth()	!= expectedD	||
53283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getFormat()	!= format)
53293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						return false;
53303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
53313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
53323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
53333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
53343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
53353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
53373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
53383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
53393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
53403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
53413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 Texture3D::sample (float s, float t, float r, float lod) const
53433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
53443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_view.sample(getSampler(), s, t, r, lod);
53453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
53463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3D::sample4 (tcu::Vec4 output[4], const tcu::Vec3 packetTexcoords[4], float lodBias) const
53483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5349b0a384bf9b6816d4e3e594b37955d220d66ac7d1Jarkko Pöyry	const float texWidth  = (float)m_view.getWidth();
5350b0a384bf9b6816d4e3e594b37955d220d66ac7d1Jarkko Pöyry	const float texHeight = (float)m_view.getHeight();
5351b0a384bf9b6816d4e3e594b37955d220d66ac7d1Jarkko Pöyry	const float texDepth  = (float)m_view.getDepth();
53523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdx0 = packetTexcoords[1] - packetTexcoords[0];
53543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdx1 = packetTexcoords[3] - packetTexcoords[2];
53553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdy0 = packetTexcoords[2] - packetTexcoords[0];
53563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdy1 = packetTexcoords[3] - packetTexcoords[1];
53573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
53593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
53603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec3& dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
53613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec3& dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;
53623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mu = de::max(de::abs(dFdx.x()), de::abs(dFdy.x()));
53643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mv = de::max(de::abs(dFdx.y()), de::abs(dFdy.y()));
53653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mw = de::max(de::abs(dFdx.z()), de::abs(dFdy.z()));
53663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float p = de::max(de::max(mu * texWidth, mv * texHeight), mw * texDepth);
53673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lod = deFloatLog2(p) + lodBias;
53693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		output[fragNdx] = sample(packetTexcoords[fragNdx].x(), packetTexcoords[fragNdx].y(), packetTexcoords[fragNdx].z(), lod);
53713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
53723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
53733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53745a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyryvoid Texture3D::updateView (tcu::Sampler::DepthStencilMode mode)
53753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
53763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int baseLevel	= getBaseLevel();
53773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel) && !isEmpty(getLevel(baseLevel)))
53793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
53803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	width		= getLevel(baseLevel).getWidth();
53813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	height		= getLevel(baseLevel).getHeight();
53823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	depth		= getLevel(baseLevel).getDepth();
53833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
53843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels3D(width, height, depth)) : 1;
53853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53865a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		m_levels.updateSamplerMode(mode);
53875a0a3bbda9383ed89e44198619b9564282905865Jarkko Pöyry		m_view = tcu::Texture3DView(numLevels, m_levels.getEffectiveLevels() + baseLevel);
53883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
53893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
53903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::Texture3DView(0, DE_NULL);
53913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
53923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53933c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRenderbuffer::Renderbuffer (deUint32 name)
53943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: NamedObject		(name)
53953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
53963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
53973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRenderbuffer::~Renderbuffer (void)
53993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
54003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
54013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Renderbuffer::setStorage (const TextureFormat& format, int width, int height)
54033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
54043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data.setStorage(format, width, height);
54053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
54063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54073c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFramebuffer::Framebuffer (deUint32 name)
54083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: NamedObject(name)
54093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
54103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
54113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFramebuffer::~Framebuffer (void)
54133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
54143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
54153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54163c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexArray::VertexArray (deUint32 name, int maxVertexAttribs)
54173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: NamedObject					(name)
54183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_elementArrayBufferBinding	(DE_NULL)
54193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_arrays						(maxVertexAttribs)
54203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
54213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < maxVertexAttribs; ++i)
54223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
54233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].enabled			= false;
54243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].size			= 4;
54253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].stride			= 0;
54263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].type			= GL_FLOAT;
54273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].normalized		= false;
54283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].integer			= false;
54293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].divisor			= 0;
54303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].bufferDeleted	= false;
54313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].bufferBinding	= DE_NULL;
54323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].pointer			= DE_NULL;
54333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
54343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
54353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgramObjectContainer::ShaderProgramObjectContainer (deUint32 name, ShaderProgram* program)
54373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: NamedObject	(name)
54383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program		(program)
54393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_deleteFlag	(false)
54403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
54413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
54423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54433c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgramObjectContainer::~ShaderProgramObjectContainer (void)
54443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
54453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
54463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // rc
54483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // sglr
5449