sglrReferenceContext.cpp revision 5e334966c020f28d520c1c6bb36193990195fe0e
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);
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex1D.updateView();
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);
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex2D.updateView();
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	}
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTexCube.updateView();
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);
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex2DArray.updateView();
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);
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTex3D.updateView();
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);
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_emptyTexCubeArray.updateView();
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
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int z = 0; z < depth; z++)
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < height; y++)
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < width; x++)
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec4 data = src.getPixel(x, y, z);
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		dst.setPixel(Vec4(de::clamp(data.x(), 0.0f, 1.0f), data.y(), data.z(), data.w()), x, y, z);
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texImage1D (deUint32 target, int level, deUint32 internalFormat, int width, int border, deUint32 format, deUint32 type, const void* data)
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	texImage2D(target, level, internalFormat, width, 1, border, format, type, data);
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texImage2D (deUint32 target, int level, deUint32 internalFormat, int width, int height, int border, deUint32 format, deUint32 type, const void* data)
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	texImage3D(target, level, internalFormat, width, height, 1, border, format, type, data);
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texImage3D (deUint32 target, int level, deUint32 internalFormat, int width, int height, int depth, int border, deUint32 format, deUint32 type, const void* data)
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&		unit					= m_textureUnits[m_activeTexture];
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const void*			unpackPtr				= getPixelUnpackPtr(data);
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool			isDstFloatDepthFormat	= (internalFormat == GL_DEPTH_COMPONENT32F || internalFormat == GL_DEPTH32F_STENCIL8); // depth components are limited to [0,1] range
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat		storageFmt;
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat		transferFmt;
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(border != 0, GL_INVALID_VALUE, RC_RET_VOID);
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0 || height < 0 || depth < 0 || level < 0, GL_INVALID_VALUE, RC_RET_VOID);
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map storage format.
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	storageFmt = mapInternalFormat(internalFormat);
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(storageFmt.order	== TextureFormat::CHANNELORDER_LAST ||
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				storageFmt.type		== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map transfer format.
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	transferFmt = glu::mapGLTransferFormat(format, type);
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(transferFmt.order	== TextureFormat::CHANNELORDER_LAST ||
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				transferFmt.type	== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_1D && glu::isContextTypeGLCore(m_limits.contextType))
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width > m_limits.maxTexture2DSize || height != 1 || depth != 1, GL_INVALID_VALUE, RC_RET_VOID);
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture1D* texture = unit.tex1DBinding ? unit.tex1DBinding : &unit.default1DTex;
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getLevel(level));
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth(), GL_INVALID_OPERATION, RC_RET_VOID);
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocLevel(level, storageFmt, width);
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unpackPtr)
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess	src		= getUnpack2DAccess(transferFmt, width, 1, unpackPtr);
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess		dst		(texture->getLevel(level));
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDstFloatDepthFormat)
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				depthValueFloatClampCopy(dst, src);
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::copy(dst, src);
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// No data supplied, clear to black.
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess dst = texture->getLevel(level);
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::clear(dst, Vec4(0.0f, 0.0f, 0.0f, 1.0f));
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_2D)
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width > m_limits.maxTexture2DSize || height > m_limits.maxTexture2DSize || depth != 1, GL_INVALID_VALUE, RC_RET_VOID);
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2D* texture = unit.tex2DBinding ? unit.tex2DBinding : &unit.default2DTex;
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getLevel(level));
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth()	||
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						height		!= dst.getHeight(), GL_INVALID_OPERATION, RC_RET_VOID);
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocLevel(level, storageFmt, width, height);
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unpackPtr)
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess	src		= getUnpack2DAccess(transferFmt, width, height, unpackPtr);
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess		dst		(texture->getLevel(level));
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDstFloatDepthFormat)
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				depthValueFloatClampCopy(dst, src);
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::copy(dst, src);
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// No data supplied, clear to black.
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess dst = texture->getLevel(level);
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::clear(dst, Vec4(0.0f, 0.0f, 0.0f, 1.0f));
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ||
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z)
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width != height || width > m_limits.maxTextureCubeSize || depth != 1, GL_INVALID_VALUE, RC_RET_VOID);
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTextureCubeSize), GL_INVALID_VALUE, RC_RET_VOID);
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCube*	texture	= unit.texCubeBinding ? unit.texCubeBinding : &unit.defaultCubeTex;
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::CubeFace	face	= mapGLCubeFace(target);
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasFace(level, face), GL_INVALID_OPERATION, RC_RET_VOID);
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getFace(level, face));
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth()	||
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						height		!= dst.getHeight(), GL_INVALID_OPERATION, RC_RET_VOID);
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocFace(level, face, storageFmt, width, height);
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unpackPtr)
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess	src		= getUnpack2DAccess(transferFmt, width, height, unpackPtr);
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess		dst		(texture->getFace(level, face));
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDstFloatDepthFormat)
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				depthValueFloatClampCopy(dst, src);
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::copy(dst, src);
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// No data supplied, clear to black.
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess dst = texture->getFace(level, face);
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::clear(dst, Vec4(0.0f, 0.0f, 0.0f, 1.0f));
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_2D_ARRAY)
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width	> m_limits.maxTexture2DSize ||
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					height	> m_limits.maxTexture2DSize ||
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth	> m_limits.maxTexture2DArrayLayers, GL_INVALID_VALUE, RC_RET_VOID);
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2DArray* texture = unit.tex2DArrayBinding ? unit.tex2DArrayBinding : &unit.default2DArrayTex;
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getLevel(level));
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth()	||
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						height		!= dst.getHeight()	||
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						depth		!= dst.getDepth(), GL_INVALID_OPERATION, RC_RET_VOID);
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocLevel(level, storageFmt, width, height, depth);
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unpackPtr)
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess	src		= getUnpack3DAccess(transferFmt, width, height, depth, unpackPtr);
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess		dst		(texture->getLevel(level));
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDstFloatDepthFormat)
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				depthValueFloatClampCopy(dst, src);
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::copy(dst, src);
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// No data supplied, clear to black.
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess dst = texture->getLevel(level);
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::clear(dst, Vec4(0.0f, 0.0f, 0.0f, 1.0f));
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_3D)
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width	> m_limits.maxTexture3DSize ||
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					height	> m_limits.maxTexture3DSize ||
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth	> m_limits.maxTexture3DSize, GL_INVALID_VALUE, RC_RET_VOID);
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture3DSize), GL_INVALID_VALUE, RC_RET_VOID);
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture3D* texture = unit.tex3DBinding ? unit.tex3DBinding : &unit.default3DTex;
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getLevel(level));
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth()	||
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						height		!= dst.getHeight()	||
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						depth		!= dst.getDepth(), GL_INVALID_OPERATION, RC_RET_VOID);
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocLevel(level, storageFmt, width, height, depth);
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unpackPtr)
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess	src		= getUnpack3DAccess(transferFmt, width, height, depth, unpackPtr);
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess		dst		(texture->getLevel(level));
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDstFloatDepthFormat)
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				depthValueFloatClampCopy(dst, src);
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::copy(dst, src);
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// No data supplied, clear to black.
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess dst = texture->getLevel(level);
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::clear(dst, Vec4(0.0f, 0.0f, 0.0f, 1.0f));
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width		!= height						||
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					width		 > m_limits.maxTexture2DSize	||
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth % 6	!= 0							||
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth		 > m_limits.maxTexture2DArrayLayers, GL_INVALID_VALUE, RC_RET_VOID);
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCubeArray* texture = unit.texCubeArrayBinding ? unit.texCubeArrayBinding : &unit.defaultCubeArrayTex;
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getLevel(level));
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth()	||
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						height		!= dst.getHeight()	||
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						depth		!= dst.getDepth(), GL_INVALID_OPERATION, RC_RET_VOID);
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocLevel(level, storageFmt, width, height, depth);
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (unpackPtr)
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess	src		= getUnpack3DAccess(transferFmt, width, height, depth, unpackPtr);
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess		dst		(texture->getLevel(level));
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isDstFloatDepthFormat)
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				depthValueFloatClampCopy(dst, src);
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::copy(dst, src);
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// No data supplied, clear to black.
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			PixelBufferAccess dst = texture->getLevel(level);
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::clear(dst, Vec4(0.0f, 0.0f, 0.0f, 1.0f));
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texSubImage1D (deUint32 target, int level, int xoffset, int width, deUint32 format, deUint32 type, const void* data)
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	texSubImage2D(target, level, xoffset, 0, width, 1, format, type, data);
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texSubImage2D (deUint32 target, int level, int xoffset, int yoffset, int width, int height, deUint32 format, deUint32 type, const void* data)
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	texSubImage3D(target, level, xoffset, yoffset, 0, width, height, 1, format, type, data);
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12663c827367444ee418f129b2c238299f49d3264554Jarkko 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)
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit& unit = m_textureUnits[m_activeTexture];
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(xoffset < 0 || yoffset < 0 || zoffset < 0,	GL_INVALID_VALUE, RC_RET_VOID);
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0 || height < 0 || depth < 0,		GL_INVALID_VALUE, RC_RET_VOID);
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat transferFmt = glu::mapGLTransferFormat(format, type);
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(transferFmt.order	== TextureFormat::CHANNELORDER_LAST ||
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				transferFmt.type	== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstPixelBufferAccess src = getUnpack3DAccess(transferFmt, width, height, depth, getPixelUnpackPtr(data));
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_1D && glu::isContextTypeGLCore(m_limits.contextType))
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture1D& texture = unit.tex1DBinding ? *unit.tex1DBinding : unit.default1DTex;
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getLevel(level);
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight()	||
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					zoffset + depth		> dst.getDepth(),
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// depth components are limited to [0,1] range
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_2D)
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2D& texture = unit.tex2DBinding ? *unit.tex2DBinding : unit.default2DTex;
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getLevel(level);
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight()	||
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					zoffset + depth		> dst.getDepth(),
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// depth components are limited to [0,1] range
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ||
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z)
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCube&	texture		= unit.texCubeBinding ? *unit.texCubeBinding : unit.defaultCubeTex;
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::CubeFace	face		= mapGLCubeFace(target);
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasFace(level, face), GL_INVALID_VALUE, RC_RET_VOID);
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getFace(level, face);
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight()	||
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					zoffset + depth		> dst.getDepth(),
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// depth components are limited to [0,1] range
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_3D)
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture3D& texture = unit.tex3DBinding ? *unit.tex3DBinding : unit.default3DTex;
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getLevel(level);
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight()	||
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					zoffset + depth		> dst.getDepth(),
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// depth components are limited to [0,1] range
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_2D_ARRAY)
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2DArray& texture = unit.tex2DArrayBinding ? *unit.tex2DArrayBinding : unit.default2DArrayTex;
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getLevel(level);
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight()	||
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					zoffset + depth		> dst.getDepth(),
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// depth components are limited to [0,1] range
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCubeArray& texture = unit.texCubeArrayBinding ? *unit.texCubeArrayBinding : unit.defaultCubeArrayTex;
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getLevel(level);
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth()	||
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight()	||
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					zoffset + depth		> dst.getDepth(),
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// depth components are limited to [0,1] range
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (dst.getFormat().order == tcu::TextureFormat::D || dst.getFormat().order == tcu::TextureFormat::DS)
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			depthValueFloatClampCopy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::copy(tcu::getSubregion(dst, xoffset, yoffset, zoffset, width, height, depth), src);
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::copyTexImage1D (deUint32 target, int level, deUint32 internalFormat, int x, int y, int width, int border)
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&							unit		= m_textureUnits[m_activeTexture];
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat							storageFmt;
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisampleConstPixelBufferAccess	src			= getReadColorbuffer();
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(border != 0, GL_INVALID_VALUE, RC_RET_VOID);
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0 || level < 0, GL_INVALID_VALUE, RC_RET_VOID);
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(isEmpty(src), GL_INVALID_OPERATION, RC_RET_VOID);
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map storage format.
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	storageFmt = mapInternalFormat(internalFormat);
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(storageFmt.order	== TextureFormat::CHANNELORDER_LAST ||
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				storageFmt.type		== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_1D)
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width > m_limits.maxTexture2DSize, GL_INVALID_VALUE, RC_RET_VOID);
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture1D* texture = unit.tex1DBinding ? unit.tex1DBinding : &unit.default1DTex;
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getLevel(level));
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth(), GL_INVALID_OPERATION, RC_RET_VOID);
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocLevel(level, storageFmt, width);
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Copy from current framebuffer.
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture->getLevel(level);
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int xo = 0; xo < width; xo++)
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::inBounds(x+xo, 0, src.raw().getHeight()))
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue; // Undefined pixel.
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y), xo, 0);
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::copyTexImage2D (deUint32 target, int level, deUint32 internalFormat, int x, int y, int width, int height, int border)
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&							unit		= m_textureUnits[m_activeTexture];
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat							storageFmt;
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisampleConstPixelBufferAccess	src			= getReadColorbuffer();
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(border != 0, GL_INVALID_VALUE, RC_RET_VOID);
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0 || height < 0 || level < 0, GL_INVALID_VALUE, RC_RET_VOID);
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(isEmpty(src), GL_INVALID_OPERATION, RC_RET_VOID);
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map storage format.
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	storageFmt = mapInternalFormat(internalFormat);
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(storageFmt.order	== TextureFormat::CHANNELORDER_LAST ||
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				storageFmt.type		== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_2D)
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width > m_limits.maxTexture2DSize || height > m_limits.maxTexture2DSize, GL_INVALID_VALUE, RC_RET_VOID);
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTexture2DSize), GL_INVALID_VALUE, RC_RET_VOID);
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2D* texture = unit.tex2DBinding ? unit.tex2DBinding : &unit.default2DTex;
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasLevel(level), GL_INVALID_OPERATION, RC_RET_VOID);
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getLevel(level));
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth()	||
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						height		!= dst.getHeight(), GL_INVALID_OPERATION, RC_RET_VOID);
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocLevel(level, storageFmt, width, height);
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Copy from current framebuffer.
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture->getLevel(level);
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int yo = 0; yo < height; yo++)
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int xo = 0; xo < width; xo++)
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::inBounds(x+xo, 0, src.raw().getHeight()) || !de::inBounds(y+yo, 0, src.raw().getDepth()))
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue; // Undefined pixel.
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y+yo), xo, yo);
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ||
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z)
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate size and level.
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width != height || width > m_limits.maxTextureCubeSize, GL_INVALID_VALUE, RC_RET_VOID);
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(level > deLog2Floor32(m_limits.maxTextureCubeSize), GL_INVALID_VALUE, RC_RET_VOID);
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCube*	texture	= unit.texCubeBinding ? unit.texCubeBinding : &unit.defaultCubeTex;
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::CubeFace	face	= mapGLCubeFace(target);
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture->isImmutable())
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texture->hasFace(level, face), GL_INVALID_OPERATION, RC_RET_VOID);
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			ConstPixelBufferAccess dst(texture->getFace(level, face));
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(storageFmt	!= dst.getFormat()	||
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						width		!= dst.getWidth()	||
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						height		!= dst.getHeight(), GL_INVALID_OPERATION, RC_RET_VOID);
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->allocFace(level, face, storageFmt, width, height);
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Copy from current framebuffer.
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture->getFace(level, face);
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int yo = 0; yo < height; yo++)
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int xo = 0; xo < width; xo++)
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::inBounds(x+xo, 0, src.raw().getHeight()) || !de::inBounds(y+yo, 0, src.raw().getDepth()))
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue; // Undefined pixel.
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y+yo), xo, yo);
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::copyTexSubImage1D (deUint32 target, int level, int xoffset, int x, int y, int width)
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&							unit	= m_textureUnits[m_activeTexture];
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisampleConstPixelBufferAccess	src		= getReadColorbuffer();
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(xoffset < 0,	GL_INVALID_VALUE,		RC_RET_VOID);
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0,		GL_INVALID_VALUE,		RC_RET_VOID);
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(isEmpty(src),	GL_INVALID_OPERATION,	RC_RET_VOID);
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_1D)
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture1D& texture = unit.tex1DBinding ? *unit.tex1DBinding : unit.default1DTex;
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getLevel(level);
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width > dst.getWidth(), GL_INVALID_VALUE, RC_RET_VOID);
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int xo = 0; xo < width; xo++)
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::inBounds(x+xo, 0, src.raw().getHeight()))
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue;
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y), xo+xoffset, 0);
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::copyTexSubImage2D (deUint32 target, int level, int xoffset, int yoffset, int x, int y, int width, int height)
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&							unit	= m_textureUnits[m_activeTexture];
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisampleConstPixelBufferAccess	src		= getReadColorbuffer();
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(xoffset < 0 || yoffset < 0,					GL_INVALID_VALUE, RC_RET_VOID);
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0 || height < 0,					GL_INVALID_VALUE, RC_RET_VOID);
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(isEmpty(src),								GL_INVALID_OPERATION, RC_RET_VOID);
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_2D)
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2D& texture = unit.tex2DBinding ? *unit.tex2DBinding : unit.default2DTex;
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasLevel(level), GL_INVALID_VALUE, RC_RET_VOID);
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getLevel(level);
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth() ||
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight(),
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int yo = 0; yo < height; yo++)
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int xo = 0; xo < width; xo++)
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::inBounds(x+xo, 0, src.raw().getHeight()) || !de::inBounds(y+yo, 0, src.raw().getDepth()))
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue;
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y+yo), xo+xoffset, yo+yoffset);
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X ||
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y ||
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y ||
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z ||
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z)
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCube&	texture		= unit.texCubeBinding ? *unit.texCubeBinding : unit.defaultCubeTex;
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::CubeFace	face		= mapGLCubeFace(target);
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!texture.hasFace(level, face), GL_INVALID_VALUE, RC_RET_VOID);
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		PixelBufferAccess dst = texture.getFace(level, face);
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(xoffset + width		> dst.getWidth() ||
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					yoffset + height	> dst.getHeight(),
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					GL_INVALID_VALUE, RC_RET_VOID);
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int yo = 0; yo < height; yo++)
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int xo = 0; xo < width; xo++)
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!de::inBounds(x+xo, 0, src.raw().getHeight()) || !de::inBounds(y+yo, 0, src.raw().getDepth()))
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				continue;
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.setPixel(rr::resolveMultisamplePixel(src, x+xo, y+yo), xo+xoffset, yo+yoffset);
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::copyTexSubImage3D (deUint32 target, int level, int xoffset, int yoffset, int zoffset, int x, int y, int width, int height)
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(target && level && xoffset && yoffset && zoffset && x && y && width && height);
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texStorage2D (deUint32 target, int levels, deUint32 internalFormat, int width, int height)
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&		unit		= m_textureUnits[m_activeTexture];
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat		storageFmt;
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width <= 0 || height <= 0, GL_INVALID_VALUE, RC_RET_VOID);
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!de::inRange(levels, 1, (int)deLog2Floor32(de::max(width, height))+1), GL_INVALID_VALUE, RC_RET_VOID);
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map storage format.
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	storageFmt = mapInternalFormat(internalFormat);
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(storageFmt.order	== TextureFormat::CHANNELORDER_LAST ||
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				storageFmt.type		== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_2D)
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2D& texture = unit.tex2DBinding ? *unit.tex2DBinding : unit.default2DTex;
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width > m_limits.maxTexture2DSize || height >= m_limits.maxTexture2DSize, GL_INVALID_VALUE, RC_RET_VOID);
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(texture.isImmutable(), GL_INVALID_OPERATION, RC_RET_VOID);
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.clearLevels();
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.setImmutable();
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int level = 0; level < levels; level++)
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelW = de::max(1, width >> level);
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelH = de::max(1, height >> level);
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture.allocLevel(level, storageFmt, levelW, levelH);
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP)
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCube& texture = unit.texCubeBinding ? *unit.texCubeBinding : unit.defaultCubeTex;
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width > m_limits.maxTextureCubeSize || height > m_limits.maxTextureCubeSize, GL_INVALID_VALUE, RC_RET_VOID);
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(texture.isImmutable(), GL_INVALID_OPERATION, RC_RET_VOID);
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.clearLevels();
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.setImmutable();
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int level = 0; level < levels; level++)
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelW = de::max(1, width >> level);
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelH = de::max(1, height >> level);
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				texture.allocFace(level, (tcu::CubeFace)face, storageFmt, levelW, levelH);
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texStorage3D (deUint32 target, int levels, deUint32 internalFormat, int width, int height, int depth)
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&		unit		= m_textureUnits[m_activeTexture];
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat		storageFmt;
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width <= 0 || height <= 0, GL_INVALID_VALUE, RC_RET_VOID);
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!de::inRange(levels, 1, (int)deLog2Floor32(de::max(width, height))+1), GL_INVALID_VALUE, RC_RET_VOID);
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map storage format.
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	storageFmt = mapInternalFormat(internalFormat);
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(storageFmt.order	== TextureFormat::CHANNELORDER_LAST ||
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				storageFmt.type		== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (target == GL_TEXTURE_2D_ARRAY)
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture2DArray& texture = unit.tex2DArrayBinding ? *unit.tex2DArrayBinding : unit.default2DArrayTex;
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width	>	m_limits.maxTexture2DSize	||
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					height	>=	m_limits.maxTexture2DSize	||
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth	>=	m_limits.maxTexture2DArrayLayers, GL_INVALID_VALUE, RC_RET_VOID);
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(texture.isImmutable(), GL_INVALID_OPERATION, RC_RET_VOID);
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.clearLevels();
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.setImmutable();
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int level = 0; level < levels; level++)
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelW = de::max(1, width >> level);
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelH = de::max(1, height >> level);
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture.allocLevel(level, storageFmt, levelW, levelH, depth);
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_3D)
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture3D& texture = unit.tex3DBinding ? *unit.tex3DBinding : unit.default3DTex;
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width	> m_limits.maxTexture3DSize	||
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					height	> m_limits.maxTexture3DSize	||
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth	> m_limits.maxTexture3DSize, GL_INVALID_VALUE, RC_RET_VOID);
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(texture.isImmutable(), GL_INVALID_OPERATION, RC_RET_VOID);
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.clearLevels();
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.setImmutable();
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int level = 0; level < levels; level++)
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelW = de::max(1, width		>> level);
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelH = de::max(1, height	>> level);
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelD = de::max(1, depth		>> level);
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture.allocLevel(level, storageFmt, levelW, levelH, levelD);
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (target == GL_TEXTURE_CUBE_MAP_ARRAY)
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TextureCubeArray& texture = unit.texCubeArrayBinding ? *unit.texCubeArrayBinding : unit.defaultCubeArrayTex;
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(width		!=	height								||
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth % 6	!= 0									||
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					width		>	m_limits.maxTexture2DSize			||
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					depth		>=	m_limits.maxTexture2DArrayLayers, GL_INVALID_VALUE, RC_RET_VOID);
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(texture.isImmutable(), GL_INVALID_OPERATION, RC_RET_VOID);
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.clearLevels();
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		texture.setImmutable();
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int level = 0; level < levels; level++)
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelW = de::max(1, width >> level);
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int levelH = de::max(1, height >> level);
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture.allocLevel(level, storageFmt, levelW, levelH, depth);
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \todo [2014-02-19 pyry] Duplicated with code in gluTextureUtil.hpp
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::Sampler::WrapMode mapGLWrapMode (int value)
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (value)
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_CLAMP_TO_EDGE:		return tcu::Sampler::CLAMP_TO_EDGE;
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_REPEAT:				return tcu::Sampler::REPEAT_GL;
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MIRRORED_REPEAT:	return tcu::Sampler::MIRRORED_REPEAT_GL;
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:					return tcu::Sampler::WRAPMODE_LAST;
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::Sampler::FilterMode mapGLFilterMode (int value)
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (value)
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_NEAREST:				return tcu::Sampler::NEAREST;
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LINEAR:					return tcu::Sampler::LINEAR;
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_NEAREST_MIPMAP_NEAREST:	return tcu::Sampler::NEAREST_MIPMAP_NEAREST;
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_NEAREST_MIPMAP_LINEAR:	return tcu::Sampler::NEAREST_MIPMAP_LINEAR;
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LINEAR_MIPMAP_NEAREST:	return tcu::Sampler::LINEAR_MIPMAP_NEAREST;
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LINEAR_MIPMAP_LINEAR:	return tcu::Sampler::LINEAR_MIPMAP_LINEAR;
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:						return tcu::Sampler::FILTERMODE_LAST;
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::texParameteri (deUint32 target, deUint32 pname, int value)
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureUnit&	unit		= m_textureUnits[m_activeTexture];
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Texture*		texture		= DE_NULL;
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (target)
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_1D:				texture = unit.tex1DBinding			? unit.tex1DBinding			: &unit.default1DTex;			break;
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_2D:				texture = unit.tex2DBinding			? unit.tex2DBinding			: &unit.default2DTex;			break;
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP:		texture = unit.texCubeBinding		? unit.texCubeBinding		: &unit.defaultCubeTex;			break;
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_2D_ARRAY:		texture = unit.tex2DArrayBinding	? unit.tex2DArrayBinding	: &unit.default2DArrayTex;		break;
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_3D:				texture = unit.tex3DBinding			? unit.tex3DBinding			: &unit.default3DTex;			break;
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_ARRAY:	texture = unit.texCubeArrayBinding	? unit.texCubeArrayBinding	: &unit.defaultCubeArrayTex;	break;
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:					RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (pname)
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_WRAP_S:
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Sampler::WrapMode wrapS = mapGLWrapMode(value);
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(wrapS == tcu::Sampler::WRAPMODE_LAST, GL_INVALID_VALUE, RC_RET_VOID);
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->getSampler().wrapS = wrapS;
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_WRAP_T:
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Sampler::WrapMode wrapT = mapGLWrapMode(value);
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(wrapT == tcu::Sampler::WRAPMODE_LAST, GL_INVALID_VALUE, RC_RET_VOID);
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->getSampler().wrapT = wrapT;
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_WRAP_R:
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Sampler::WrapMode wrapR = mapGLWrapMode(value);
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(wrapR == tcu::Sampler::WRAPMODE_LAST, GL_INVALID_VALUE, RC_RET_VOID);
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->getSampler().wrapR = wrapR;
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_MIN_FILTER:
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Sampler::FilterMode minMode = mapGLFilterMode(value);
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(minMode == tcu::Sampler::FILTERMODE_LAST, GL_INVALID_VALUE, RC_RET_VOID);
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->getSampler().minFilter = minMode;
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_MAG_FILTER:
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::Sampler::FilterMode magMode = mapGLFilterMode(value);
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(magMode != tcu::Sampler::LINEAR && magMode != tcu::Sampler::NEAREST,
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						GL_INVALID_VALUE, RC_RET_VOID);
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->getSampler().magFilter = magMode;
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_MAX_LEVEL:
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(value < 0, GL_INVALID_VALUE, RC_RET_VOID);
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texture->setMaxLevel(value);
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Framebuffer::AttachmentPoint mapGLAttachmentPoint (deUint32 attachment)
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (attachment)
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_COLOR_ATTACHMENT0:	return Framebuffer::ATTACHMENTPOINT_COLOR0;
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DEPTH_ATTACHMENT:	return Framebuffer::ATTACHMENTPOINT_DEPTH;
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_STENCIL_ATTACHMENT:	return Framebuffer::ATTACHMENTPOINT_STENCIL;
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:					return Framebuffer::ATTACHMENTPOINT_LAST;
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Framebuffer::TexTarget mapGLFboTexTarget (deUint32 target)
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (target)
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_2D:						return Framebuffer::TEXTARGET_2D;
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:	return Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_X;
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:	return Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_Y;
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:	return Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_Z;
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:	return Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_X;
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:	return Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Y;
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:	return Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Z;
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:								return Framebuffer::TEXTARGET_LAST;
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::acquireFboAttachmentReference (const Framebuffer::Attachment& attachment)
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (attachment.type)
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::ATTACHMENTTYPE_TEXTURE:
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(attachment.name != 0);
19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Texture* texture = m_textures.find(attachment.name);
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(texture);
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.acquireReference(texture);
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::ATTACHMENTTYPE_RENDERBUFFER:
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(attachment.name != 0);
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Renderbuffer* rbo = m_renderbuffers.find(attachment.name);
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(rbo);
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_renderbuffers.acquireReference(rbo);
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break; // Silently ignore
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::releaseFboAttachmentReference (const Framebuffer::Attachment& attachment)
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (attachment.type)
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::ATTACHMENTTYPE_TEXTURE:
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(attachment.name != 0);
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Texture* texture = m_textures.find(attachment.name);
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(texture);
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures.releaseReference(texture);
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::ATTACHMENTTYPE_RENDERBUFFER:
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(attachment.name != 0);
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Renderbuffer* rbo = m_renderbuffers.find(attachment.name);
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(rbo);
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_renderbuffers.releaseReference(rbo);
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break; // Silently ignore
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::framebufferTexture2D (deUint32 target, deUint32 attachment, deUint32 textarget, deUint32 texture, int level)
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Attach to both depth and stencil.
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferTexture2D(target, GL_DEPTH_ATTACHMENT,	textarget, texture, level);
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferTexture2D(target, GL_STENCIL_ATTACHMENT,	textarget, texture, level);
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Framebuffer::AttachmentPoint	point			= mapGLAttachmentPoint(attachment);
19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture*						texObj			= DE_NULL;
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Framebuffer::TexTarget			fboTexTarget	= mapGLFboTexTarget(textarget);
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(target != GL_FRAMEBUFFER		&&
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					target != GL_DRAW_FRAMEBUFFER	&&
19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					target != GL_READ_FRAMEBUFFER,				GL_INVALID_ENUM,		RC_RET_VOID);
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(point == Framebuffer::ATTACHMENTPOINT_LAST,	GL_INVALID_ENUM,		RC_RET_VOID);
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Select binding point.
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rc::Framebuffer* framebufferBinding = (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) ? m_drawFramebufferBinding : m_readFramebufferBinding;
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!framebufferBinding, GL_INVALID_OPERATION, RC_RET_VOID);
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// If framebuffer object is bound for both reading and writing then we need to acquire/release multiple references.
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bindingRefCount = (framebufferBinding == m_drawFramebufferBinding ? 1 : 0)
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							+ (framebufferBinding == m_readFramebufferBinding ? 1 : 0);
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture != 0)
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texObj = m_textures.find(texture);
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texObj,		GL_INVALID_OPERATION,	RC_RET_VOID);
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(level != 0,		GL_INVALID_VALUE,		RC_RET_VOID); // \todo [2012-03-19 pyry] We should allow other levels as well.
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (texObj->getType() == Texture::TYPE_2D)
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				RC_IF_ERROR(fboTexTarget != Framebuffer::TEXTARGET_2D, GL_INVALID_OPERATION, RC_RET_VOID);
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TCU_CHECK(texObj->getType() == Texture::TYPE_CUBE_MAP);
19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (!deInRange32(fboTexTarget, Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_X, Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Z))
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					RC_ERROR_RET(GL_INVALID_OPERATION, RC_RET_VOID);
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Framebuffer::Attachment& fboAttachment = framebufferBinding->getAttachment(point);
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < bindingRefCount; ndx++)
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			releaseFboAttachmentReference(fboAttachment);
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fboAttachment = Framebuffer::Attachment();
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texObj)
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.type			= Framebuffer::ATTACHMENTTYPE_TEXTURE;
20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.name			= texObj->getName();
20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.texTarget		= fboTexTarget;
20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.level			= level;
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < bindingRefCount; ndx++)
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				acquireFboAttachmentReference(fboAttachment);
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::framebufferTextureLayer (deUint32 target, deUint32 attachment, deUint32 texture, int level, int layer)
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Attach to both depth and stencil.
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferTextureLayer(target, GL_DEPTH_ATTACHMENT,	texture, level, layer);
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferTextureLayer(target, GL_STENCIL_ATTACHMENT,	texture, level, layer);
20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Framebuffer::AttachmentPoint	point			= mapGLAttachmentPoint(attachment);
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Texture*						texObj			= DE_NULL;
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(target != GL_FRAMEBUFFER		&&
20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					target != GL_DRAW_FRAMEBUFFER	&&
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					target != GL_READ_FRAMEBUFFER,				GL_INVALID_ENUM,		RC_RET_VOID);
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(point == Framebuffer::ATTACHMENTPOINT_LAST,	GL_INVALID_ENUM,		RC_RET_VOID);
20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Select binding point.
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rc::Framebuffer* framebufferBinding = (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) ? m_drawFramebufferBinding : m_readFramebufferBinding;
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!framebufferBinding, GL_INVALID_OPERATION, RC_RET_VOID);
20313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// If framebuffer object is bound for both reading and writing then we need to acquire/release multiple references.
20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bindingRefCount = (framebufferBinding == m_drawFramebufferBinding ? 1 : 0)
20343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							+ (framebufferBinding == m_readFramebufferBinding ? 1 : 0);
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texture != 0)
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			texObj = m_textures.find(texture);
20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!texObj,		GL_INVALID_OPERATION,	RC_RET_VOID);
20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(level != 0,		GL_INVALID_VALUE,		RC_RET_VOID); // \todo [2012-03-19 pyry] We should allow other levels as well.
20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			RC_IF_ERROR(texObj->getType() != Texture::TYPE_2D_ARRAY			&&
20448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry						texObj->getType() != Texture::TYPE_3D				&&
20458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry						texObj->getType() != Texture::TYPE_CUBE_MAP_ARRAY,				GL_INVALID_OPERATION,	RC_RET_VOID);
20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			if (texObj->getType() == Texture::TYPE_2D_ARRAY || texObj->getType() == Texture::TYPE_CUBE_MAP_ARRAY)
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				RC_IF_ERROR((layer < 0) || (layer >= GL_MAX_ARRAY_TEXTURE_LAYERS),		GL_INVALID_VALUE,		RC_RET_VOID);
20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				RC_IF_ERROR((level < 0) || (level > tcu::log2(GL_MAX_TEXTURE_SIZE)),	GL_INVALID_VALUE,		RC_RET_VOID);
20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if	(texObj->getType() == Texture::TYPE_3D)
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				RC_IF_ERROR((layer < 0) || (layer >= GL_MAX_3D_TEXTURE_SIZE),			GL_INVALID_VALUE,		RC_RET_VOID);
20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				RC_IF_ERROR((level < 0) || (level > tcu::log2(GL_MAX_3D_TEXTURE_SIZE)),	GL_INVALID_VALUE,		RC_RET_VOID);
20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Framebuffer::Attachment& fboAttachment = framebufferBinding->getAttachment(point);
20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < bindingRefCount; ndx++)
20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			releaseFboAttachmentReference(fboAttachment);
20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fboAttachment = Framebuffer::Attachment();
20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texObj)
20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.type			= Framebuffer::ATTACHMENTTYPE_TEXTURE;
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.name			= texObj->getName();
20688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			fboAttachment.texTarget		= texLayeredTypeToTarget(texObj->getType());
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.level			= level;
20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.layer			= layer;
20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			DE_ASSERT(fboAttachment.texTarget != Framebuffer::TEXTARGET_LAST);
20738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < bindingRefCount; ndx++)
20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				acquireFboAttachmentReference(fboAttachment);
20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::framebufferRenderbuffer (deUint32 target, deUint32 attachment, deUint32 renderbuffertarget, deUint32 renderbuffer)
20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (attachment == GL_DEPTH_STENCIL_ATTACHMENT)
20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Attach both to depth and stencil.
20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT,	renderbuffertarget, renderbuffer);
20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT,	renderbuffertarget, renderbuffer);
20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Framebuffer::AttachmentPoint	point			= mapGLAttachmentPoint(attachment);
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Renderbuffer*					rbo				= DE_NULL;
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(target != GL_FRAMEBUFFER		&&
20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					target != GL_DRAW_FRAMEBUFFER	&&
20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					target != GL_READ_FRAMEBUFFER,				GL_INVALID_ENUM,		RC_RET_VOID);
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(point == Framebuffer::ATTACHMENTPOINT_LAST,	GL_INVALID_ENUM,		RC_RET_VOID);
20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Select binding point.
20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rc::Framebuffer* framebufferBinding = (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) ? m_drawFramebufferBinding : m_readFramebufferBinding;
21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!framebufferBinding, GL_INVALID_OPERATION, RC_RET_VOID);
21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// If framebuffer object is bound for both reading and writing then we need to acquire/release multiple references.
21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int bindingRefCount = (framebufferBinding == m_drawFramebufferBinding ? 1 : 0)
21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							+ (framebufferBinding == m_readFramebufferBinding ? 1 : 0);
21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (renderbuffer != 0)
21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rbo = m_renderbuffers.find(renderbuffer);
21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(renderbuffertarget != GL_RENDERBUFFER,	GL_INVALID_ENUM,		RC_RET_VOID);
21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(!rbo,									GL_INVALID_OPERATION,	RC_RET_VOID);
21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Framebuffer::Attachment& fboAttachment = framebufferBinding->getAttachment(point);
21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < bindingRefCount; ndx++)
21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			releaseFboAttachmentReference(fboAttachment);
21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		fboAttachment = Framebuffer::Attachment();
21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (rbo)
21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.type	= Framebuffer::ATTACHMENTTYPE_RENDERBUFFER;
21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fboAttachment.name	= rbo->getName();
21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int ndx = 0; ndx < bindingRefCount; ndx++)
21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				acquireFboAttachmentReference(fboAttachment);
21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21303c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 ReferenceContext::checkFramebufferStatus (deUint32 target)
21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(target != GL_FRAMEBUFFER		&&
21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				target != GL_DRAW_FRAMEBUFFER	&&
21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				target != GL_READ_FRAMEBUFFER, GL_INVALID_ENUM, 0);
21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Select binding point.
21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::Framebuffer* framebufferBinding = (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER) ? m_drawFramebufferBinding : m_readFramebufferBinding;
21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Default framebuffer is always complete.
21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!framebufferBinding)
21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return GL_FRAMEBUFFER_COMPLETE;
21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		width				= -1;
21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		height				= -1;
21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	hasAttachment		= false;
21463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	attachmentComplete	= true;
21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	dimensionsOk		= true;
21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int point = 0; point < Framebuffer::ATTACHMENTPOINT_LAST; point++)
21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Framebuffer::Attachment&	attachment			= framebufferBinding->getAttachment((Framebuffer::AttachmentPoint)point);
21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int								attachmentWidth		= 0;
21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int								attachmentHeight	= 0;
21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureFormat				attachmentFormat;
21553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (attachment.type == Framebuffer::ATTACHMENTTYPE_TEXTURE)
21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Texture*					texture	= m_textures.find(attachment.name);
21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::ConstPixelBufferAccess		level;
21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(texture);
21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (attachment.texTarget == Framebuffer::TEXTARGET_2D)
21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(texture->getType() == Texture::TYPE_2D);
21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const Texture2D* tex2D = static_cast<const Texture2D*>(texture);
21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex2D->hasLevel(attachment.level))
21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					level = tex2D->getLevel(attachment.level);
21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (deInRange32(attachment.texTarget, Framebuffer::TEXTARGET_CUBE_MAP_POSITIVE_X,
21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													   Framebuffer::TEXTARGET_CUBE_MAP_NEGATIVE_Z))
21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(texture->getType() == Texture::TYPE_CUBE_MAP);
21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const TextureCube*	texCube	= static_cast<const TextureCube*>(texture);
21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const tcu::CubeFace	face	= texTargetToFace(attachment.texTarget);
21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TCU_CHECK(de::inBounds<int>(face, 0, tcu::CUBEFACE_LAST));
21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (texCube->hasFace(attachment.level, face))
21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					level = texCube->getFace(attachment.level, face);
21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (attachment.texTarget == Framebuffer::TEXTARGET_2D_ARRAY)
21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(texture->getType() == Texture::TYPE_2D_ARRAY);
21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const Texture2DArray* tex2DArr = static_cast<const Texture2DArray*>(texture);
21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex2DArr->hasLevel(attachment.level))
21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					level = tex2DArr->getLevel(attachment.level); // \note Slice doesn't matter here.
21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (attachment.texTarget == Framebuffer::TEXTARGET_3D)
21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
21923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(texture->getType() == Texture::TYPE_3D);
21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const Texture3D* tex3D = static_cast<const Texture3D*>(texture);
21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex3D->hasLevel(attachment.level))
21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					level = tex3D->getLevel(attachment.level); // \note Slice doesn't matter here.
21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
21988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			else if (attachment.texTarget == Framebuffer::TEXTARGET_CUBE_MAP_ARRAY)
21998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			{
22008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				DE_ASSERT(texture->getType() == Texture::TYPE_CUBE_MAP_ARRAY);
22018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				const TextureCubeArray* texCubeArr = static_cast<const TextureCubeArray*>(texture);
22028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
22038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				if (texCubeArr->hasLevel(attachment.level))
22048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry					level = texCubeArr->getLevel(attachment.level); // \note Slice doesn't matter here.
22058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			}
22063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TCU_FAIL("Framebuffer attached to a texture but no valid target specified");
22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attachmentWidth		= level.getWidth();
22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attachmentHeight	= level.getHeight();
22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attachmentFormat	= level.getFormat();
22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (attachment.type == Framebuffer::ATTACHMENTTYPE_RENDERBUFFER)
22143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Renderbuffer* renderbuffer = m_renderbuffers.find(attachment.name);
22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(renderbuffer);
22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attachmentWidth		= renderbuffer->getWidth();
22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attachmentHeight	= renderbuffer->getHeight();
22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			attachmentFormat	= renderbuffer->getFormat();
22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(attachment.type == Framebuffer::ATTACHMENTTYPE_LAST);
22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue; // Skip rest of checks.
22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!hasAttachment && attachmentWidth > 0 && attachmentHeight > 0)
22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			width			= attachmentWidth;
22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			height			= attachmentHeight;
22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			hasAttachment	= true;
22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (attachmentWidth != width || attachmentHeight != height)
22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dimensionsOk = false;
22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Validate attachment point compatibility.
22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (attachmentFormat.order)
22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::R:
22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::RG:
22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::RGB:
22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::RGBA:
22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::sRGB:
22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::sRGBA:
22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (point != Framebuffer::ATTACHMENTPOINT_COLOR0)
22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					attachmentComplete = false;
22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::D:
22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (point != Framebuffer::ATTACHMENTPOINT_DEPTH)
22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					attachmentComplete = false;
22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::S:
22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (point != Framebuffer::ATTACHMENTPOINT_STENCIL)
22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					attachmentComplete = false;
22583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case TextureFormat::DS:
22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (point != Framebuffer::ATTACHMENTPOINT_DEPTH &&
22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					point != Framebuffer::ATTACHMENTPOINT_STENCIL)
22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					attachmentComplete = false;
22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TCU_FAIL("Unsupported attachment channel order");
22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!attachmentComplete)
22723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (!hasAttachment)
22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (!dimensionsOk)
22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return GL_FRAMEBUFFER_COMPLETE;
22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::getFramebufferAttachmentParameteriv (deUint32 target, deUint32 attachment, deUint32 pname, int* params)
22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(target && attachment && pname && params);
22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK(false); // \todo [pyry] Implement
22853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::renderbufferStorage (deUint32 target, deUint32 internalformat, int width, int height)
22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat format = glu::mapGLInternalFormat(internalformat);
22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(target != GL_RENDERBUFFER, GL_INVALID_ENUM, RC_RET_VOID);
22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!m_renderbufferBinding, GL_INVALID_OPERATION, RC_RET_VOID);
22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!deInRange32(width, 0, m_limits.maxRenderbufferSize) ||
22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!deInRange32(height, 0, m_limits.maxRenderbufferSize),
22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_INVALID_OPERATION, RC_RET_VOID);
22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(format.order == TextureFormat::CHANNELORDER_LAST ||
22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				format.type == TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_renderbufferBinding->setStorage(format, (int)width, (int)height);
23003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::renderbufferStorageMultisample (deUint32 target, int samples, deUint32 internalFormat, int width, int height)
23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2012-04-07 pyry] Implement MSAA support.
23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(samples);
23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	renderbufferStorage(target, internalFormat, width, height);
23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::PixelBufferAccess ReferenceContext::getFboAttachment (const rc::Framebuffer& framebuffer, rc::Framebuffer::AttachmentPoint point)
23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Framebuffer::Attachment& attachment = framebuffer.getAttachment(point);
23123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (attachment.type)
23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::ATTACHMENTTYPE_TEXTURE:
23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Texture* texture = m_textures.find(attachment.name);
23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(texture);
23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (texture->getType() == Texture::TYPE_2D)
23213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return dynamic_cast<Texture2D*>(texture)->getLevel(attachment.level);
23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (texture->getType() == Texture::TYPE_CUBE_MAP)
23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return dynamic_cast<TextureCube*>(texture)->getFace(attachment.level, texTargetToFace(attachment.texTarget));
23248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			else if (texture->getType() == Texture::TYPE_2D_ARRAY	||
23258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry					 texture->getType() == Texture::TYPE_3D			||
23268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry					 texture->getType() == Texture::TYPE_CUBE_MAP_ARRAY)
23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
23288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				tcu::PixelBufferAccess level;
23298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
23308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				if (texture->getType() == Texture::TYPE_2D_ARRAY)
23318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry					level = dynamic_cast<Texture2DArray*>(texture)->getLevel(attachment.level);
23328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				else if (texture->getType() == Texture::TYPE_3D)
23338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry					level = dynamic_cast<Texture3D*>(texture)->getLevel(attachment.level);
23348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				else if (texture->getType() == Texture::TYPE_CUBE_MAP_ARRAY)
23358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry					level = dynamic_cast<TextureCubeArray*>(texture)->getLevel(attachment.level);
23363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				void* layerData = static_cast<deUint8*>(level.getDataPtr()) + level.getSlicePitch() * attachment.layer;
23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return tcu::PixelBufferAccess(level.getFormat(), level.getWidth(), level.getHeight(), 1, level.getRowPitch(), 0, layerData);
23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
23423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return nullAccess();
23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case Framebuffer::ATTACHMENTTYPE_RENDERBUFFER:
23463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Renderbuffer* rbo = m_renderbuffers.find(attachment.name);
23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK(rbo);
23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return rbo->getAccess();
23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return nullAccess();
23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst Texture2D& ReferenceContext::getTexture2D (int unitNdx) const
23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TextureUnit& unit = m_textureUnits[unitNdx];
23613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return unit.tex2DBinding ? *unit.tex2DBinding : unit.default2DTex;
23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst TextureCube& ReferenceContext::getTextureCube (int unitNdx) const
23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TextureUnit& unit = m_textureUnits[unitNdx];
23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return unit.texCubeBinding ? *unit.texCubeBinding : unit.defaultCubeTex;
23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isValidBufferTarget (deUint32 target)
23713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (target)
23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ARRAY_BUFFER:
23753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_COPY_READ_BUFFER:
23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_COPY_WRITE_BUFFER:
23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DRAW_INDIRECT_BUFFER:
23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ELEMENT_ARRAY_BUFFER:
23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PIXEL_PACK_BUFFER:
23803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PIXEL_UNPACK_BUFFER:
23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TRANSFORM_FEEDBACK_BUFFER:
23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_UNIFORM_BUFFER:
23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::setBufferBinding (deUint32 target, DataBuffer* buffer)
23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DataBuffer** bindingPoint = DE_NULL;
23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VertexArray* vertexArrayObject = (m_vertexArrayBinding) ? (m_vertexArrayBinding) : (&m_clientVertexArray);
23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (target)
23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ARRAY_BUFFER:				bindingPoint = &m_arrayBufferBinding;								break;
23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_COPY_READ_BUFFER:			bindingPoint = &m_copyReadBufferBinding;							break;
23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_COPY_WRITE_BUFFER:			bindingPoint = &m_copyWriteBufferBinding;							break;
24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DRAW_INDIRECT_BUFFER:		bindingPoint = &m_drawIndirectBufferBinding;						break;
24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ELEMENT_ARRAY_BUFFER:		bindingPoint = &vertexArrayObject->m_elementArrayBufferBinding;		break;
24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PIXEL_PACK_BUFFER:			bindingPoint = &m_pixelPackBufferBinding;							break;
24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PIXEL_UNPACK_BUFFER:		bindingPoint = &m_pixelUnpackBufferBinding;							break;
24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TRANSFORM_FEEDBACK_BUFFER:	bindingPoint = &m_transformFeedbackBufferBinding;					break;
24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_UNIFORM_BUFFER:				bindingPoint = &m_uniformBufferBinding;								break;
24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (*bindingPoint)
24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffers.releaseReference(*bindingPoint);
24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*bindingPoint = DE_NULL;
24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (buffer)
24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffers.acquireReference(buffer);
24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	*bindingPoint = buffer;
24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24233c827367444ee418f129b2c238299f49d3264554Jarkko PoyryDataBuffer* ReferenceContext::getBufferBinding (deUint32 target) const
24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const VertexArray* vertexArrayObject = (m_vertexArrayBinding) ? (m_vertexArrayBinding) : (&m_clientVertexArray);
24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (target)
24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ARRAY_BUFFER:				return m_arrayBufferBinding;
24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_COPY_READ_BUFFER:			return m_copyReadBufferBinding;
24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_COPY_WRITE_BUFFER:			return m_copyWriteBufferBinding;
24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DRAW_INDIRECT_BUFFER:		return m_drawIndirectBufferBinding;
24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ELEMENT_ARRAY_BUFFER:		return vertexArrayObject->m_elementArrayBufferBinding;
24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PIXEL_PACK_BUFFER:			return m_pixelPackBufferBinding;
24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PIXEL_UNPACK_BUFFER:		return m_pixelUnpackBufferBinding;
24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_TRANSFORM_FEEDBACK_BUFFER:	return m_transformFeedbackBufferBinding;
24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_UNIFORM_BUFFER:				return m_uniformBufferBinding;
24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
24393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::bindBuffer (deUint32 target, deUint32 buffer)
24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidBufferTarget(target), GL_INVALID_ENUM, RC_RET_VOID);
24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::DataBuffer*	bufObj	= DE_NULL;
24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (buffer != 0)
24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bufObj = m_buffers.find(buffer);
24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!bufObj)
24543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bufObj = new DataBuffer(buffer);
24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_buffers.insert(bufObj);
24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setBufferBinding(target, bufObj);
24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::genBuffers (int numBuffers, deUint32* buffers)
24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!buffers, GL_INVALID_VALUE, RC_RET_VOID);
24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < numBuffers; ndx++)
24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buffers[ndx] = m_buffers.allocateName();
24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteBuffers (int numBuffers, const deUint32* buffers)
24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(numBuffers < 0, GL_INVALID_VALUE, RC_RET_VOID);
24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < numBuffers; ndx++)
24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32	buffer	= buffers[ndx];
24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DataBuffer*	bufObj	= DE_NULL;
24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (buffer == 0)
24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bufObj = m_buffers.find(buffer);
24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (bufObj)
24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deleteBuffer(bufObj);
24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteBuffer (DataBuffer* buffer)
24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint32 bindingPoints[] =
24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_ARRAY_BUFFER,
24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_COPY_READ_BUFFER,
24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_COPY_WRITE_BUFFER,
24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_DRAW_INDIRECT_BUFFER,
24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_ELEMENT_ARRAY_BUFFER,
24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_PIXEL_PACK_BUFFER,
25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_PIXEL_UNPACK_BUFFER,
25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_TRANSFORM_FEEDBACK_BUFFER,
25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GL_UNIFORM_BUFFER
25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int bindingNdx = 0; bindingNdx < DE_LENGTH_OF_ARRAY(bindingPoints); bindingNdx++)
25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (getBufferBinding(bindingPoints[bindingNdx]) == buffer)
25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setBufferBinding(bindingPoints[bindingNdx], DE_NULL);
25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<VertexArray*> vertexArrays;
25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_vertexArrays.getAll(vertexArrays);
25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexArrays.push_back(&m_clientVertexArray);
25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (vector<VertexArray*>::iterator i = vertexArrays.begin(); i != vertexArrays.end(); i++)
25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if ((*i)->m_elementArrayBufferBinding == buffer)
25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_buffers.releaseReference(buffer);
25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				(*i)->m_elementArrayBufferBinding = DE_NULL;
25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (size_t vertexAttribNdx = 0; vertexAttribNdx < (*i)->m_arrays.size(); ++vertexAttribNdx)
25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if ((*i)->m_arrays[vertexAttribNdx].bufferBinding == buffer)
25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_buffers.releaseReference(buffer);
25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					(*i)->m_arrays[vertexAttribNdx].bufferDeleted = true;
25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					(*i)->m_arrays[vertexAttribNdx].bufferBinding = DE_NULL;
25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(buffer->getRefCount() == 1);
25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_buffers.releaseReference(buffer);
25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::bufferData (deUint32 target, deIntptr size, const void* data, deUint32 usage)
25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidBufferTarget(target), GL_INVALID_ENUM, RC_RET_VOID);
25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(size < 0, GL_INVALID_VALUE, RC_RET_VOID);
25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(usage);
25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DataBuffer* buffer = getBufferBinding(target);
25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!buffer, GL_INVALID_OPERATION, RC_RET_VOID);
25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((deIntptr)(int)size == size);
25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	buffer->setStorage((int)size);
25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (data)
25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMemcpy(buffer->getData(), data, (int)size);
25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::bufferSubData (deUint32 target, deIntptr offset, deIntptr size, const void* data)
25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidBufferTarget(target), GL_INVALID_ENUM, RC_RET_VOID);
25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(offset < 0 || size < 0, GL_INVALID_VALUE, RC_RET_VOID);
25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DataBuffer* buffer = getBufferBinding(target);
25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!buffer, GL_INVALID_OPERATION, RC_RET_VOID);
25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((int)(offset+size) > buffer->getSize(), GL_INVALID_VALUE, RC_RET_VOID);
25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMemcpy(buffer->getData()+offset, data, (int)size);
25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clearColor (float red, float green, float blue, float alpha)
25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_clearColor = Vec4(de::clamp(red,	0.0f, 1.0f),
25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::clamp(green,	0.0f, 1.0f),
25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::clamp(blue,	0.0f, 1.0f),
25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::clamp(alpha,	0.0f, 1.0f));
25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clearDepthf (float depth)
25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_clearDepth = de::clamp(depth, 0.0f, 1.0f);
25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clearStencil (int stencil)
25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_clearStencil = stencil;
25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::scissor (int x, int y, int width, int height)
25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0 || height < 0, GL_INVALID_VALUE, RC_RET_VOID);
25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_scissorBox = IVec4(x, y, width, height);
25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::enable (deUint32 cap)
25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (cap)
25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_BLEND:					m_blendEnabled				= true;	break;
25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SCISSOR_TEST:			m_scissorEnabled			= true;	break;
25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DEPTH_TEST:				m_depthTestEnabled			= true;	break;
26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_STENCIL_TEST:			m_stencilTestEnabled		= true;	break;
26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_POLYGON_OFFSET_FILL:	m_polygonOffsetFillEnabled	= true;	break;
26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_FRAMEBUFFER_SRGB:
26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isContextTypeGLCore(getType()))
26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_sRGBUpdateEnabled = true;
26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DEPTH_CLAMP:
26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isContextTypeGLCore(getType()))
26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_depthClampEnabled = true;
26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DITHER:
26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Not implemented - just ignored.
26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PRIMITIVE_RESTART_FIXED_INDEX:
26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!glu::isContextTypeGLCore(getType()))
26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_primitiveRestartFixedIndex = true;
26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PRIMITIVE_RESTART:
26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isContextTypeGLCore(getType()))
26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_primitiveRestartSettableIndex = true;
26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::disable (deUint32 cap)
26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (cap)
26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_BLEND:					m_blendEnabled				= false;	break;
26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SCISSOR_TEST:			m_scissorEnabled			= false;	break;
26553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DEPTH_TEST:				m_depthTestEnabled			= false;	break;
26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_STENCIL_TEST:			m_stencilTestEnabled		= false;	break;
26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_POLYGON_OFFSET_FILL:	m_polygonOffsetFillEnabled	= false;	break;
26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_FRAMEBUFFER_SRGB:
26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isContextTypeGLCore(getType()))
26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_sRGBUpdateEnabled = false;
26633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DEPTH_CLAMP:
26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isContextTypeGLCore(getType()))
26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_depthClampEnabled = false;
26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
26733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DITHER:
26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PRIMITIVE_RESTART_FIXED_INDEX:
26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!glu::isContextTypeGLCore(getType()))
26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_primitiveRestartFixedIndex = false;
26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
26853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_PRIMITIVE_RESTART:
26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (glu::isContextTypeGLCore(getType()))
26913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_primitiveRestartSettableIndex = false;
26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
26973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
26993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isValidCompareFunc (deUint32 func)
27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (func)
27073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_NEVER:
27093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LESS:
27103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LEQUAL:
27113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_GREATER:
27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_GEQUAL:
27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_EQUAL:
27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_NOTEQUAL:
27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ALWAYS:
27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
27203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27233c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isValidStencilOp (deUint32 op)
27243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (op)
27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_KEEP:
27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ZERO:
27293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_REPLACE:
27303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_INCR:
27313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_INCR_WRAP:
27323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DECR:
27333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DECR_WRAP:
27343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_INVERT:
27353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
27363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
27383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
27393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::stencilFunc (deUint32 func, int ref, deUint32 mask)
27433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
27453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::stencilFuncSeparate (deUint32 face, deUint32 func, int ref, deUint32 mask)
27483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	setFront	= face == GL_FRONT || face == GL_FRONT_AND_BACK;
27503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	setBack		= face == GL_BACK || face == GL_FRONT_AND_BACK;
27513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidCompareFunc(func), GL_INVALID_ENUM, RC_RET_VOID);
27533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!setFront && !setBack, GL_INVALID_ENUM, RC_RET_VOID);
27543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int type = 0; type < rr::FACETYPE_LAST; ++type)
27563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((type == rr::FACETYPE_FRONT && setFront) ||
27583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(type == rr::FACETYPE_BACK && setBack))
27593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_stencil[type].func	= func;
27613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_stencil[type].ref		= ref;
27623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_stencil[type].opMask	= mask;
27633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::stencilOp (deUint32 sfail, deUint32 dpfail, deUint32 dppass)
27683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stencilOpSeparate(GL_FRONT_AND_BACK, sfail, dpfail, dppass);
27703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::stencilOpSeparate (deUint32 face, deUint32 sfail, deUint32 dpfail, deUint32 dppass)
27733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	setFront	= face == GL_FRONT || face == GL_FRONT_AND_BACK;
27753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	setBack		= face == GL_BACK || face == GL_FRONT_AND_BACK;
27763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidStencilOp(sfail)	||
27783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!isValidStencilOp(dpfail)	||
27793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!isValidStencilOp(dppass),
27803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_INVALID_ENUM, RC_RET_VOID);
27813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!setFront && !setBack, GL_INVALID_ENUM, RC_RET_VOID);
27823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int type = 0; type < rr::FACETYPE_LAST; ++type)
27843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((type == rr::FACETYPE_FRONT && setFront) ||
27863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(type == rr::FACETYPE_BACK && setBack))
27873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
27883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_stencil[type].opStencilFail	= sfail;
27893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_stencil[type].opDepthFail		= dpfail;
27903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_stencil[type].opDepthPass		= dppass;
27913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
27923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::depthFunc (deUint32 func)
27963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidCompareFunc(func), GL_INVALID_ENUM, RC_RET_VOID);
27983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_depthFunc = func;
27993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::depthRangef (float n, float f)
28023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_depthRangeNear = de::clamp(n, 0.0f, 1.0f);
28043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_depthRangeFar = de::clamp(f, 0.0f, 1.0f);
28053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::depthRange (double n, double f)
28083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	depthRangef((float)n, (float)f);
28103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::polygonOffset (float factor, float units)
28133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_polygonOffsetFactor = factor;
28153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_polygonOffsetUnits = units;
28163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::provokingVertex (deUint32 convention)
28193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// only in core
28213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isContextTypeGLCore(getType()));
28223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (convention)
28243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
28253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_FIRST_VERTEX_CONVENTION:	m_provokingFirstVertexConvention = true; break;
28263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_LAST_VERTEX_CONVENTION:		m_provokingFirstVertexConvention = false; break;
28273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
28293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_ERROR_RET(GL_INVALID_ENUM, RC_RET_VOID);
28303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
28313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::primitiveRestartIndex (deUint32 index)
28343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// only in core
28363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(glu::isContextTypeGLCore(getType()));
28373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_primitiveRestartIndex = index;
28383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool isValidBlendEquation (deUint32 mode)
28413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return mode == GL_FUNC_ADD				||
28433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   mode == GL_FUNC_SUBTRACT			||
28443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   mode == GL_FUNC_REVERSE_SUBTRACT	||
28453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   mode == GL_MIN					||
28463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   mode == GL_MAX;
28473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28493c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool isValidBlendFactor (deUint32 factor)
28503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (factor)
28523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
28533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ZERO:
28543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ONE:
28553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SRC_COLOR:
28563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ONE_MINUS_SRC_COLOR:
28573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DST_COLOR:
28583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ONE_MINUS_DST_COLOR:
28593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SRC_ALPHA:
28603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ONE_MINUS_SRC_ALPHA:
28613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_DST_ALPHA:
28623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ONE_MINUS_DST_ALPHA:
28633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_CONSTANT_COLOR:
28643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ONE_MINUS_CONSTANT_COLOR:
28653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_CONSTANT_ALPHA:
28663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_ONE_MINUS_CONSTANT_ALPHA:
28673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_SRC_ALPHA_SATURATE:
28683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
28693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
28713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
28723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
28733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::blendEquation (deUint32 mode)
28763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidBlendEquation(mode), GL_INVALID_ENUM, RC_RET_VOID);
28783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendModeRGB		= mode;
28803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendModeAlpha	= mode;
28813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::blendEquationSeparate (deUint32 modeRGB, deUint32 modeAlpha)
28843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidBlendEquation(modeRGB) ||
28863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!isValidBlendEquation(modeAlpha),
28873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_INVALID_ENUM, RC_RET_VOID);
28883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendModeRGB		= modeRGB;
28903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendModeAlpha	= modeAlpha;
28913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::blendFunc (deUint32 src, deUint32 dst)
28943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidBlendFactor(src) ||
28963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!isValidBlendFactor(dst),
28973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_INVALID_ENUM, RC_RET_VOID);
28983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorSrcRGB		= src;
29003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorSrcAlpha	= src;
29013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorDstRGB		= dst;
29023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorDstAlpha	= dst;
29033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29053c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::blendFuncSeparate (deUint32 srcRGB, deUint32 dstRGB, deUint32 srcAlpha, deUint32 dstAlpha)
29063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!isValidBlendFactor(srcRGB)		||
29083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!isValidBlendFactor(dstRGB)		||
29093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!isValidBlendFactor(srcAlpha)	||
29103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				!isValidBlendFactor(dstAlpha),
29113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_INVALID_ENUM, RC_RET_VOID);
29123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorSrcRGB		= srcRGB;
29143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorSrcAlpha	= srcAlpha;
29153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorDstRGB		= dstRGB;
29163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendFactorDstAlpha	= dstAlpha;
29173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::blendColor (float red, float green, float blue, float alpha)
29203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_blendColor = Vec4(de::clamp(red,	0.0f, 1.0f),
29223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::clamp(green,	0.0f, 1.0f),
29233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::clamp(blue,	0.0f, 1.0f),
29243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						de::clamp(alpha,	0.0f, 1.0f));
29253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::colorMask (deBool r, deBool g, deBool b, deBool a)
29283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_colorMask = tcu::BVec4(!!r, !!g, !!b, !!a);
29303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::depthMask (deBool mask)
29333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_depthMask = !!mask;
29353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::stencilMask (deUint32 mask)
29383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
29403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::stencilMaskSeparate (deUint32 face, deUint32 mask)
29433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	setFront	= face == GL_FRONT || face == GL_FRONT_AND_BACK;
29453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool	setBack		= face == GL_BACK || face == GL_FRONT_AND_BACK;
29463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!setFront && !setBack, GL_INVALID_ENUM, RC_RET_VOID);
29483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (setFront)	m_stencil[rr::FACETYPE_FRONT].writeMask	= mask;
29503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (setBack)	m_stencil[rr::FACETYPE_BACK].writeMask	= mask;
29513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic int getNumStencilBits (const tcu::TextureFormat& format)
29543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (format.order)
29563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::TextureFormat::S:
29583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (format.type)
29593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case tcu::TextureFormat::UNSIGNED_INT8:		return 8;
29613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case tcu::TextureFormat::UNSIGNED_INT16:	return 16;
29623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case tcu::TextureFormat::UNSIGNED_INT32:	return 32;
29633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
29643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
29653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return 0;
29663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case tcu::TextureFormat::DS:
29693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (format.type)
29703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case tcu::TextureFormat::UNSIGNED_INT_24_8:				return 8;
29723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:	return 8;
29733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
29743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
29753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return 0;
29763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
29793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
29803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
29813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29843c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline int maskStencil (int bits, int s) { return s & ((1<<bits)-1); }
29853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline void writeStencilOnly (const rr::MultisamplePixelBufferAccess& access, int s, int x, int y, int stencil, deUint32 writeMask)
29873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int const oldVal = access.raw().getPixelInt(s, x, y).w();
29893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	access.raw().setPixStencil((oldVal & ~writeMask) | (stencil & writeMask), s, x, y);
29903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline void writeDepthOnly (const rr::MultisamplePixelBufferAccess& access, int s, int x, int y, float depth)
29933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	access.raw().setPixDepth(depth, s, x, y);
29953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
29963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29973c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 ReferenceContext::blitResolveMultisampleFramebuffer (deUint32 mask, const IVec4& srcRect, const IVec4& dstRect, bool flipX, bool flipY)
29983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
29993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (mask & GL_COLOR_BUFFER_BIT)
30003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
30013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisampleConstPixelBufferAccess	src			= rr::getSubregion(getReadColorbuffer(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w());
30023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::PixelBufferAccess					dst			= tcu::getSubregion(getDrawColorbuffer().toSinglesampleAccess(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w());
30033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureChannelClass				dstClass	= tcu::getTextureChannelClass(dst.getFormat().type);
30043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool									dstIsFloat	= dstClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT		||
30053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															  dstClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT	||
30063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															  dstClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
300789a729134d6a1880d2b59426dfe14d615381e314Jarkko Pöyry		bool									srcIsSRGB	= tcu::isSRGB(src.raw().getFormat());
300889a729134d6a1880d2b59426dfe14d615381e314Jarkko Pöyry		bool									dstIsSRGB	= tcu::isSRGB(dst.getFormat());
30093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool								convertSRGB	= m_sRGBUpdateEnabled && glu::isContextTypeES(getType());
30103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!convertSRGB)
30123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::ConstPixelBufferAccess	srcRaw	= src.raw();
30143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::TextureFormat			srcFmt	= toNonSRGBFormat(srcRaw.getFormat());
30153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			srcRaw	= tcu::ConstPixelBufferAccess(srcFmt, srcRaw.getWidth(), srcRaw.getHeight(), srcRaw.getDepth(), srcRaw.getRowPitch(), srcRaw.getSlicePitch(), srcRaw.getDataPtr());
30173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			src		= rr::MultisampleConstPixelBufferAccess::fromMultisampleAccess(srcRaw);
30183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst		= tcu::PixelBufferAccess(toNonSRGBFormat(dst.getFormat()), dst.getWidth(), dst.getHeight(), dst.getDepth(), dst.getRowPitch(), dst.getSlicePitch(), dst.getDataPtr());
30203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < dstRect.z(); ++x)
30233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < dstRect.w(); ++y)
30243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int srcX = (flipX) ? (srcRect.z() - x - 1) : (x);
30263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int srcY = (flipY) ? (srcRect.z() - y - 1) : (y);
30273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (dstIsFloat || srcIsSRGB)
30293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
30303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Vec4 p = src.raw().getPixel(0, srcX,srcY);
30313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst.setPixel((dstIsSRGB && convertSRGB) ? tcu::linearToSRGB(p) : p, x, y);
30323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
30333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
30343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				dst.setPixel(src.raw().getPixelInt(0, srcX, srcY), x, y);
30353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
30373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (mask & GL_DEPTH_BUFFER_BIT)
30393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
30403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisampleConstPixelBufferAccess	src	= rr::getSubregion(getReadColorbuffer(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w());
30413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess		dst	= rr::getSubregion(getDrawDepthbuffer(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w());
30423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < dstRect.z(); ++x)
30443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < dstRect.w(); ++y)
30453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int srcX = (flipX) ? (srcRect.z() - x - 1) : (x);
30473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int srcY = (flipY) ? (srcRect.z() - y - 1) : (y);
30483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			writeDepthOnly(dst, 0, x, y, src.raw().getPixel(0, srcX, srcY).x());
30503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
30523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (mask & GL_STENCIL_BUFFER_BIT)
30543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
30553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisampleConstPixelBufferAccess	src	= rr::getSubregion(getReadColorbuffer(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w());
30563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess		dst	= rr::getSubregion(getDrawDepthbuffer(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w());
30573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int x = 0; x < dstRect.z(); ++x)
30593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int y = 0; y < dstRect.w(); ++y)
30603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int srcX = (flipX) ? (srcRect.z() - x - 1) : (x);
30623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int srcY = (flipY) ? (srcRect.z() - y - 1) : (y);
30633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			writeStencilOnly(dst, 0, x, y, src.raw().getPixelInt(0, srcX, srcY).w(), m_stencil[rr::FACETYPE_FRONT].writeMask);
30653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
30673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return GL_NO_ERROR;
30693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
30703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::blitFramebuffer (int srcX0, int srcY0, int srcX1, int srcY1, int dstX0, int dstY0, int dstX1, int dstY1, deUint32 mask, deUint32 filter)
30723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
30733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// p0 in inclusive, p1 exclusive.
30743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Negative width/height means swap.
30753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	swapSrcX	= srcX1 < srcX0;
30763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	swapSrcY	= srcY1 < srcY0;
30773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	swapDstX	= dstX1 < dstX0;
30783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	swapDstY	= dstY1 < dstY0;
30793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		srcW		= de::abs(srcX1-srcX0);
30803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		srcH		= de::abs(srcY1-srcY0);
30813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		dstW		= de::abs(dstX1-dstX0);
30823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		dstH		= de::abs(dstY1-dstY0);
30833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	scale		= srcW != dstW || srcH != dstH;
30843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		srcOriginX	= swapSrcX ? srcX1 : srcX0;
30853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		srcOriginY	= swapSrcY ? srcY1 : srcY0;
30863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		dstOriginX	= swapDstX ? dstX1 : dstX0;
30873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		dstOriginY	= swapDstY ? dstY1 : dstY0;
30883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec4	srcRect		= IVec4(srcOriginX, srcOriginY, srcW, srcH);
30893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec4	dstRect		= IVec4(dstOriginX, dstOriginY, dstW, dstH);
30903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(filter != GL_NEAREST && filter != GL_LINEAR, GL_INVALID_ENUM, RC_RET_VOID);
30923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((mask & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) != 0 && filter != GL_NEAREST, GL_INVALID_OPERATION, RC_RET_VOID);
30933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Validate that both targets are complete.
30953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE ||
30963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				checkFramebufferStatus(GL_READ_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_OPERATION, RC_RET_VOID);
30973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check samples count is valid
30993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(getDrawColorbuffer().getNumSamples() != 1, GL_INVALID_OPERATION, RC_RET_VOID);
31003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check size restrictions of multisampled case
31023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (getReadColorbuffer().getNumSamples() != 1)
31033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
31043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Src and Dst rect dimensions must be the same
31053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(srcW != dstW || srcH != dstH, GL_INVALID_OPERATION, RC_RET_VOID);
31063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Framebuffer formats must match
31083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mask & GL_COLOR_BUFFER_BIT)		RC_IF_ERROR(getReadColorbuffer().raw().getFormat()   != getDrawColorbuffer().raw().getFormat(),   GL_INVALID_OPERATION, RC_RET_VOID);
31093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mask & GL_DEPTH_BUFFER_BIT)		RC_IF_ERROR(getReadDepthbuffer().raw().getFormat()   != getDrawDepthbuffer().raw().getFormat(),   GL_INVALID_OPERATION, RC_RET_VOID);
31103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mask & GL_STENCIL_BUFFER_BIT)	RC_IF_ERROR(getReadStencilbuffer().raw().getFormat() != getDrawStencilbuffer().raw().getFormat(), GL_INVALID_OPERATION, RC_RET_VOID);
31113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
31123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute actual source rect.
31143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	srcRect = (mask & GL_COLOR_BUFFER_BIT)		? intersect(srcRect, getBufferRect(getReadColorbuffer()))	: srcRect;
31153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	srcRect = (mask & GL_DEPTH_BUFFER_BIT)		? intersect(srcRect, getBufferRect(getReadDepthbuffer()))	: srcRect;
31163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	srcRect = (mask & GL_STENCIL_BUFFER_BIT)	? intersect(srcRect, getBufferRect(getReadStencilbuffer()))	: srcRect;
31173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compute destination rect.
31193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dstRect = (mask & GL_COLOR_BUFFER_BIT)		? intersect(dstRect, getBufferRect(getDrawColorbuffer()))	: dstRect;
31203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dstRect = (mask & GL_DEPTH_BUFFER_BIT)		? intersect(dstRect, getBufferRect(getDrawDepthbuffer()))	: dstRect;
31213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dstRect = (mask & GL_STENCIL_BUFFER_BIT)	? intersect(dstRect, getBufferRect(getDrawStencilbuffer()))	: dstRect;
31223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	dstRect = m_scissorEnabled					? intersect(dstRect, m_scissorBox)							: dstRect;
31233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isEmpty(srcRect) || isEmpty(dstRect))
31253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return; // Don't attempt copy.
31263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Multisampled read buffer is a special case
31283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (getReadColorbuffer().getNumSamples() != 1)
31293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
31303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 error = blitResolveMultisampleFramebuffer(mask, srcRect, dstRect, swapSrcX ^ swapDstX, swapSrcY ^ swapDstY);
31313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (error != GL_NO_ERROR)
31333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(error);
31343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
31363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
31373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31383c827367444ee418f129b2c238299f49d3264554Jarkko 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
31393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Coordinate transformation:
31413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Dst offset space -> dst rectangle space -> src rectangle space -> src offset space.
31423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Mat3 transform = tcu::translationMatrix(Vec2((float)(srcX0 - srcRect.x()), (float)(srcY0 - srcRect.y())))
31433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						* tcu::Mat3(Vec3((float)(srcX1-srcX0) / (float)(dstX1-dstX0),
31443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 (float)(srcY1-srcY0) / (float)(dstY1-dstY0),
31453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										 1.0f))
31463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						* tcu::translationMatrix(Vec2((float)(dstRect.x() - dstX0), (float)(dstRect.y() - dstY0)));
31473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (mask & GL_COLOR_BUFFER_BIT)
31493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
31503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::ConstPixelBufferAccess		src			= tcu::getSubregion(getReadColorbuffer().toSinglesampleAccess(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w());
31513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::PixelBufferAccess			dst			= tcu::getSubregion(getDrawColorbuffer().toSinglesampleAccess(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w());
31523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureChannelClass		dstClass	= tcu::getTextureChannelClass(dst.getFormat().type);
31533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool							dstIsFloat	= dstClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT		||
31543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													  dstClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT	||
31553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													  dstClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT;
31563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Sampler::FilterMode		sFilter		= (scale && filter == GL_LINEAR) ? tcu::Sampler::LINEAR : tcu::Sampler::NEAREST;
31573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Sampler					sampler		(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
31583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 sFilter, sFilter, 0.0f /* lod threshold */, false /* non-normalized coords */);
315989a729134d6a1880d2b59426dfe14d615381e314Jarkko Pöyry		bool							srcIsSRGB	= tcu::isSRGB(src.getFormat());
316089a729134d6a1880d2b59426dfe14d615381e314Jarkko Pöyry		bool							dstIsSRGB	= tcu::isSRGB(dst.getFormat());
31613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool						convertSRGB	= m_sRGBUpdateEnabled && glu::isContextTypeES(getType());
31623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!convertSRGB)
31643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
31653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			src	= tcu::ConstPixelBufferAccess	(toNonSRGBFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth(), src.getRowPitch(), src.getSlicePitch(), src.getDataPtr());
31663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst	= tcu::PixelBufferAccess		(toNonSRGBFormat(dst.getFormat()), dst.getWidth(), dst.getHeight(), dst.getDepth(), dst.getRowPitch(), dst.getSlicePitch(), dst.getDataPtr());
31673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
31683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note We don't check for unsupported conversions, unlike spec requires.
31703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int yo = 0; yo < dstRect.w(); yo++)
31723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
31733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int xo = 0; xo < dstRect.z(); xo++)
31743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
31753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	dX	= (float)xo + 0.5f;
31763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	dY	= (float)yo + 0.5f;
31773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \note Only affine part is used.
31793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	sX	= transform(0, 0)*dX + transform(0, 1)*dY + transform(0, 2);
31803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	sY	= transform(1, 0)*dX + transform(1, 1)*dY + transform(1, 2);
31813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// do not copy pixels outside the modified source region (modified by buffer intersection)
31833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (sX < 0.0f || sX >= (float)srcRect.z() ||
31843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					sY < 0.0f || sY >= (float)srcRect.w())
31853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
31863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (dstIsFloat || srcIsSRGB || filter == tcu::Sampler::LINEAR)
31883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
31893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					Vec4 p = src.sample2D(sampler, sampler.minFilter, sX, sY, 0);
31903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					dst.setPixel((dstIsSRGB && convertSRGB) ? tcu::linearToSRGB(p) : p, xo, yo);
31913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
31923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
31933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					dst.setPixel(src.getPixelInt(deFloorFloatToInt32(sX), deFloorFloatToInt32(sY)), xo, yo);
31943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
31953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
31963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
31973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((mask & GL_DEPTH_BUFFER_BIT) && m_depthMask)
31993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
32003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisampleConstPixelBufferAccess	src		= rr::getSubregion(getReadDepthbuffer(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w());
32013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess		dst		= rr::getSubregion(getDrawDepthbuffer(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w());
32023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int yo = 0; yo < dstRect.w(); yo++)
32043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
32053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int xo = 0; xo < dstRect.z(); xo++)
32063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
32073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int sampleNdx = 0; // multisample read buffer case is already handled
32083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	dX	= (float)xo + 0.5f;
32103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	dY	= (float)yo + 0.5f;
32113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	sX	= transform(0, 0)*dX + transform(0, 1)*dY + transform(0, 2);
32123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	sY	= transform(1, 0)*dX + transform(1, 1)*dY + transform(1, 2);
32133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				writeDepthOnly(dst, sampleNdx, xo, yo, src.raw().getPixel(sampleNdx, deFloorFloatToInt32(sX), deFloorFloatToInt32(sY)).x());
32153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
32163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
32173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
32183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (mask & GL_STENCIL_BUFFER_BIT)
32203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
32213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisampleConstPixelBufferAccess	src		= rr::getSubregion(getReadStencilbuffer(), srcRect.x(), srcRect.y(), srcRect.z(), srcRect.w());
32223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess		dst		= rr::getSubregion(getDrawStencilbuffer(), dstRect.x(), dstRect.y(), dstRect.z(), dstRect.w());
32233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int yo = 0; yo < dstRect.w(); yo++)
32253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
32263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int xo = 0; xo < dstRect.z(); xo++)
32273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
32283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int sampleNdx = 0; // multisample read buffer case is already handled
32293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	dX	= (float)xo + 0.5f;
32313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	dY	= (float)yo + 0.5f;
32323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	sX	= transform(0, 0)*dX + transform(0, 1)*dY + transform(0, 2);
32333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	sY	= transform(1, 0)*dX + transform(1, 1)*dY + transform(1, 2);
32343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				writeStencilOnly(dst, sampleNdx, xo, yo, src.raw().getPixelInt(sampleNdx, deFloorFloatToInt32(sX), deFloorFloatToInt32(sY)).w(), m_stencil[rr::FACETYPE_FRONT].writeMask);
32363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
32373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
32383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
32393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
32403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::invalidateSubFramebuffer (deUint32 target, int numAttachments, const deUint32* attachments, int x, int y, int width, int height)
32423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
32433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(target != GL_FRAMEBUFFER, GL_INVALID_ENUM, RC_RET_VOID);
32443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((numAttachments < 0) || (numAttachments > 1 && attachments == DE_NULL), GL_INVALID_VALUE, RC_RET_VOID);
32453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(width < 0 || height < 0, GL_INVALID_VALUE, RC_RET_VOID);
32463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2012-07-17 pyry] Support multiple color attachments.
32483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec4		colorClearValue		(0.0f);
32503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		depthClearValue		= 1.0f;
32513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		stencilClearValue	= 0;
32523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool			isFboBound			= m_drawFramebufferBinding != DE_NULL;
32543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool			discardBuffers[3]	= { false, false, false }; // Color, depth, stencil
32553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int attNdx = 0; attNdx < numAttachments; attNdx++)
32573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
32583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool	isColor			= attachments[attNdx] == (isFboBound ? GL_COLOR_ATTACHMENT0		: GL_COLOR);
32593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool	isDepth			= attachments[attNdx] == (isFboBound ? GL_DEPTH_ATTACHMENT		: GL_DEPTH);
32603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool	isStencil		= attachments[attNdx] == (isFboBound ? GL_STENCIL_ATTACHMENT	: GL_STENCIL);
32613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool	isDepthStencil	= isFboBound && attachments[attNdx] == GL_DEPTH_STENCIL_ATTACHMENT;
32623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(!isColor && !isDepth && !isStencil && !isDepthStencil, GL_INVALID_VALUE, RC_RET_VOID);
32643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isColor)						discardBuffers[0] = true;
32663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isDepth || isDepthStencil)		discardBuffers[1] = true;
32673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isStencil || isDepthStencil)	discardBuffers[2] = true;
32683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
32693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < 3; ndx++)
32713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
32723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!discardBuffers[ndx])
32733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
32743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								isColor					= ndx == 0;
32763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								isDepth					= ndx == 1;
32773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								isStencil				= ndx == 2;
32783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess	buf						= isColor ? getDrawColorbuffer() :
32793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	  isDepth ? getDrawDepthbuffer() :
32803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				getDrawStencilbuffer();
32813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isEmpty(buf))
32833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
32843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::IVec4							area					= intersect(tcu::IVec4(0, 0, buf.raw().getHeight(), buf.raw().getDepth()), tcu::IVec4(x, y, width, height));
32863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess	access					= rr::getSubregion(buf, area.x(), area.y(), area.z(), area.w());
32873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								isSharedDepthStencil	= access.raw().getFormat().order == tcu::TextureFormat::DS;
32883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
32893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isSharedDepthStencil)
32903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
32913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int yo = 0; yo < access.raw().getDepth(); yo++)
32923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
32933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int xo = 0; xo < access.raw().getHeight(); xo++)
32943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
32953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int s = 0; s < access.getNumSamples(); s++)
32963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
32973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						if (isDepth)
32983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							writeDepthOnly(access, s, xo, yo, depthClearValue);
32993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						else if (isStencil)
33003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							writeStencilOnly(access, s, xo, yo, stencilClearValue, 0xffffffffu);
33013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
33023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
33033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
33043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
33053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
33063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
33073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isColor)
33083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::clear(access, colorClearValue);
33093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (isDepth)
33103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::clear(access, tcu::Vec4(depthClearValue));
33113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (isStencil)
33123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::clear(access, tcu::IVec4(stencilClearValue));
33133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
33143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::invalidateFramebuffer (deUint32 target, int numAttachments, const deUint32* attachments)
33183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [2012-07-17 pyry] Support multiple color attachments.
33203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisampleConstPixelBufferAccess	colorBuf0	= getDrawColorbuffer();
33213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisampleConstPixelBufferAccess	depthBuf	= getDrawDepthbuffer();
33223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisampleConstPixelBufferAccess	stencilBuf	= getDrawStencilbuffer();
33233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int										width		= 0;
33243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int										height		= 0;
33253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	width = de::max(width, colorBuf0.raw().getHeight());
33273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	width = de::max(width, depthBuf.raw().getHeight());
33283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	width = de::max(width, stencilBuf.raw().getHeight());
33293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	height = de::max(height, colorBuf0.raw().getDepth());
33313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	height = de::max(height, depthBuf.raw().getDepth());
33323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	height = de::max(height, stencilBuf.raw().getDepth());
33333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	invalidateSubFramebuffer(target, numAttachments, attachments, 0, 0, width, height);
33353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
33363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clear (deUint32 buffers)
33383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
33393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((buffers & ~(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) != 0, GL_INVALID_VALUE, RC_RET_VOID);
33403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisamplePixelBufferAccess	colorBuf0	= getDrawColorbuffer();
33423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisamplePixelBufferAccess	depthBuf	= getDrawDepthbuffer();
33433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisamplePixelBufferAccess	stencilBuf	= getDrawStencilbuffer();
33443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool								hasColor0	= !isEmpty(colorBuf0);
33453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool								hasDepth	= !isEmpty(depthBuf);
33463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool								hasStencil	= !isEmpty(stencilBuf);
33473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec4								baseArea	= m_scissorEnabled ? m_scissorBox : IVec4(0, 0, 0x7fffffff, 0x7fffffff);
33483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasColor0 && (buffers & GL_COLOR_BUFFER_BIT) != 0)
33503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec4								colorArea	= intersect(baseArea, getBufferRect(colorBuf0));
33523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(colorBuf0, colorArea.x(), colorArea.y(), colorArea.z(), colorArea.w());
335389a729134d6a1880d2b59426dfe14d615381e314Jarkko Pöyry		bool								isSRGB		= tcu::isSRGB(colorBuf0.raw().getFormat());
33543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec4								c			= (isSRGB && m_sRGBUpdateEnabled) ? tcu::linearToSRGB(m_clearColor) : m_clearColor;
33553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskUsed	= !m_colorMask[0] || !m_colorMask[1] || !m_colorMask[2] || !m_colorMask[3];
33563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskZero	= !m_colorMask[0] && !m_colorMask[1] && !m_colorMask[2] && !m_colorMask[3];
33573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!maskUsed)
33593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::clear(access, c);
33603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (!maskZero)
33613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
33623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < access.raw().getDepth(); y++)
33633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int x = 0; x < access.raw().getHeight(); x++)
33643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int s = 0; s < access.getNumSamples(); s++)
33653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						access.raw().setPixel(tcu::select(c, access.raw().getPixel(s, x, y), m_colorMask), s, x, y);
33663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
33673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// else all channels masked out
33683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasDepth && (buffers & GL_DEPTH_BUFFER_BIT) != 0 && m_depthMask)
33713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
33723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec4								depthArea				= intersect(baseArea, getBufferRect(depthBuf));
33733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess	access					= rr::getSubregion(depthBuf, depthArea.x(), depthArea.y(), depthArea.z(), depthArea.w());
33743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								isSharedDepthStencil	= depthBuf.raw().getFormat().order != tcu::TextureFormat::D;
33753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isSharedDepthStencil)
33773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
33783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Slow path where stencil is masked out in write.
33793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < access.raw().getDepth(); y++)
33803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int x = 0; x < access.raw().getHeight(); x++)
33813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int s = 0; s < access.getNumSamples(); s++)
33823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						writeDepthOnly(access, s, x, y, m_clearDepth);
33833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
33843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
33853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
33863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Fast path.
33873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						pixelSize		= access.raw().getFormat().getPixelSize();
33883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::vector<deUint8>	row				(access.raw().getWidth()*access.raw().getHeight()*pixelSize);
33893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::PixelBufferAccess	rowAccess		(depthBuf.raw().getFormat(), access.raw().getWidth(), access.raw().getHeight(), 1, &row[0]);
33903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < rowAccess.getHeight(); y++)
33923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int x = 0; x < rowAccess.getWidth(); x++)
33933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					rowAccess.setPixel(tcu::Vec4(m_clearDepth), x, y);
33943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
33953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < access.raw().getDepth(); y++)
33963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deMemcpy((deUint8*)access.raw().getDataPtr() + access.raw().getSlicePitch()*y, &row[0], (int)row.size());
33973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
33983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
33993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasStencil && (buffers & GL_STENCIL_BUFFER_BIT) != 0)
34013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
34023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		IVec4								stencilArea				= intersect(baseArea, getBufferRect(stencilBuf));
34033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess	access					= rr::getSubregion(stencilBuf, stencilArea.x(), stencilArea.y(), stencilArea.z(), stencilArea.w());
34043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int									stencilBits				= getNumStencilBits(stencilBuf.raw().getFormat());
34053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int									stencil					= maskStencil(stencilBits, m_clearStencil);
34063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								isSharedDepthStencil	= stencilBuf.raw().getFormat().order != tcu::TextureFormat::S;
34073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (isSharedDepthStencil || ((m_stencil[rr::FACETYPE_FRONT].writeMask & ((1u<<stencilBits)-1u)) != ((1u<<stencilBits)-1u)))
34093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
34103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Slow path where depth or stencil is masked out in write.
34113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < access.raw().getDepth(); y++)
34123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int x = 0; x < access.raw().getHeight(); x++)
34133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int s = 0; s < access.getNumSamples(); s++)
34143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						writeStencilOnly(access, s, x, y, stencil, m_stencil[rr::FACETYPE_FRONT].writeMask);
34153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
34163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
34173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
34183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Fast path.
34193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int						pixelSize		= access.raw().getFormat().getPixelSize();
34203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			std::vector<deUint8>	row				(access.raw().getWidth()*access.raw().getHeight()*pixelSize);
34213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::PixelBufferAccess	rowAccess		(stencilBuf.raw().getFormat(), access.raw().getWidth(), access.raw().getHeight(), 1, &row[0]);
34223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < rowAccess.getHeight(); y++)
34243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int x = 0; x < rowAccess.getWidth(); x++)
34253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					rowAccess.setPixel(tcu::IVec4(stencil), x, y);
34263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < access.raw().getDepth(); y++)
34283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				deMemcpy((deUint8*)access.raw().getDataPtr() + access.raw().getSlicePitch()*y, &row[0], (int)row.size());
34293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
34303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
34313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clearBufferiv (deUint32 buffer, int drawbuffer, const int* value)
34343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(buffer != GL_COLOR && buffer != GL_STENCIL, GL_INVALID_ENUM, RC_RET_VOID);
34363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(drawbuffer != 0, GL_INVALID_VALUE, RC_RET_VOID); // \todo [2012-04-06 pyry] MRT support.
34373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec4 baseArea = m_scissorEnabled ? m_scissorBox : IVec4(0, 0, 0x7fffffff, 0x7fffffff);
34393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (buffer == GL_COLOR)
34413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
34423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess	colorBuf	= getDrawColorbuffer();
34433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskUsed	= !m_colorMask[0] || !m_colorMask[1] || !m_colorMask[2] || !m_colorMask[3];
34443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskZero	= !m_colorMask[0] && !m_colorMask[1] && !m_colorMask[2] && !m_colorMask[3];
34453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!isEmpty(colorBuf) && !maskZero)
34473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
34483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			IVec4								area		= intersect(baseArea, getBufferRect(colorBuf));
34493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(colorBuf, area.x(), area.y(), area.z(), area.w());
34503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			IVec4								color		(value[0], value[1], value[2], value[3]);
34513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!maskUsed)
34533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::clear(access, color);
34543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
34553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
34563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int y = 0; y < access.raw().getDepth(); y++)
34573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int x = 0; x < access.raw().getHeight(); x++)
34583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int s = 0; s < access.getNumSamples(); s++)
34593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							access.raw().setPixel(tcu::select(color, access.raw().getPixelInt(s, x, y), m_colorMask), s, x, y);
34603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
34613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
34623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
34633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
34643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
34653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_INTERNAL(buffer == GL_STENCIL);
34663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess stencilBuf = getDrawStencilbuffer();
34683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!isEmpty(stencilBuf) && m_stencil[rr::FACETYPE_FRONT].writeMask != 0)
34703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
34713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			IVec4								area		= intersect(baseArea, getBufferRect(stencilBuf));
34723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(stencilBuf, area.x(), area.y(), area.z(), area.w());
34733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int									stencil		= value[0];
34743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < access.raw().getDepth(); y++)
34763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int x = 0; x < access.raw().getHeight(); x++)
34773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int s = 0; s < access.getNumSamples(); s++)
34783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						writeStencilOnly(access, s, x, y, stencil, m_stencil[rr::FACETYPE_FRONT].writeMask);
34793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
34803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
34813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
34823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clearBufferfv (deUint32 buffer, int drawbuffer, const float* value)
34843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
34853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(buffer != GL_COLOR && buffer != GL_DEPTH, GL_INVALID_ENUM, RC_RET_VOID);
34863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(drawbuffer != 0, GL_INVALID_VALUE, RC_RET_VOID); // \todo [2012-04-06 pyry] MRT support.
34873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec4 baseArea = m_scissorEnabled ? m_scissorBox : IVec4(0, 0, 0x7fffffff, 0x7fffffff);
34893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (buffer == GL_COLOR)
34913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
34923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess	colorBuf	= getDrawColorbuffer();
34933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskUsed	= !m_colorMask[0] || !m_colorMask[1] || !m_colorMask[2] || !m_colorMask[3];
34943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskZero	= !m_colorMask[0] && !m_colorMask[1] && !m_colorMask[2] && !m_colorMask[3];
34953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
34963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!isEmpty(colorBuf) && !maskZero)
34973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
34983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			IVec4								area		= intersect(baseArea, getBufferRect(colorBuf));
34993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(colorBuf, area.x(), area.y(), area.z(), area.w());
35003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Vec4								color		(value[0], value[1], value[2], value[3]);
35013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
350289a729134d6a1880d2b59426dfe14d615381e314Jarkko Pöyry			if (m_sRGBUpdateEnabled && tcu::isSRGB(access.raw().getFormat()))
35033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				color = tcu::linearToSRGB(color);
35043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!maskUsed)
35063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::clear(access, color);
35073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
35083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
35093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int y = 0; y < access.raw().getDepth(); y++)
35103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int x = 0; x < access.raw().getHeight(); x++)
35113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int s = 0; s < access.getNumSamples(); s++)
35123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							access.raw().setPixel(tcu::select(color, access.raw().getPixel(s, x, y), m_colorMask), s, x, y);
35133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
35143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
35153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
35163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
35173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
35183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_CHECK_INTERNAL(buffer == GL_DEPTH);
35193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess depthBuf = getDrawDepthbuffer();
35213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!isEmpty(depthBuf) && m_depthMask)
35233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
35243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			IVec4								area		= intersect(baseArea, getBufferRect(depthBuf));
35253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(depthBuf, area.x(), area.y(), area.z(), area.w());
35263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float								depth		= value[0];
35273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int y = 0; y < access.raw().getDepth(); y++)
35293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int x = 0; x < access.raw().getHeight(); x++)
35303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int s = 0; s < access.getNumSamples(); s++)
35313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						writeDepthOnly(access, s, x, y, depth);
35323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
35333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
35343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clearBufferuiv (deUint32 buffer, int drawbuffer, const deUint32* value)
35373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(buffer != GL_COLOR, GL_INVALID_ENUM, RC_RET_VOID);
35393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(drawbuffer != 0, GL_INVALID_VALUE, RC_RET_VOID); // \todo [2012-04-06 pyry] MRT support.
35403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec4 baseArea = m_scissorEnabled ? m_scissorBox : IVec4(0, 0, 0x7fffffff, 0x7fffffff);
35423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_INTERNAL(buffer == GL_COLOR);
35443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
35453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rr::MultisamplePixelBufferAccess	colorBuf	= getDrawColorbuffer();
35463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskUsed	= !m_colorMask[0] || !m_colorMask[1] || !m_colorMask[2] || !m_colorMask[3];
35473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool								maskZero	= !m_colorMask[0] && !m_colorMask[1] && !m_colorMask[2] && !m_colorMask[3];
35483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!isEmpty(colorBuf) && !maskZero)
35503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
35513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			IVec4								area		= intersect(baseArea, getBufferRect(colorBuf));
35523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			rr::MultisamplePixelBufferAccess	access		= rr::getSubregion(colorBuf, area.x(), area.y(), area.z(), area.w());
35533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::UVec4							color		(value[0], value[1], value[2], value[3]);
35543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!maskUsed)
35563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rr::clear(access, color.asInt());
35573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
35583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
35593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int y = 0; y < access.raw().getDepth(); y++)
35603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int x = 0; x < access.raw().getHeight(); x++)
35613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int s = 0; s < access.getNumSamples(); s++)
35623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							access.raw().setPixel(tcu::select(color, access.raw().getPixelUint(s, x, y), m_colorMask), s, x, y);
35633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
35643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
35653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
35663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::clearBufferfi (deUint32 buffer, int drawbuffer, float depth, int stencil)
35693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(buffer != GL_DEPTH_STENCIL, GL_INVALID_ENUM, RC_RET_VOID);
35713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clearBufferfv(GL_DEPTH, drawbuffer, &depth);
35723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clearBufferiv(GL_STENCIL, drawbuffer, &stencil);
35733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::bindVertexArray (deUint32 array)
35763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
35773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::VertexArray* vertexArrayObject = DE_NULL;
35783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (array != 0)
35803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
35813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexArrayObject = m_vertexArrays.find(array);
35823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!vertexArrayObject)
35833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
35843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vertexArrayObject = new rc::VertexArray(array, m_limits.maxVertexAttribs);
35853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_vertexArrays.insert(vertexArrayObject);
35863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
35873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
35883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create new references
35903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (vertexArrayObject)
35913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_vertexArrays.acquireReference(vertexArrayObject);
35923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Remove old references
35943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_vertexArrayBinding)
35953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_vertexArrays.releaseReference(m_vertexArrayBinding);
35963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
35973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertexArrayBinding = vertexArrayObject;
35983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
35993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::genVertexArrays (int numArrays, deUint32* vertexArrays)
36013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!vertexArrays, GL_INVALID_VALUE, RC_RET_VOID);
36033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < numArrays; ndx++)
36053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexArrays[ndx] = m_vertexArrays.allocateName();
36063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteVertexArrays (int numArrays, const deUint32* vertexArrays)
36093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numArrays; i++)
36113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
36123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		name		= vertexArrays[i];
36133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VertexArray*	vertexArray	= name ? m_vertexArrays.find(name) : DE_NULL;
36143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vertexArray)
36163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deleteVertexArray(vertexArray);
36173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
36183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttribPointer (deUint32 index, int rawSize, deUint32 type, deBool normalized, int stride, const void *pointer)
36213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool allowBGRA	= !glu::isContextTypeES(getType());
36233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int effectiveSize	= (allowBGRA && rawSize == GL_BGRA) ? (4) : (rawSize);
36243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
36263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(effectiveSize <= 0 || effectiveSize > 4, GL_INVALID_VALUE, RC_RET_VOID);
36273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(type != GL_BYTE					&&	type != GL_UNSIGNED_BYTE	&&
36283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_SHORT				&&	type != GL_UNSIGNED_SHORT	&&
36293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_INT					&&	type != GL_UNSIGNED_INT		&&
36303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_FIXED				&&	type != GL_DOUBLE			&&
36313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_FLOAT				&&	type != GL_HALF_FLOAT		&&
36323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_INT_2_10_10_10_REV	&&	type != GL_UNSIGNED_INT_2_10_10_10_REV, GL_INVALID_ENUM, RC_RET_VOID);
36333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(normalized != GL_TRUE && normalized != GL_FALSE, GL_INVALID_ENUM, RC_RET_VOID);
36343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(stride < 0, GL_INVALID_VALUE, RC_RET_VOID);
36353c827367444ee418f129b2c238299f49d3264554Jarkko 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);
36363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(m_vertexArrayBinding != DE_NULL && m_arrayBufferBinding == DE_NULL && pointer != DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
36373c827367444ee418f129b2c238299f49d3264554Jarkko 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);
36383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(allowBGRA && rawSize == GL_BGRA && normalized == GL_FALSE, GL_INVALID_OPERATION, RC_RET_VOID);
36393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
36413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].size			= rawSize;
36433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].stride			= stride;
36443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].type			= type;
36453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].normalized		= normalized == GL_TRUE;
36463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].integer			= false;
36473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].pointer			= pointer;
36483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// acquire new reference
36503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_arrayBufferBinding)
36513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffers.acquireReference(m_arrayBufferBinding);
36523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// release old reference
36543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (vao.m_arrays[index].bufferBinding)
36553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffers.releaseReference(vao.m_arrays[index].bufferBinding);
36563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].bufferDeleted	= false;
36583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].bufferBinding	= m_arrayBufferBinding;
36593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttribIPointer (deUint32 index, int size, deUint32 type, int stride, const void *pointer)
36623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
36643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(size <= 0 || size > 4, GL_INVALID_VALUE, RC_RET_VOID);
36653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(type != GL_BYTE					&&	type != GL_UNSIGNED_BYTE	&&
36663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_SHORT				&&	type != GL_UNSIGNED_SHORT	&&
36673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_INT					&&	type != GL_UNSIGNED_INT, GL_INVALID_ENUM, RC_RET_VOID);
36683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(stride < 0, GL_INVALID_VALUE, RC_RET_VOID);
36693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(m_vertexArrayBinding != DE_NULL && m_arrayBufferBinding == DE_NULL && pointer != DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
36703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
36723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].size			= size;
36743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].stride			= stride;
36753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].type			= type;
36763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].normalized		= false;
36773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].integer			= true;
36783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].pointer			= pointer;
36793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// acquire new reference
36813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_arrayBufferBinding)
36823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffers.acquireReference(m_arrayBufferBinding);
36833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// release old reference
36853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (vao.m_arrays[index].bufferBinding)
36863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffers.releaseReference(vao.m_arrays[index].bufferBinding);
36873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].bufferDeleted	= false;
36893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].bufferBinding	= m_arrayBufferBinding;
36903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::enableVertexAttribArray (deUint32 index)
36933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
36943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
36953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
36963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
36973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].enabled = true;
36983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
36993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::disableVertexAttribArray (deUint32 index)
37013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
37033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
37053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].enabled = false;
37063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttribDivisor (deUint32 index, deUint32 divisor)
37093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
37113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
37133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vao.m_arrays[index].divisor = divisor;
37143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttrib1f (deUint32 index, float x)
37173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
37193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentAttribs[index] = rr::GenericVec4(tcu::Vec4(x, 0, 0, 1));
37213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttrib2f (deUint32 index, float x, float y)
37243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
37263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentAttribs[index] = rr::GenericVec4(tcu::Vec4(x, y, 0, 1));
37283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttrib3f (deUint32 index, float x, float y, float z)
37313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
37333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentAttribs[index] = rr::GenericVec4(tcu::Vec4(x, y, z, 1));
37353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttrib4f (deUint32 index, float x, float y, float z, float w)
37383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
37403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentAttribs[index] = rr::GenericVec4(tcu::Vec4(x, y, z, w));
37423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttribI4i (deUint32 index, deInt32 x, deInt32 y, deInt32 z, deInt32 w)
37453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
37473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentAttribs[index] = rr::GenericVec4(tcu::IVec4(x, y, z, w));
37493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::vertexAttribI4ui (deUint32 index, deUint32 x, deUint32 y, deUint32 z, deUint32 w)
37523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(index >= (deUint32)m_limits.maxVertexAttribs, GL_INVALID_VALUE, RC_RET_VOID);
37543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentAttribs[index] = rr::GenericVec4(tcu::UVec4(x, y, z, w));
37563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37583c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeInt32 ReferenceContext::getAttribLocation (deUint32 program, const char *name)
37593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderProgramObjectContainer* shaderProg = m_programs.find(program);
37613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(shaderProg == DE_NULL, GL_INVALID_OPERATION, -1);
37633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (name)
37653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
37663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		std::string nameString(name);
37673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (size_t ndx = 0; ndx < shaderProg->m_program->m_attributeNames.size(); ++ndx)
37693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (shaderProg->m_program->m_attributeNames[ndx] == nameString)
37703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return (int)ndx;
37713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
37723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return -1;
37743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniformv (deInt32 location, glu::DataType type, deInt32 count, const void* 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(uniforms[location].type != type, GL_INVALID_OPERATION, RC_RET_VOID);
37873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(count != 1, GL_INVALID_OPERATION, RC_RET_VOID); // \todo [2013-12-13 pyry] Array uniforms.
37883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
37903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int scalarSize = glu::getDataTypeScalarSize(type);
37913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(scalarSize*sizeof(deUint32) <= sizeof(uniforms[location].value));
37923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deMemcpy(&uniforms[location].value, v, scalarSize*(int)sizeof(deUint32));
37933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
37943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
37953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
37963c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform1iv (deInt32 location, deInt32 count, const deInt32* v)
37973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
37983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(m_currentProgram == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
37993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<sglr::UniformSlot>& uniforms = m_currentProgram->m_program->m_uniforms;
38013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (location == -1)
38033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
38043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(location < 0 || (size_t)location >= uniforms.size(), GL_INVALID_OPERATION, RC_RET_VOID);
38063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(count != 1, GL_INVALID_OPERATION, RC_RET_VOID); // \todo [2013-12-13 pyry] Array uniforms.
38073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (uniforms[location].type)
38093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
38103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT:		uniforms[location].value.i = *v;	return;
38113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note texture unit is stored to value
38133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D:
38143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_2D:
38153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_2D:
38163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_CUBE:
38173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_CUBE:
38183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_CUBE:
38193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_2D_ARRAY:
38203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
38213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_2D_ARRAY:
38223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_SAMPLER_3D:
38233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_3D:
38243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_INT_SAMPLER_3D:
38258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		case glu::TYPE_SAMPLER_CUBE_ARRAY:
38268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		case glu::TYPE_UINT_SAMPLER_CUBE_ARRAY:
38278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		case glu::TYPE_INT_SAMPLER_CUBE_ARRAY:
38283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			uniforms[location].value.i = *v;
38293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
38303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
38323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_OPERATION);
38333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
38343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
38353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform1f (deInt32 location, const float v0)
38383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniform1fv(location, 1, &v0);
38403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform1i (deInt32 location, deInt32 v0)
38433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniform1iv(location, 1, &v0);
38453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform1fv (deInt32 location, deInt32 count, const float* v)
38483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniformv(location, glu::TYPE_FLOAT, count, v);
38503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform2fv (deInt32 location, deInt32 count, const float* v)
38533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniformv(location, glu::TYPE_FLOAT_VEC2, count, v);
38553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform3fv (deInt32 location, deInt32 count, const float* v)
38583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniformv(location, glu::TYPE_FLOAT_VEC3, count, v);
38603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform4fv (deInt32 location, deInt32 count, const float* v)
38633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniformv(location, glu::TYPE_FLOAT_VEC4, count, v);
38653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38673c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform2iv (deInt32 location, deInt32 count, const deInt32* v)
38683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniformv(location, glu::TYPE_INT_VEC2, count, v);
38703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform3iv (deInt32 location, deInt32 count, const deInt32* v)
38733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniformv(location, glu::TYPE_INT_VEC3, count, v);
38753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniform4iv (deInt32 location, deInt32 count, const deInt32* v)
38783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	uniformv(location, glu::TYPE_INT_VEC4, count, v);
38803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
38813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniformMatrix3fv (deInt32 location, deInt32 count, deInt32 transpose, const float *value)
38833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
38843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(m_currentProgram == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
38853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<sglr::UniformSlot>& uniforms = m_currentProgram->m_program->m_uniforms;
38873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (location == -1)
38893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
38903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(location < 0 || (size_t)location >= uniforms.size(), GL_INVALID_OPERATION, RC_RET_VOID);
38923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (count == 0)
38943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
38953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(transpose != GL_TRUE && transpose != GL_FALSE, GL_INVALID_ENUM, RC_RET_VOID);
38973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
38983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (uniforms[location].type)
38993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
39003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_FLOAT_MAT3:
39013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(count > 1, GL_INVALID_OPERATION, RC_RET_VOID);
39023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (transpose == GL_FALSE) // input is column major => transpose from column major to internal row major
39043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int row = 0; row < 3; ++row)
39053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int col = 0; col < 3; ++col)
39063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					uniforms[location].value.m3[row*3+col] = value[col*3+row];
39073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else // input is row major
39083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int row = 0; row < 3; ++row)
39093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int col = 0; col < 3; ++col)
39103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					uniforms[location].value.m3[row*3+col] = value[row*3+col];
39113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
39133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
39153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_OPERATION);
39163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
39173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
39183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
39193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::uniformMatrix4fv (deInt32 location, deInt32 count, deInt32 transpose, const float *value)
39213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
39223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(m_currentProgram == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
39233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<sglr::UniformSlot>& uniforms = m_currentProgram->m_program->m_uniforms;
39253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (location == -1)
39273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
39283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(location < 0 || (size_t)location >= uniforms.size(), GL_INVALID_OPERATION, RC_RET_VOID);
39303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (count == 0)
39323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
39333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(transpose != GL_TRUE && transpose != GL_FALSE, GL_INVALID_ENUM, RC_RET_VOID);
39353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (uniforms[location].type)
39373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
39383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::TYPE_FLOAT_MAT4:
39393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_IF_ERROR(count > 1, GL_INVALID_OPERATION, RC_RET_VOID);
39403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (transpose == GL_FALSE) // input is column major => transpose from column major to internal row major
39423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int row = 0; row < 4; ++row)
39433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int col = 0; col < 4; ++col)
39443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					uniforms[location].value.m4[row*3+col] = value[col*3+row];
39453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else // input is row major
39463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int row = 0; row < 4; ++row)
39473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int col = 0; col < 4; ++col)
39483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					uniforms[location].value.m4[row*3+col] = value[row*3+col];
39493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
39513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
39533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_OPERATION);
39543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
39553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
39563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
39573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39583c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeInt32 ReferenceContext::getUniformLocation (deUint32 program, const char *name)
39593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
39603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderProgramObjectContainer* shaderProg = m_programs.find(program);
39613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(shaderProg == DE_NULL, GL_INVALID_OPERATION, -1);
39623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<sglr::UniformSlot>& uniforms = shaderProg->m_program->m_uniforms;
39643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t i = 0; i < uniforms.size(); ++i)
39663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (name && deStringEqual(uniforms[i].name.c_str(), name))
39673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return (int)i;
39683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return -1;
39703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
39713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::lineWidth (float w)
39733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
39743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(w < 0.0f, GL_INVALID_VALUE, RC_RET_VOID);
39753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_lineWidth = w;
39763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
39773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteVertexArray (rc::VertexArray* vertexArray)
39793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
39803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_vertexArrayBinding == vertexArray)
39813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bindVertexArray(0);
39823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (vertexArray->m_elementArrayBufferBinding)
39843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_buffers.releaseReference(vertexArray->m_elementArrayBufferBinding);
39853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t ndx = 0; ndx < vertexArray->m_arrays.size(); ++ndx)
39873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (vertexArray->m_arrays[ndx].bufferBinding)
39883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_buffers.releaseReference(vertexArray->m_arrays[ndx].bufferBinding);
39893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(vertexArray->getRefCount() == 1);
39913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_vertexArrays.releaseReference(vertexArray);
39923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
39933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
39943c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteProgramObject (rc::ShaderProgramObjectContainer* sp)
39953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
39963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Unbinding program will delete it
39973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentProgram == sp && sp->m_deleteFlag)
39983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
39993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		useProgram(0);
40003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
40013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
40023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Unbinding program will NOT delete it
40043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentProgram == sp)
40053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		useProgram(0);
40063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(sp->getRefCount() == 1);
40083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_programs.releaseReference(sp);
40093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawArrays (deUint32 mode, int first, int count)
40123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawArraysInstanced(mode, first, count, 1);
40143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawArraysInstanced (deUint32 mode, int first, int count, int instanceCount)
40173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Error conditions
40193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
40203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(first < 0 || count < 0 || instanceCount < 0, GL_INVALID_VALUE, RC_RET_VOID);
40213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!predrawErrorChecks(mode))
40233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
40243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
40253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// All is ok
40273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
40283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const rr::PrimitiveType primitiveType = sglr::rr_util::mapGLPrimitiveType(mode);
40293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawWithReference(rr::PrimitiveList(primitiveType, count, first), instanceCount);
40313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
40323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40343c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawElements (deUint32 mode, int count, deUint32 type, const void *indices)
40353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawElementsInstanced(mode, count, type, indices, 1);
40373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40393c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawElementsBaseVertex (deUint32 mode, int count, deUint32 type, const void *indices, int baseVertex)
40403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawElementsInstancedBaseVertex(mode, count, type, indices, 1, baseVertex);
40423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawElementsInstanced (deUint32 mode, int count, deUint32 type, const void *indices, int instanceCount)
40453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawElementsInstancedBaseVertex(mode, count, type, indices, instanceCount, 0);
40473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawElementsInstancedBaseVertex (deUint32 mode, int count, deUint32 type, const void *indices, int instanceCount, int baseVertex)
40503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
40523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Error conditions
40543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
40553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(type != GL_UNSIGNED_BYTE &&
40563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					type != GL_UNSIGNED_SHORT &&
40573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					type != GL_UNSIGNED_INT, GL_INVALID_ENUM, RC_RET_VOID);
40583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(count < 0 || instanceCount < 0, GL_INVALID_VALUE, RC_RET_VOID);
40593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!predrawErrorChecks(mode))
40613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return;
40623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
40633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// All is ok
40653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
40663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const rr::PrimitiveType primitiveType	= sglr::rr_util::mapGLPrimitiveType(mode);
40673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const void*				indicesPtr		= (vao.m_elementArrayBufferBinding) ? (vao.m_elementArrayBufferBinding->getData() + ((const deUint8*)indices - (const deUint8*)DE_NULL)) : (indices);
40683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawWithReference(rr::PrimitiveList(primitiveType, count, rr::DrawIndices(indicesPtr, sglr::rr_util::mapGLIndexType(type), baseVertex)), instanceCount);
40703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
40713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawRangeElements (deUint32 mode, deUint32 start, deUint32 end, int count, deUint32 type, const void *indices)
40743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(end < start, GL_INVALID_VALUE, RC_RET_VOID);
40763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawElements(mode, count, type, indices);
40783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawRangeElementsBaseVertex (deUint32 mode, deUint32 start, deUint32 end, int count, deUint32 type, const void *indices, int baseVertex)
40813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(end < start, GL_INVALID_VALUE, RC_RET_VOID);
40833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawElementsBaseVertex(mode, count, type, indices, baseVertex);
40853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
40863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawArraysIndirect (deUint32 mode, const void *indirect)
40883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
40893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct DrawArraysIndirectCommand
40903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
40913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 count;
40923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 primCount;
40933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 first;
40943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 reservedMustBeZero;
40953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
40963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const DrawArraysIndirectCommand* command;
40983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
40993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check errors
41003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!predrawErrorChecks(mode))
41023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
41033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check pointer validity
41053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(m_drawIndirectBufferBinding == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
41073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!deIsAlignedPtr(indirect, 4), GL_INVALID_OPERATION, RC_RET_VOID);
41083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note watch for overflows, indirect might be close to 0xFFFFFFFF and indirect+something might overflow
41103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((size_t)((const char*)indirect - (const char*)DE_NULL)                                     > (size_t)m_drawIndirectBufferBinding->getSize(), GL_INVALID_OPERATION, RC_RET_VOID);
41113c827367444ee418f129b2c238299f49d3264554Jarkko 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);
41123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check values
41143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	command = (const DrawArraysIndirectCommand*)(m_drawIndirectBufferBinding->getData() + ((const char*)indirect - (const char*)DE_NULL));
41163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(command->reservedMustBeZero != 0, GL_INVALID_OPERATION, RC_RET_VOID);
41173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// draw
41193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	drawArraysInstanced(mode, command->first, command->count, command->primCount);
41203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
41213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawElementsIndirect	(deUint32 mode, deUint32 type, const void *indirect)
41233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
41243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct DrawElementsIndirectCommand
41253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
41263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 count;
41273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 primCount;
41283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 firstIndex;
41293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt32  baseVertex;
41303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 reservedMustBeZero;
41313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
41323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const DrawElementsIndirectCommand* command;
41343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check errors
41363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!predrawErrorChecks(mode))
41383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
41393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(type != GL_UNSIGNED_BYTE &&
41413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_UNSIGNED_SHORT &&
41423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				type != GL_UNSIGNED_INT, GL_INVALID_ENUM, RC_RET_VOID);
41433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!getBufferBinding(GL_ELEMENT_ARRAY_BUFFER), GL_INVALID_OPERATION, RC_RET_VOID);
41453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check pointer validity
41473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(m_drawIndirectBufferBinding == DE_NULL, GL_INVALID_OPERATION, RC_RET_VOID);
41493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(!deIsAlignedPtr(indirect, 4), GL_INVALID_OPERATION, RC_RET_VOID);
41503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note watch for overflows, indirect might be close to 0xFFFFFFFF and indirect+something might overflow
41523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((size_t)((const char*)indirect - (const char*)DE_NULL)                                       > (size_t)m_drawIndirectBufferBinding->getSize(), GL_INVALID_OPERATION, RC_RET_VOID);
41533c827367444ee418f129b2c238299f49d3264554Jarkko 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);
41543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check values
41563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	command = (const DrawElementsIndirectCommand*)(m_drawIndirectBufferBinding->getData() + ((const char*)indirect - (const char*)DE_NULL));
41583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(command->reservedMustBeZero != 0, GL_INVALID_OPERATION, RC_RET_VOID);
41593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Check command error conditions
41613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR((int)command->count < 0 || (int)command->primCount < 0, GL_INVALID_VALUE, RC_RET_VOID);
41623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Draw
41643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
41653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const size_t			sizeOfType		= (type == GL_UNSIGNED_BYTE) ?  (1) : ((type == GL_UNSIGNED_SHORT) ? (2) : (4));
41663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const void*				indicesPtr		= (deUint8*)DE_NULL + (command->firstIndex * sizeOfType);
41673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		drawElementsInstancedBaseVertex(mode, (int)command->count, type, indicesPtr, (int)command->primCount, command->baseVertex);
41693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
41703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
41713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41723c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::multiDrawArrays (deUint32 mode, const int* first, const int* count, int primCount)
41733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
41743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(mode);
41753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(first);
41763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(count);
41773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(primCount);
41783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// not supported in gles, prevent accidental use
41803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
41813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
41823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::multiDrawElements (deUint32 mode, const int* count, deUint32 type, const void** indices, int primCount)
41843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
41853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(mode);
41863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(count);
41873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(type);
41883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(indices);
41893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(primCount);
41903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// not supported in gles, prevent accidental use
41923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
41933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
41943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
41953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::multiDrawElementsBaseVertex (deUint32 mode, const int* count, deUint32 type, const void** indices, int primCount, const int* baseVertex)
41963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
41973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(mode);
41983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(count);
41993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(type);
42003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(indices);
42013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(primCount);
42023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(baseVertex);
42033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// not supported in gles, prevent accidental use
42053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(false);
42063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
42073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ReferenceContext::predrawErrorChecks (deUint32 mode)
42093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
42103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(mode != GL_POINTS &&
42113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				mode != GL_LINE_STRIP && mode != GL_LINE_LOOP && mode != GL_LINES &&
42123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				mode != GL_TRIANGLE_STRIP && mode != GL_TRIANGLE_FAN && mode != GL_TRIANGLES &&
42133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				mode != GL_LINES_ADJACENCY && mode != GL_LINE_STRIP_ADJACENCY &&
42143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				mode != GL_TRIANGLES_ADJACENCY && mode != GL_TRIANGLE_STRIP_ADJACENCY,
42153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				GL_INVALID_ENUM, false);
42163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \todo [jarkko] Uncomment following code when the buffer mapping support is added
42183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//for (size_t ndx = 0; ndx < vao.m_arrays.size(); ++ndx)
42193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//	if (vao.m_arrays[ndx].enabled && vao.m_arrays[ndx].bufferBinding && vao.m_arrays[ndx].bufferBinding->isMapped)
42203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		RC_ERROR_RET(GL_INVALID_OPERATION, RC_RET_VOID);
42213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, GL_INVALID_FRAMEBUFFER_OPERATION, false);
42233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Geometry shader checks
42253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentProgram && m_currentProgram->m_program->m_hasGeometryShader)
42263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
42273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(m_currentProgram->m_program->rr::GeometryShader::getInputType() == rr::GEOMETRYSHADERINPUTTYPE_POINTS && mode != GL_POINTS, GL_INVALID_OPERATION, false);
42283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(m_currentProgram->m_program->rr::GeometryShader::getInputType() == rr::GEOMETRYSHADERINPUTTYPE_LINES &&
42303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(mode != GL_LINES &&
42313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 mode != GL_LINE_STRIP &&
42323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 mode != GL_LINE_LOOP),
42333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 GL_INVALID_OPERATION, false);
42343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(m_currentProgram->m_program->rr::GeometryShader::getInputType() == rr::GEOMETRYSHADERINPUTTYPE_TRIANGLES &&
42363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(mode != GL_TRIANGLES &&
42373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 mode != GL_TRIANGLE_STRIP &&
42383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 mode != GL_TRIANGLE_FAN),
42393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 GL_INVALID_OPERATION, false);
42403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(m_currentProgram->m_program->rr::GeometryShader::getInputType() == rr::GEOMETRYSHADERINPUTTYPE_LINES_ADJACENCY &&
42423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(mode != GL_LINES_ADJACENCY &&
42433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 mode != GL_LINE_STRIP_ADJACENCY),
42443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 GL_INVALID_OPERATION, false);
42453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		RC_IF_ERROR(m_currentProgram->m_program->rr::GeometryShader::getInputType() == rr::GEOMETRYSHADERINPUTTYPE_TRIANGLES_ADJACENCY &&
42473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			(mode != GL_TRIANGLES_ADJACENCY &&
42483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 mode != GL_TRIANGLE_STRIP_ADJACENCY),
42493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			 GL_INVALID_OPERATION, false);
42503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
42513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
42533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
42543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic rr::PrimitiveType getPrimitiveBaseType (rr::PrimitiveType derivedType)
42563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
42573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (derivedType)
42583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
42593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_TRIANGLES:
42603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_TRIANGLE_STRIP:
42613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_TRIANGLE_FAN:
42623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY:
42633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY:
42643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return rr::PRIMITIVETYPE_TRIANGLES;
42653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_LINES:
42673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_LINE_STRIP:
42683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_LINE_LOOP:
42693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_LINES_ADJACENCY:
42703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY:
42713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return rr::PRIMITIVETYPE_LINES;
42723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::PRIMITIVETYPE_POINTS:
42743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return rr::PRIMITIVETYPE_POINTS;
42753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
42773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
42783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return rr::PRIMITIVETYPE_LAST;
42793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
42803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
42813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deUint32 getFixedRestartIndex (rr::IndexType indexType)
42833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
42843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (indexType)
42853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
42863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::INDEXTYPE_UINT8:		return 0xFF;
42873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::INDEXTYPE_UINT16:		return 0xFFFF;
42883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::INDEXTYPE_UINT32:		return 0xFFFFFFFFul;
42893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case rr::INDEXTYPE_LAST:
42913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
42923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
42933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return 0;
42943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
42953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
42963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
42973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::drawWithReference (const rr::PrimitiveList& primitives, int instanceCount)
42983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
42993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// undefined results
43003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentProgram == DE_NULL)
43013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
43023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisamplePixelBufferAccess	colorBuf0	= getDrawColorbuffer();
43043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisamplePixelBufferAccess	depthBuf	= getDrawDepthbuffer();
43053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisamplePixelBufferAccess	stencilBuf	= getDrawStencilbuffer();
43063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool							hasStencil	= !isEmpty(stencilBuf);
43073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int							stencilBits	= (hasStencil) ? (getNumStencilBits(stencilBuf.raw().getFormat())) : (0);
43083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const rr::RenderTarget				renderTarget(colorBuf0, depthBuf,stencilBuf);
43103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const rr::Program					program		(m_currentProgram->m_program->getVertexShader(),
43113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 m_currentProgram->m_program->getFragmentShader(),
43123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 (m_currentProgram->m_program->m_hasGeometryShader) ? (m_currentProgram->m_program->getGeometryShader()) : (DE_NULL));
43133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::RenderState						state		((rr::ViewportState)(colorBuf0));
43143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const rr::Renderer					referenceRenderer;
43163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<rr::VertexAttrib>		vertexAttribs;
43173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Gen state
43193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
43203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const rr::PrimitiveType	baseType							= getPrimitiveBaseType(primitives.getPrimitiveType());
43213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool				polygonOffsetEnabled				= (baseType == rr::PRIMITIVETYPE_TRIANGLES) ? (m_polygonOffsetFillEnabled) : (false);
43223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//state.cullMode											= m_cullMode
43243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.scissorTestEnabled							= m_scissorEnabled;
43263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.scissorRectangle								= rr::WindowRectangle(m_scissorBox.x(), m_scissorBox.y(), m_scissorBox.z(), m_scissorBox.w());
43273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.numStencilBits								= stencilBits;
43293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.stencilTestEnabled							= m_stencilTestEnabled;
43303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int faceType = 0; faceType < rr::FACETYPE_LAST; faceType++)
43323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
43333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.fragOps.stencilStates[faceType].compMask	= m_stencil[faceType].opMask;
43343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.fragOps.stencilStates[faceType].writeMask	= m_stencil[faceType].writeMask;
43353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.fragOps.stencilStates[faceType].ref		= m_stencil[faceType].ref;
43363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.fragOps.stencilStates[faceType].func		= sglr::rr_util::mapGLTestFunc(m_stencil[faceType].func);
43373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.fragOps.stencilStates[faceType].sFail		= sglr::rr_util::mapGLStencilOp(m_stencil[faceType].opStencilFail);
43383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.fragOps.stencilStates[faceType].dpFail	= sglr::rr_util::mapGLStencilOp(m_stencil[faceType].opDepthFail);
43393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			state.fragOps.stencilStates[faceType].dpPass	= sglr::rr_util::mapGLStencilOp(m_stencil[faceType].opDepthPass);
43403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
43413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.depthTestEnabled								= m_depthTestEnabled;
43433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.depthFunc										= sglr::rr_util::mapGLTestFunc(m_depthFunc);
43443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.depthMask										= m_depthMask;
43453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendMode										= m_blendEnabled ? rr::BLENDMODE_STANDARD : rr::BLENDMODE_NONE;
43473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendRGBState.equation						= sglr::rr_util::mapGLBlendEquation(m_blendModeRGB);
43483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendRGBState.srcFunc							= sglr::rr_util::mapGLBlendFunc(m_blendFactorSrcRGB);
43493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendRGBState.dstFunc							= sglr::rr_util::mapGLBlendFunc(m_blendFactorDstRGB);
43503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendAState.equation							= sglr::rr_util::mapGLBlendEquation(m_blendModeAlpha);
43513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendAState.srcFunc							= sglr::rr_util::mapGLBlendFunc(m_blendFactorSrcAlpha);
43523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendAState.dstFunc							= sglr::rr_util::mapGLBlendFunc(m_blendFactorDstAlpha);
43533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.blendColor									= m_blendColor;
43543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.sRGBEnabled									= m_sRGBUpdateEnabled;
43563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.colorMask										= m_colorMask;
43583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.depthClampEnabled								= m_depthClampEnabled;
43603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.viewport.rect											= rr::WindowRectangle(m_viewport.x(), m_viewport.y(), m_viewport.z(), m_viewport.w());
43623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.viewport.zn											= m_depthRangeNear;
43633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.viewport.zf											= m_depthRangeFar;
43643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		//state.point.pointSize										= m_pointSize;
43663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.line.lineWidth										= m_lineWidth;
43673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.polygonOffsetEnabled							= polygonOffsetEnabled;
43693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.polygonOffsetFactor							= m_polygonOffsetFactor;
43703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.fragOps.polygonOffsetUnits							= m_polygonOffsetUnits;
43713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
43733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const rr::IndexType indexType = primitives.getIndexType();
43743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_primitiveRestartFixedIndex && indexType != rr::INDEXTYPE_LAST)
43763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
43773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.restart.enabled = true;
43783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.restart.restartIndex = getFixedRestartIndex(indexType);
43793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
43803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (m_primitiveRestartSettableIndex)
43813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
43823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \note PRIMITIVE_RESTART is active for non-indexed (DrawArrays) operations too.
43833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.restart.enabled = true;
43843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.restart.restartIndex = m_primitiveRestartIndex;
43853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
43863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
43873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
43883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				state.restart.enabled = false;
43893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
43903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
43913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		state.provokingVertexConvention								= (m_provokingFirstVertexConvention) ? (rr::PROVOKINGVERTEX_FIRST) : (rr::PROVOKINGVERTEX_LAST);
43933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
43943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// gen attributes
43963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
43973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		rc::VertexArray& vao = (m_vertexArrayBinding) ? (*m_vertexArrayBinding) : (m_clientVertexArray);
43983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
43993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vertexAttribs.resize(vao.m_arrays.size());
44003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (size_t ndx = 0; ndx < vao.m_arrays.size(); ++ndx)
44013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
44023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!vao.m_arrays[ndx].enabled)
44033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
44043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].type = rr::VERTEXATTRIBTYPE_DONT_CARE; // reading with wrong type is allowed, but results are undefined
44053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].generic = m_currentAttribs[ndx];
44063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
44073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (vao.m_arrays[ndx].bufferDeleted)
44083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
44093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].type = rr::VERTEXATTRIBTYPE_DONT_CARE; // reading from deleted buffer, output zeros
44103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].generic = tcu::Vec4(0, 0, 0, 0);
44113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
44123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
44133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
44143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].type				= (vao.m_arrays[ndx].integer) ?
44153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														(sglr::rr_util::mapGLPureIntegerVertexAttributeType(vao.m_arrays[ndx].type)) :
44163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														(sglr::rr_util::mapGLFloatVertexAttributeType(vao.m_arrays[ndx].type, vao.m_arrays[ndx].normalized, vao.m_arrays[ndx].size, this->getType()));
44173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].size				= sglr::rr_util::mapGLSize(vao.m_arrays[ndx].size);
44183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].stride			= vao.m_arrays[ndx].stride;
44193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexAttribs[ndx].instanceDivisor	= vao.m_arrays[ndx].divisor;
44203c827367444ee418f129b2c238299f49d3264554Jarkko 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);
44213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
44223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
44233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
44243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Set shader samplers
44263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (size_t uniformNdx = 0; uniformNdx < m_currentProgram->m_program->m_uniforms.size(); ++uniformNdx)
44273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
44283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texNdx = m_currentProgram->m_program->m_uniforms[uniformNdx].value.i;
44293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (m_currentProgram->m_program->m_uniforms[uniformNdx].type)
44313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
44323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_SAMPLER_1D:
44333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_UINT_SAMPLER_1D:
44343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_INT_SAMPLER_1D:
44353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
44363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rc::Texture1D* tex = DE_NULL;
44373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
44393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex = (m_textureUnits[texNdx].tex1DBinding) ? (m_textureUnits[texNdx].tex1DBinding) : (&m_textureUnits[texNdx].default1DTex);
44403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex && tex->isComplete())
44423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
44433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex->updateView();
44443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex1D = tex;
44453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
44463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
44473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex1D = &m_emptyTex1D;
44483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
44503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
44513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_SAMPLER_2D:
44523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_UINT_SAMPLER_2D:
44533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_INT_SAMPLER_2D:
44543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
44553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rc::Texture2D* tex = DE_NULL;
44563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
44583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex = (m_textureUnits[texNdx].tex2DBinding) ? (m_textureUnits[texNdx].tex2DBinding) : (&m_textureUnits[texNdx].default2DTex);
44593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex && tex->isComplete())
44613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
44623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex->updateView();
44633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex2D = tex;
44643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
44653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
44663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex2D = &m_emptyTex2D;
44673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
44693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
44703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_SAMPLER_CUBE:
44713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_UINT_SAMPLER_CUBE:
44723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_INT_SAMPLER_CUBE:
44733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
44743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rc::TextureCube* tex = DE_NULL;
44753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
44773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex = (m_textureUnits[texNdx].texCubeBinding) ? (m_textureUnits[texNdx].texCubeBinding) : (&m_textureUnits[texNdx].defaultCubeTex);
44783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex && tex->isComplete())
44803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
44813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex->updateView();
44823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.texCube = tex;
44833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
44843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
44853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.texCube = &m_emptyTexCube;
44863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
44883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
44893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_SAMPLER_2D_ARRAY:
44903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
44913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_INT_SAMPLER_2D_ARRAY:
44923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
44933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rc::Texture2DArray* tex = DE_NULL;
44943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
44963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex = (m_textureUnits[texNdx].tex2DArrayBinding) ? (m_textureUnits[texNdx].tex2DArrayBinding) : (&m_textureUnits[texNdx].default2DArrayTex);
44973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
44983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex && tex->isComplete())
44993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
45003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex->updateView();
45013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex2DArray = tex;
45023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
45033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
45043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex2DArray = &m_emptyTex2DArray;
45053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
45073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
45083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_SAMPLER_3D:
45093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_UINT_SAMPLER_3D:
45103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_INT_SAMPLER_3D:
45113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
45123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rc::Texture3D* tex = DE_NULL;
45133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
45153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex = (m_textureUnits[texNdx].tex3DBinding) ? (m_textureUnits[texNdx].tex3DBinding) : (&m_textureUnits[texNdx].default3DTex);
45163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex && tex->isComplete())
45183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
45193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex->updateView();
45203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex3D = tex;
45213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
45223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
45233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.tex3D = &m_emptyTex3D;
45243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
45263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
45273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_SAMPLER_CUBE_ARRAY:
45283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_UINT_SAMPLER_CUBE_ARRAY:
45293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case glu::TYPE_INT_SAMPLER_CUBE_ARRAY:
45303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
45313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				rc::TextureCubeArray* tex = DE_NULL;
45323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (texNdx >= 0 && (size_t)texNdx < m_textureUnits.size())
45343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex = (m_textureUnits[texNdx].texCubeArrayBinding) ? (m_textureUnits[texNdx].texCubeArrayBinding) : (&m_textureUnits[texNdx].defaultCubeArrayTex);
45353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (tex && tex->isComplete())
45373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
45383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					tex->updateView();
45393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.texCubeArray = tex;
45403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
45413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
45423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					m_currentProgram->m_program->m_uniforms[uniformNdx].sampler.texCubeArray = &m_emptyTexCubeArray;
45433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
45453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
45463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
45473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// nothing
45483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				break;
45493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
45503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
45513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	referenceRenderer.drawInstanced(rr::DrawCommand(state, renderTarget, program, (int)vertexAttribs.size(), &vertexAttribs[0], primitives), instanceCount);
45533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
45543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45553c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 ReferenceContext::createProgram (ShaderProgram* program)
45563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
45573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int name = m_programs.allocateName();
45583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_programs.insert(new rc::ShaderProgramObjectContainer(name, program));
45603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return name;
45623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
45633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::useProgram (deUint32 program)
45653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
45663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::ShaderProgramObjectContainer* shaderProg			= DE_NULL;
45673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::ShaderProgramObjectContainer* programToBeDeleted	= DE_NULL;
45683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (program)
45703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
45713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		shaderProg = m_programs.find(program);
45723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// shader has not been linked
45743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!shaderProg || shaderProg->m_deleteFlag)
45753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			RC_ERROR_RET(GL_INVALID_OPERATION, RC_RET_VOID);
45763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
45773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_currentProgram && m_currentProgram->m_deleteFlag)
45793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		programToBeDeleted = m_currentProgram;
45803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_currentProgram = shaderProg;
45823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (programToBeDeleted)
45843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
45853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(programToBeDeleted->getRefCount() == 1);
45863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deleteProgramObject(programToBeDeleted);
45873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
45883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
45893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::deleteProgram (deUint32 program)
45913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
45923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!program)
45933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return;
45943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
45953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rc::ShaderProgramObjectContainer* shaderProg = m_programs.find(program);
45963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (shaderProg)
45973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
45983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (shaderProg == m_currentProgram)
45993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
46003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_currentProgram->m_deleteFlag = true;
46013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
46023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
46033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
46043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(shaderProg->getRefCount() == 1);
46053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_programs.releaseReference(shaderProg);
46063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
46073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
46083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::readPixels (int x, int y, int width, int height, deUint32 format, deUint32 type, void* data)
46113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::MultisamplePixelBufferAccess	src = getReadColorbuffer();
46133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TextureFormat						transferFmt;
46143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Map transfer format.
46163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	transferFmt = glu::mapGLTransferFormat(format, type);
46173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RC_IF_ERROR(transferFmt.order	== TextureFormat::CHANNELORDER_LAST ||
46183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				transferFmt.type	== TextureFormat::CHANNELTYPE_LAST, GL_INVALID_ENUM, RC_RET_VOID);
46193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clamp input values
46213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int copyX			= deClamp32(x,		0, src.raw().getHeight());
46223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int copyY			= deClamp32(y,		0, src.raw().getDepth());
46233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int copyWidth		= deClamp32(width,	0, src.raw().getHeight()-x);
46243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int copyHeight	= deClamp32(height,	0, src.raw().getDepth()-y);
46253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	PixelBufferAccess dst(transferFmt, width, height, 1, deAlign32(width*transferFmt.getPixelSize(), m_pixelPackAlignment), 0, getPixelPackPtr(data));
46273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rr::resolveMultisampleColorBuffer(tcu::getSubregion(dst, 0, 0, copyWidth, copyHeight), rr::getSubregion(src, copyX, copyY, copyWidth, copyHeight));
46283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46303c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 ReferenceContext::getError (void)
46313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 err = m_lastError;
46333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_lastError = GL_NO_ERROR;
46343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return err;
46353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::finish (void)
46383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline void ReferenceContext::setError (deUint32 error)
46423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_lastError == GL_NO_ERROR)
46443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_lastError = error;
46453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ReferenceContext::getIntegerv (deUint32 pname, int* param)
46483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (pname)
46503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
46513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MAX_TEXTURE_SIZE:			*param = m_limits.maxTexture2DSize;			break;
46523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MAX_CUBE_MAP_TEXTURE_SIZE:	*param = m_limits.maxTextureCubeSize;		break;
46533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MAX_ARRAY_TEXTURE_LAYERS:	*param = m_limits.maxTexture2DArrayLayers;	break;
46543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MAX_3D_TEXTURE_SIZE:		*param = m_limits.maxTexture3DSize;			break;
46553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MAX_RENDERBUFFER_SIZE:		*param = m_limits.maxRenderbufferSize;		break;
46563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MAX_TEXTURE_IMAGE_UNITS:	*param = m_limits.maxTextureImageUnits;		break;
46573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_MAX_VERTEX_ATTRIBS:			*param = m_limits.maxVertexAttribs;			break;
46583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
46603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
46613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
46623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
46633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst char* ReferenceContext::getString (deUint32 pname)
46663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (pname)
46683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
46693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case GL_EXTENSIONS:		return m_limits.extensionStr.c_str();
46703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
46723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			setError(GL_INVALID_ENUM);
46733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
46743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
46753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace rc
46783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46803c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelArray::TextureLevelArray (void)
46813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46843c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureLevelArray::~TextureLevelArray (void)
46853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clear();
46873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelArray::clear (void)
46903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
46913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(m_data) == DE_LENGTH_OF_ARRAY(m_access));
46923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
46933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(m_data); ndx++)
46943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
46955e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry		m_data[ndx].clear();
46965e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry		m_access[ndx] = PixelBufferAccess();
46973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
46983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
46993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelArray::allocLevel (int level, const tcu::TextureFormat& format, int width, int height, int depth)
47013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
47025e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry	const int dataSize = format.getPixelSize()*width*height*depth;
47033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47045e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry	DE_ASSERT(deInBounds32(level, 0, DE_LENGTH_OF_ARRAY(m_data)));
47053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(level))
47073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		clearLevel(level);
47083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47095e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry	m_data[level].setStorage(dataSize);
47105e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry	m_access[level] = PixelBufferAccess(format, width, height, depth, m_data[level].getPtr());
47113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
47123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureLevelArray::clearLevel (int level)
47143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
47155e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry	DE_ASSERT(deInBounds32(level, 0, DE_LENGTH_OF_ARRAY(m_data)));
47163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47175e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry	m_data[level].clear();
47185e334966c020f28d520c1c6bb36193990195fe0eJarkko Pöyry	m_access[level] = PixelBufferAccess();
47193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
47203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture::Texture (deUint32 name, Type type)
47223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: NamedObject	(name)
47233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_type		(type)
47243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_immutable	(false)
47253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_sampler		(tcu::Sampler::REPEAT_GL,
47263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 tcu::Sampler::REPEAT_GL,
47273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 tcu::Sampler::REPEAT_GL,
47283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 tcu::Sampler::NEAREST_MIPMAP_LINEAR,
47293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 tcu::Sampler::LINEAR,
47303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 0.0f,				// LOD threshold
47313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 true,				// normalized coords
47323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 tcu::Sampler::COMPAREMODE_NONE,
47333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 0,					// cmp channel ndx
47343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 tcu::Vec4(0.0f),	// border color
47353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 true				// seamless cube map \todo [2014-02-19 pyry] Default value ok?
47363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 )
47373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_baseLevel	(0)
47383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_maxLevel	(1000)
47393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
47403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
47413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47423c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::Texture1D (deUint32 name)
47433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: Texture	(name, TYPE_1D)
47443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view	(0, DE_NULL)
47453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
47463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
47473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture1D::~Texture1D (void)
47493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
47503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
47513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1D::allocLevel (int level, const tcu::TextureFormat& format, int width)
47533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
47543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_levels.allocLevel(level, format, width, 1, 1);
47553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
47563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool Texture1D::isComplete (void) const
47583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
47593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	baseLevel	= getBaseLevel();
47603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel))
47623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
47633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::ConstPixelBufferAccess&	level0		= getLevel(baseLevel);
47643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool							mipmap		= isMipmapFilter(getSampler().minFilter);
47653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mipmap)
47673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
47683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const TextureFormat&	format		= level0.getFormat();
47693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				w			= level0.getWidth();
47703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLevels	= de::min(getMaxLevel()-baseLevel+1, getNumMipLevels1D(w));
47713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
47733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
47743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (hasLevel(baseLevel+levelNdx))
47753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
47763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const tcu::ConstPixelBufferAccess&	level		= getLevel(baseLevel+levelNdx);
47773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedW	= getMipLevelSize(w, levelNdx);
47783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (level.getWidth()	!= expectedW	||
47803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getFormat()	!= format)
47813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						return false;
47823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
47833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
47843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
47853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
47863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
47873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
47893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
47903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
47913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
47923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
47933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 Texture1D::sample (float s, float lod) const
47953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
47963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_view.sample(getSampler(), s, 0.0f, lod);
47973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
47983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
47993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1D::sample4 (tcu::Vec4 output[4], const float packetTexcoords[4], float lodBias) const
48003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
48013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int texWidth  = m_view.getWidth();
48023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dFdx0 = packetTexcoords[1] - packetTexcoords[0];
48043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dFdx1 = packetTexcoords[3] - packetTexcoords[2];
48053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dFdy0 = packetTexcoords[2] - packetTexcoords[0];
48063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dFdy1 = packetTexcoords[3] - packetTexcoords[1];
48073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
48093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
48103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float& dFdx = (fragNdx > 2) ? dFdx1 : dFdx0;
48113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float& dFdy = (fragNdx % 2) ? dFdy1 : dFdy0;
48123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mu = de::max(de::abs(dFdx), de::abs(dFdy));
48143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float p = mu * texWidth;
48153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lod = deFloatLog2(p) + lodBias;
48173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		output[fragNdx] = sample(packetTexcoords[fragNdx], lod);
48193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
48203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
48213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48223c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture1D::updateView (void)
48233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
48243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int baseLevel	= getBaseLevel();
48253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel) && !isEmpty(getLevel(baseLevel)))
48273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
48283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	width		= getLevel(baseLevel).getWidth();
48293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
48303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels1D(width)) : 1;
48313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::Texture2DView(numLevels, m_levels.getLevels() + baseLevel);
48333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
48343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
48353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::Texture2DView(0, DE_NULL);
48363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
48373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48383c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::Texture2D (deUint32 name)
48393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: Texture	(name, TYPE_2D)
48403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view	(0, DE_NULL)
48413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
48423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
48433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48443c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2D::~Texture2D (void)
48453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
48463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
48473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2D::allocLevel (int level, const tcu::TextureFormat& format, int width, int height)
48493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
48503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_levels.allocLevel(level, format, width, height, 1);
48513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
48523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool Texture2D::isComplete (void) const
48543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
48553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	baseLevel	= getBaseLevel();
48563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel))
48583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
48593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::ConstPixelBufferAccess&	level0		= getLevel(baseLevel);
48603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool							mipmap		= isMipmapFilter(getSampler().minFilter);
48613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mipmap)
48633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
48643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const TextureFormat&	format		= level0.getFormat();
48653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				w			= level0.getWidth();
48663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				h			= level0.getHeight();
48673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLevels	= de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(w, h));
48683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
48703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
48713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (hasLevel(baseLevel+levelNdx))
48723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
48733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const tcu::ConstPixelBufferAccess&	level		= getLevel(baseLevel+levelNdx);
48743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedW	= getMipLevelSize(w, levelNdx);
48753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedH	= getMipLevelSize(h, levelNdx);
48763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (level.getWidth()	!= expectedW	||
48783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getHeight()	!= expectedH	||
48793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getFormat()	!= format)
48803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						return false;
48813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
48823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
48833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
48843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
48853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
48863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
48883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
48893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
48903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
48913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
48923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2D::updateView (void)
48943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
48953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int baseLevel	= getBaseLevel();
48963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
48973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel) && !isEmpty(getLevel(baseLevel)))
48983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
48993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Update number of levels in mipmap pyramid.
49003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	width		= getLevel(baseLevel).getWidth();
49013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	height		= getLevel(baseLevel).getHeight();
49023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
49033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(width, height)) : 1;
49043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::Texture2DView(numLevels, m_levels.getLevels() + baseLevel);
49063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
49073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
49083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::Texture2DView(0, DE_NULL);
49093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
49103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 Texture2D::sample (float s, float t, float lod) const
49123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
49133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_view.sample(getSampler(), s, t, lod);
49143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
49153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49163c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2D::sample4 (tcu::Vec4 output[4], const tcu::Vec2 packetTexcoords[4], float lodBias) const
49173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
49183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int texWidth  = m_view.getWidth();
49193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int texHeight = m_view.getHeight();
49203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec2 dFdx0 = packetTexcoords[1] - packetTexcoords[0];
49223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec2 dFdx1 = packetTexcoords[3] - packetTexcoords[2];
49233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec2 dFdy0 = packetTexcoords[2] - packetTexcoords[0];
49243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec2 dFdy1 = packetTexcoords[3] - packetTexcoords[1];
49253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
49273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
49283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2& dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
49293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2& dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;
49303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mu = de::max(de::abs(dFdx.x()), de::abs(dFdy.x()));
49323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mv = de::max(de::abs(dFdx.y()), de::abs(dFdy.y()));
49333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float p = de::max(mu * texWidth, mv * texHeight);
49343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lod = deFloatLog2(p) + lodBias;
49363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		output[fragNdx] = sample(packetTexcoords[fragNdx].x(), packetTexcoords[fragNdx].y(), lod);
49383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
49393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
49403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49413c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::TextureCube (deUint32 name)
49423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: Texture(name, TYPE_CUBE_MAP)
49433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
49443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
49453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCube::~TextureCube (void)
49473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
49483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
49493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::clearLevels (void)
49513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
49523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
49533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_levels[face].clear();
49543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
49553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::allocFace (int level, tcu::CubeFace face, const tcu::TextureFormat& format, int width, int height)
49573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
49583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_levels[face].allocLevel(level, format, width, height, 1);
49593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
49603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool TextureCube::isComplete (void) const
49623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
49633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	baseLevel	= getBaseLevel();
49643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasFace(baseLevel, tcu::CUBEFACE_NEGATIVE_X))
49663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
49673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int					width		= getFace(baseLevel, tcu::CUBEFACE_NEGATIVE_X).getWidth();
49683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int					height		= getFace(baseLevel, tcu::CUBEFACE_NEGATIVE_X).getHeight();
49693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::TextureFormat&	format		= getFace(baseLevel, tcu::CUBEFACE_NEGATIVE_X).getFormat();
49703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool					mipmap		= isMipmapFilter(getSampler().minFilter);
49713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int					numLevels	= mipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(width, height)) : 1;
49723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (width != height)
49743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false; // Non-square is not supported.
49753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note Level 0 is always checked for consistency
49773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
49783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
49793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int levelW	= getMipLevelSize(width,	levelNdx);
49803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int levelH	= getMipLevelSize(height,	levelNdx);
49813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
49833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
49843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (hasFace(baseLevel+levelNdx, (tcu::CubeFace)face))
49853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
49863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const tcu::ConstPixelBufferAccess& level = getFace(baseLevel+levelNdx, (tcu::CubeFace)face);
49873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (level.getWidth()	!= levelW	||
49893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getHeight()	!= levelH	||
49903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getFormat()	!= format)
49913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						return false;
49923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
49933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
49943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
49953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
49963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
49973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
49983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
49993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
50003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
50013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
50023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
50033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::updateView (void)
50053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
50063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int							baseLevel	= getBaseLevel();
50073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::ConstPixelBufferAccess*	faces[tcu::CUBEFACE_LAST];
50083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deMemset(&faces[0], 0, sizeof(faces));
50103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isComplete())
50123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
50133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	size		= getFace(baseLevel, tcu::CUBEFACE_NEGATIVE_X).getWidth();
50143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
50153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels1D(size)) : 1;
50163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
50183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			faces[face] = m_levels[face].getLevels() + baseLevel;
50193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::TextureCubeView(numLevels, faces);
50213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
50223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
50233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::TextureCubeView(0, faces);
50243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
50253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCube::sample (float s, float t, float p, float lod) const
50273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
50283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_view.sample(getSampler(), s, t, p, lod);
50293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
50303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCube::sample4 (tcu::Vec4 output[4], const tcu::Vec3 packetTexcoords[4], float lodBias) const
50323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
50333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	cubeSide	= m_view.getSize();
50343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Each tex coord might be in a different face.
50363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
50383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
50393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::CubeFace face		= tcu::selectCubeFace(packetTexcoords[fragNdx]);
50403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2		coords[4]	=
50413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
50423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, packetTexcoords[0]),
50433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, packetTexcoords[1]),
50443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, packetTexcoords[2]),
50453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, packetTexcoords[3]),
50463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
50473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdx0 = coords[1] - coords[0];
50493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdx1 = coords[3] - coords[2];
50503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdy0 = coords[2] - coords[0];
50513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdy1 = coords[3] - coords[1];
50523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2& dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
50543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2& dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;
50553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mu = de::max(de::abs(dFdx.x()), de::abs(dFdy.x()));
50573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mv = de::max(de::abs(dFdx.y()), de::abs(dFdy.y()));
50583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float p = de::max(mu * cubeSide, mv * cubeSide);
50593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lod = deFloatLog2(p) + lodBias;
50613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		output[fragNdx] = sample(packetTexcoords[fragNdx].x(), packetTexcoords[fragNdx].y(), packetTexcoords[fragNdx].z(), lod);
50633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
50643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
50653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50663c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::Texture2DArray (deUint32 name)
50673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: Texture	(name, TYPE_2D_ARRAY)
50683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view	(0, DE_NULL)
50693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
50703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
50713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50723c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture2DArray::~Texture2DArray (void)
50733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
50743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
50753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DArray::allocLevel (int level, const tcu::TextureFormat& format, int width, int height, int numLayers)
50773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
50783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_levels.allocLevel(level, format, width, height, numLayers);
50793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
50803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool Texture2DArray::isComplete (void) const
50823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
50833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	baseLevel	= getBaseLevel();
50843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel))
50863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
50873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::ConstPixelBufferAccess&	level0		= getLevel(baseLevel);
50883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool							mipmap		= isMipmapFilter(getSampler().minFilter);
50893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mipmap)
50913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
50923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const TextureFormat&	format		= level0.getFormat();
50933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				w			= level0.getWidth();
50943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				h			= level0.getHeight();
50953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLayers	= level0.getDepth();
50963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLevels	= de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(w, h));
50973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
50983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
50993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
51003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (hasLevel(baseLevel+levelNdx))
51013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
51023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const tcu::ConstPixelBufferAccess&	level		= getLevel(baseLevel+levelNdx);
51033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedW	= getMipLevelSize(w, levelNdx);
51043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedH	= getMipLevelSize(h, levelNdx);
51053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (level.getWidth()	!= expectedW	||
51073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getHeight()	!= expectedH	||
51083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getDepth()	!= numLayers	||
51093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getFormat()	!= format)
51103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						return false;
51113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
51123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
51133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
51143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
51153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
51163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
51183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
51193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
51203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
51213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
51223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DArray::updateView (void)
51243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
51253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int baseLevel	= getBaseLevel();
51263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel) && !isEmpty(getLevel(baseLevel)))
51283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
51293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	width		= getLevel(baseLevel).getWidth();
51303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	height		= getLevel(baseLevel).getHeight();
51313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
51323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(width, height)) : 1;
51333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::Texture2DArrayView(numLevels, m_levels.getLevels() + baseLevel);
51353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
51363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
51373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::Texture2DArrayView(0, DE_NULL);
51383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
51393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 Texture2DArray::sample (float s, float t, float r, float lod) const
51413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
51423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_view.sample(getSampler(), s, t, r, lod);
51433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
51443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture2DArray::sample4 (tcu::Vec4 output[4], const tcu::Vec3 packetTexcoords[4], float lodBias) const
51463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
51473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int texWidth  = m_view.getWidth();
51483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int texHeight = m_view.getHeight();
51493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdx0 = packetTexcoords[1] - packetTexcoords[0];
51513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdx1 = packetTexcoords[3] - packetTexcoords[2];
51523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdy0 = packetTexcoords[2] - packetTexcoords[0];
51533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdy1 = packetTexcoords[3] - packetTexcoords[1];
51543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
51563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
51573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec3& dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
51583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec3& dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;
51593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mu = de::max(de::abs(dFdx.x()), de::abs(dFdy.x()));
51613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mv = de::max(de::abs(dFdx.y()), de::abs(dFdy.y()));
51623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float p = de::max(mu * texWidth, mv * texHeight);
51633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lod = deFloatLog2(p) + lodBias;
51653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		output[fragNdx] = sample(packetTexcoords[fragNdx].x(), packetTexcoords[fragNdx].y(), packetTexcoords[fragNdx].z(), lod);
51673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
51683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
51693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::TextureCubeArray (deUint32 name)
51713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: Texture	(name, TYPE_CUBE_MAP_ARRAY)
51723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view	(0, DE_NULL)
51733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
51743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
51753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTextureCubeArray::~TextureCubeArray (void)
51773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
51783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
51793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeArray::allocLevel (int level, const tcu::TextureFormat& format, int width, int height, int numLayers)
51813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
51823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(numLayers % 6 == 0);
51833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_levels.allocLevel(level, format, width, height, numLayers);
51843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
51853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool TextureCubeArray::isComplete (void) const
51873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
51883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	baseLevel	= getBaseLevel();
51893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel))
51913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
51923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::ConstPixelBufferAccess&	level0		= getLevel(baseLevel);
51933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool							mipmap		= isMipmapFilter(getSampler().minFilter);
51943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
51953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mipmap)
51963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
51973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const TextureFormat&	format		= level0.getFormat();
51983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				w			= level0.getWidth();
51993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				h			= level0.getHeight();
52003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLayers	= level0.getDepth();
52013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLevels	= de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(w, h));
52023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
52043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
52053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (hasLevel(baseLevel+levelNdx))
52063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
52073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const tcu::ConstPixelBufferAccess&	level		= getLevel(baseLevel+levelNdx);
52083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedW	= getMipLevelSize(w, levelNdx);
52093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedH	= getMipLevelSize(h, levelNdx);
52103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (level.getWidth()	!= expectedW	||
52123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getHeight()	!= expectedH	||
52133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getDepth()	!= numLayers	||
52143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getFormat()	!= format)
52153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						return false;
52163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
52173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
52183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
52193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
52203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
52213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
52233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
52243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
52253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
52263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
52273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeArray::updateView (void)
52293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
52303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int baseLevel	= getBaseLevel();
52313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel) && !isEmpty(getLevel(baseLevel)))
52333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
52343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	width		= getLevel(baseLevel).getWidth();
52353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	height		= getLevel(baseLevel).getHeight();
52363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
52373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels2D(width, height)) : 1;
52383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::TextureCubeArrayView(numLevels, m_levels.getLevels() + baseLevel);
52403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
52413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
52423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::TextureCubeArrayView(0, DE_NULL);
52433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
52443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 TextureCubeArray::sample (float s, float t, float r, float q, float lod) const
52463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
52473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_view.sample(getSampler(), s, t, r, q, lod);
52483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
52493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid TextureCubeArray::sample4 (tcu::Vec4 output[4], const tcu::Vec4 packetTexcoords[4], float lodBias) const
52513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
52528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int		cubeSide		= m_view.getSize();
52533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3	cubeCoords[4]	=
52543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
52553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		packetTexcoords[0].toWidth<3>(),
52563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		packetTexcoords[1].toWidth<3>(),
52573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		packetTexcoords[2].toWidth<3>(),
52583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		packetTexcoords[3].toWidth<3>()
52593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
52603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
52623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
52633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::CubeFace face			= tcu::selectCubeFace(cubeCoords[fragNdx]);
52643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2		faceCoords[4]	=
52653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
52663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, cubeCoords[0]),
52673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, cubeCoords[1]),
52683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, cubeCoords[2]),
52693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::projectToFace(face, cubeCoords[3]),
52703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
52713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdx0 = faceCoords[1] - faceCoords[0];
52733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdx1 = faceCoords[3] - faceCoords[2];
52743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdy0 = faceCoords[2] - faceCoords[0];
52753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2 dFdy1 = faceCoords[3] - faceCoords[1];
52763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2& dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
52783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec2& dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;
52793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mu = de::max(de::abs(dFdx.x()), de::abs(dFdy.x()));
52813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mv = de::max(de::abs(dFdx.y()), de::abs(dFdy.y()));
52823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float p = de::max(mu * cubeSide, mv * cubeSide);
52833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lod = deFloatLog2(p) + lodBias;
52853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		output[fragNdx] = sample(packetTexcoords[fragNdx].x(), packetTexcoords[fragNdx].y(), packetTexcoords[fragNdx].z(), packetTexcoords[fragNdx].w(), lod);
52873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
52883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
52893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52903c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::Texture3D (deUint32 name)
52913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: Texture	(name, TYPE_3D)
52923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_view	(0, DE_NULL)
52933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
52943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
52953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
52963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexture3D::~Texture3D (void)
52973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
52983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
52993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3D::allocLevel (int level, const tcu::TextureFormat& format, int width, int height, int depth)
53013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
53023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_levels.allocLevel(level, format, width, height, depth);
53033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
53043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool Texture3D::isComplete (void) const
53063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
53073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	baseLevel	= getBaseLevel();
53083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel))
53103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
53113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::ConstPixelBufferAccess&	level0		= getLevel(baseLevel);
53123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool							mipmap		= isMipmapFilter(getSampler().minFilter);
53133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (mipmap)
53153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
53163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const TextureFormat&	format		= level0.getFormat();
53173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				w			= level0.getWidth();
53183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				h			= level0.getHeight();
53193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				d			= level0.getDepth();
53203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const int				numLevels	= de::min(getMaxLevel()-baseLevel+1, getNumMipLevels3D(w, h, d));
53213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 1; levelNdx < numLevels; levelNdx++)
53233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
53243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (hasLevel(baseLevel+levelNdx))
53253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
53263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const tcu::ConstPixelBufferAccess&	level		= getLevel(baseLevel+levelNdx);
53273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedW	= getMipLevelSize(w, levelNdx);
53283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedH	= getMipLevelSize(h, levelNdx);
53293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int							expectedD	= getMipLevelSize(d, levelNdx);
53303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					if (level.getWidth()	!= expectedW	||
53323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getHeight()	!= expectedH	||
53333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getDepth()	!= expectedD	||
53343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						level.getFormat()	!= format)
53353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						return false;
53363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
53373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
53383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					return false;
53393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
53403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
53413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return true;
53433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
53443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
53453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
53463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
53473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytcu::Vec4 Texture3D::sample (float s, float t, float r, float lod) const
53493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
53503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_view.sample(getSampler(), s, t, r, lod);
53513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
53523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3D::sample4 (tcu::Vec4 output[4], const tcu::Vec3 packetTexcoords[4], float lodBias) const
53543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
53553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int texWidth  = m_view.getWidth();
53563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int texHeight = m_view.getHeight();
53573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int texDepth  = m_view.getDepth();
53583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdx0 = packetTexcoords[1] - packetTexcoords[0];
53603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdx1 = packetTexcoords[3] - packetTexcoords[2];
53613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdy0 = packetTexcoords[2] - packetTexcoords[0];
53623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Vec3 dFdy1 = packetTexcoords[3] - packetTexcoords[1];
53633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
53653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
53663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec3& dFdx = (fragNdx & 2) ? dFdx1 : dFdx0;
53673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::Vec3& dFdy = (fragNdx & 1) ? dFdy1 : dFdy0;
53683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mu = de::max(de::abs(dFdx.x()), de::abs(dFdy.x()));
53703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mv = de::max(de::abs(dFdx.y()), de::abs(dFdy.y()));
53713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float mw = de::max(de::abs(dFdx.z()), de::abs(dFdy.z()));
53723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float p = de::max(de::max(mu * texWidth, mv * texHeight), mw * texDepth);
53733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float	lod = deFloatLog2(p) + lodBias;
53753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		output[fragNdx] = sample(packetTexcoords[fragNdx].x(), packetTexcoords[fragNdx].y(), packetTexcoords[fragNdx].z(), lod);
53773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
53783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
53793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Texture3D::updateView (void)
53813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
53823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int baseLevel	= getBaseLevel();
53833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (hasLevel(baseLevel) && !isEmpty(getLevel(baseLevel)))
53853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
53863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	width		= getLevel(baseLevel).getWidth();
53873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	height		= getLevel(baseLevel).getHeight();
53883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	depth		= getLevel(baseLevel).getDepth();
53893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	isMipmap	= isMipmapFilter(getSampler().minFilter);
53903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	numLevels	= isMipmap ? de::min(getMaxLevel()-baseLevel+1, getNumMipLevels3D(width, height, depth)) : 1;
53913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::Texture3DView(numLevels, m_levels.getLevels() + baseLevel);
53933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
53943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
53953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_view = tcu::Texture3DView(0, DE_NULL);
53963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
53973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
53983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRenderbuffer::Renderbuffer (deUint32 name)
53993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: NamedObject		(name)
54003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
54013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
54023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54033c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRenderbuffer::~Renderbuffer (void)
54043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
54053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
54063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54073c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Renderbuffer::setStorage (const TextureFormat& format, int width, int height)
54083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
54093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_data.setStorage(format, width, height);
54103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
54113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFramebuffer::Framebuffer (deUint32 name)
54133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: NamedObject(name)
54143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
54153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
54163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryFramebuffer::~Framebuffer (void)
54183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
54193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
54203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54213c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexArray::VertexArray (deUint32 name, int maxVertexAttribs)
54223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: NamedObject					(name)
54233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_elementArrayBufferBinding	(DE_NULL)
54243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_arrays						(maxVertexAttribs)
54253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
54263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < maxVertexAttribs; ++i)
54273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
54283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].enabled			= false;
54293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].size			= 4;
54303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].stride			= 0;
54313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].type			= GL_FLOAT;
54323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].normalized		= false;
54333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].integer			= false;
54343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].divisor			= 0;
54353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].bufferDeleted	= false;
54363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].bufferBinding	= DE_NULL;
54373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_arrays[i].pointer			= DE_NULL;
54383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
54393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
54403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54413c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgramObjectContainer::ShaderProgramObjectContainer (deUint32 name, ShaderProgram* program)
54423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: NamedObject	(name)
54433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program		(program)
54443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_deleteFlag	(false)
54453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
54463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
54473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderProgramObjectContainer::~ShaderProgramObjectContainer (void)
54493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
54503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
54513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
54523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // rc
54533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // sglr
5454