Merge "Avoid accessing border color directly in tcuTexture."
diff --git a/external/fetch_sources.py b/external/fetch_sources.py
index 7d4c5c7..5f6a30f 100644
--- a/external/fetch_sources.py
+++ b/external/fetch_sources.py
@@ -93,9 +93,9 @@
 				  "zlib-1.2.8.tar.gz",
 				  "36658cb768a54c1d4dec43c3116c27ed893e88b02ecfcb44f2166f9c0b7f2a0d",
 				  "zlib"),
-	SourcePackage("ftp://ftp.simplesystems.org/pub/libpng/png/src/libpng16/libpng-1.6.16.tar.gz",
-				  "libpng-1.6.14.tar.gz",
-				  "02f96b6bad5a381d36d7ba7a5d9be3b06f7fe6c274da00707509c23592a073ad",
+	SourcePackage("ftp://ftp.simplesystems.org/pub/libpng/png/src/libpng16/libpng-1.6.17.tar.gz",
+				  "libpng-1.6.17.tar.gz",
+				  "a18233c99e1dc59a256180e6871d9305a42e91b3f98799b3ceb98e87e9ec5e31",
 				  "libpng",
 				  postExtract = postExtractLibpng),
 ]
diff --git a/framework/common/tcuCompressedTexture.cpp b/framework/common/tcuCompressedTexture.cpp
index 0ea7f95..c911576 100644
--- a/framework/common/tcuCompressedTexture.cpp
+++ b/framework/common/tcuCompressedTexture.cpp
@@ -2605,7 +2605,7 @@
 
 		decompressBlock(fmt, blockAccess, blockPtr, params);
 
-		copyRawPixels(getSubregion(dst, dstPixelPos.x(), dstPixelPos.y(), dstPixelPos.z(), copySize.x(), copySize.y(), copySize.z()), getSubregion(blockAccess, 0, 0, 0, copySize.x(), copySize.y(), copySize.z()));
+		copy(getSubregion(dst, dstPixelPos.x(), dstPixelPos.y(), dstPixelPos.z(), copySize.x(), copySize.y(), copySize.z()), getSubregion(blockAccess, 0, 0, 0, copySize.x(), copySize.y(), copySize.z()));
 	}
 }
 
diff --git a/framework/common/tcuTexCompareVerifier.cpp b/framework/common/tcuTexCompareVerifier.cpp
index ec3b635..9806c70 100644
--- a/framework/common/tcuTexCompareVerifier.cpp
+++ b/framework/common/tcuTexCompareVerifier.cpp
@@ -44,6 +44,11 @@
 }
 #endif // DE_DEBUG
 
+static inline float lookupDepth (const ConstPixelBufferAccess& access, int i, int j, int k = 0)
+{
+	return access.getPixDepth(i, j, k);
+}
+
 struct CmpResultSet
 {
 	bool	isTrue;
@@ -538,7 +543,7 @@
 		{
 			const int			x		= wrap(sampler.wrapS, i, level.getWidth());
 			const int			y		= wrap(sampler.wrapT, j, level.getHeight());
-			const float			depth	= level.getPixDepth(x, y, coordZ);
+			const float			depth	= lookupDepth(level, x, y, coordZ);
 			const CmpResultSet	resSet	= execCompare(sampler.compare, depth, cmpReference, prec.referenceBits, isFixedPointDepth);
 
 			if (isResultInSet(resSet, result, prec.resultBits))
@@ -588,10 +593,10 @@
 			const float	minB	= de::clamp((vBounds.x()-0.5f)-float(j), 0.0f, 1.0f);
 			const float	maxB	= de::clamp((vBounds.y()-0.5f)-float(j), 0.0f, 1.0f);
 
-			const Vec4	depths	(level.getPixDepth(x0, y0, coordZ),
-								 level.getPixDepth(x1, y0, coordZ),
-								 level.getPixDepth(x0, y1, coordZ),
-								 level.getPixDepth(x1, y1, coordZ));
+			const Vec4	depths	(lookupDepth(level, x0, y0, coordZ),
+								 lookupDepth(level, x1, y0, coordZ),
+								 lookupDepth(level, x0, y1, coordZ),
+								 lookupDepth(level, x1, y1, coordZ));
 
 			if (isBilinearCompareValid(sampler.compare, prec, depths, Vec2(minA, maxA), Vec2(minB, maxB), cmpReference, result, isFixedPointDepth))
 				return true;
@@ -652,13 +657,13 @@
 	{
 		for (int i0 = minI0; i0 <= maxI0; i0++)
 		{
-			const float	depth0	= level0.getPixDepth(wrap(sampler.wrapS, i0, w0), wrap(sampler.wrapT, j0, h0), coordZ);
+			const float	depth0	= lookupDepth(level0, wrap(sampler.wrapS, i0, w0), wrap(sampler.wrapT, j0, h0), coordZ);
 
 			for (int j1 = minJ1; j1 <= maxJ1; j1++)
 			{
 				for (int i1 = minI1; i1 <= maxI1; i1++)
 				{
-					const float	depth1	= level1.getPixDepth(wrap(sampler.wrapS, i1, w1), wrap(sampler.wrapT, j1, h1), coordZ);
+					const float	depth1	= lookupDepth(level1, wrap(sampler.wrapS, i1, w1), wrap(sampler.wrapT, j1, h1), coordZ);
 
 					if (isLinearCompareValid(sampler.compare, prec, Vec2(depth0, depth1), fBounds, cmpReference, result, isFixedPointDepth))
 						return true;
@@ -721,10 +726,10 @@
 				const int	y0		= wrap(sampler.wrapT, j0  , h0);
 				const int	y1		= wrap(sampler.wrapT, j0+1, h0);
 
-				depths0[0] = level0.getPixDepth(x0, y0, coordZ);
-				depths0[1] = level0.getPixDepth(x1, y0, coordZ);
-				depths0[2] = level0.getPixDepth(x0, y1, coordZ);
-				depths0[3] = level0.getPixDepth(x1, y1, coordZ);
+				depths0[0] = lookupDepth(level0, x0, y0, coordZ);
+				depths0[1] = lookupDepth(level0, x1, y0, coordZ);
+				depths0[2] = lookupDepth(level0, x0, y1, coordZ);
+				depths0[3] = lookupDepth(level0, x1, y1, coordZ);
 			}
 
 			for (int j1 = minJ1; j1 <= maxJ1; j1++)
@@ -743,10 +748,10 @@
 						const int	y0		= wrap(sampler.wrapT, j1  , h1);
 						const int	y1		= wrap(sampler.wrapT, j1+1, h1);
 
-						depths1[0] = level1.getPixDepth(x0, y0, coordZ);
-						depths1[1] = level1.getPixDepth(x1, y0, coordZ);
-						depths1[2] = level1.getPixDepth(x0, y1, coordZ);
-						depths1[3] = level1.getPixDepth(x1, y1, coordZ);
+						depths1[0] = lookupDepth(level1, x0, y0, coordZ);
+						depths1[1] = lookupDepth(level1, x1, y0, coordZ);
+						depths1[2] = lookupDepth(level1, x0, y1, coordZ);
+						depths1[3] = lookupDepth(level1, x1, y1, coordZ);
 					}
 
 					if (isTrilinearCompareValid(sampler.compare, prec, depths0, depths1,
@@ -908,10 +913,10 @@
 				if (c00.face == CUBEFACE_LAST || c01.face == CUBEFACE_LAST || c10.face == CUBEFACE_LAST || c11.face == CUBEFACE_LAST)
 					return true;
 
-				depths0[0] = faces0[c00.face].getPixDepth(c00.s, c00.t);
-				depths0[1] = faces0[c10.face].getPixDepth(c10.s, c10.t);
-				depths0[2] = faces0[c01.face].getPixDepth(c01.s, c01.t);
-				depths0[3] = faces0[c11.face].getPixDepth(c11.s, c11.t);
+				depths0[0] = lookupDepth(faces0[c00.face], c00.s, c00.t);
+				depths0[1] = lookupDepth(faces0[c10.face], c10.s, c10.t);
+				depths0[2] = lookupDepth(faces0[c01.face], c01.s, c01.t);
+				depths0[3] = lookupDepth(faces0[c11.face], c11.s, c11.t);
 			}
 
 			for (int j1 = minJ1; j1 <= maxJ1; j1++)
@@ -933,10 +938,10 @@
 						if (c00.face == CUBEFACE_LAST || c01.face == CUBEFACE_LAST || c10.face == CUBEFACE_LAST || c11.face == CUBEFACE_LAST)
 							return true;
 
-						depths1[0] = faces1[c00.face].getPixDepth(c00.s, c00.t);
-						depths1[1] = faces1[c10.face].getPixDepth(c10.s, c10.t);
-						depths1[2] = faces1[c01.face].getPixDepth(c01.s, c01.t);
-						depths1[3] = faces1[c11.face].getPixDepth(c11.s, c11.t);
+						depths1[0] = lookupDepth(faces1[c00.face], c00.s, c00.t);
+						depths1[1] = lookupDepth(faces1[c10.face], c10.s, c10.t);
+						depths1[2] = lookupDepth(faces1[c01.face], c01.s, c01.t);
+						depths1[3] = lookupDepth(faces1[c11.face], c11.s, c11.t);
 					}
 
 
@@ -1024,10 +1029,10 @@
 			const float	maxB	= de::clamp((vBounds.y()-0.5f)-float(j), 0.0f, 1.0f);
 
 			Vec4 depths;
-			depths[0] = faces[c00.face].getPixDepth(c00.s, c00.t);
-			depths[1] = faces[c10.face].getPixDepth(c10.s, c10.t);
-			depths[2] = faces[c01.face].getPixDepth(c01.s, c01.t);
-			depths[3] = faces[c11.face].getPixDepth(c11.s, c11.t);
+			depths[0] = lookupDepth(faces[c00.face], c00.s, c00.t);
+			depths[1] = lookupDepth(faces[c10.face], c10.s, c10.t);
+			depths[2] = lookupDepth(faces[c01.face], c01.s, c01.t);
+			depths[3] = lookupDepth(faces[c11.face], c11.s, c11.t);
 
 			if (isBilinearCompareValid(sampler.compare, prec, depths, Vec2(minA, maxA), Vec2(minB, maxB), cmpReference, result, isFixedPointDepth))
 				return true;
@@ -1142,6 +1147,8 @@
 	const int		minLayer	= de::clamp(deFloorFloatToInt32(minZ + 0.5f), 0, texture.getNumLayers()-1);
 	const int		maxLayer	= de::clamp(deFloorFloatToInt32(maxZ + 0.5f), 0, texture.getNumLayers()-1);
 
+	DE_ASSERT(isSamplerSupported(sampler));
+
 	for (int layer = minLayer; layer <= maxLayer; layer++)
 	{
 		const float		minLod			= lodBounds.x();
@@ -1149,8 +1156,6 @@
 		const bool		canBeMagnified	= minLod <= sampler.lodThreshold;
 		const bool		canBeMinified	= maxLod > sampler.lodThreshold;
 
-		DE_ASSERT(isSamplerSupported(sampler));
-
 		if (canBeMagnified)
 		{
 			if (isLevelCompareResultValid(texture.getLevel(0), sampler, sampler.magFilter, prec, coord.swizzle(0,1), layer, cmpReference, result))
@@ -1241,7 +1246,7 @@
 				// offNdx-th coordinate offset and then wrapped.
 				const int			x		= wrap(sampler.wrapS, i+offsets[offNdx].x(), w);
 				const int			y		= wrap(sampler.wrapT, j+offsets[offNdx].y(), h);
-				const float			depth	= texture.getPixDepth(x, y, coordZ);
+				const float			depth	= lookupDepth(texture, x, y, coordZ);
 				const CmpResultSet	resSet	= execCompare(sampler.compare, depth, cmpReference, prec.referenceBits, isFixedPointDepth);
 
 				if (!isResultInSet(resSet, result[offNdx], prec.resultBits))
@@ -1264,6 +1269,8 @@
 										float						cmpReference,
 										const Vec4&					result)
 {
+	DE_ASSERT(isSamplerSupported(sampler));
+
 	return isGatherOffsetsCompareResultValid(texture.getLevel(0), sampler, prec, coord, 0, offsets, cmpReference, result);
 }
 
@@ -1281,6 +1288,8 @@
 	const int		minLayer	= de::clamp(deFloorFloatToInt32(minZ + 0.5f), 0, texture.getNumLayers()-1);
 	const int		maxLayer	= de::clamp(deFloorFloatToInt32(maxZ + 0.5f), 0, texture.getNumLayers()-1);
 
+	DE_ASSERT(isSamplerSupported(sampler));
+
 	for (int layer = minLayer; layer <= maxLayer; layer++)
 	{
 		if (isGatherOffsetsCompareResultValid(texture.getLevel(0), sampler, prec, coord.swizzle(0,1), layer, offsets, cmpReference, result))
@@ -1335,7 +1344,7 @@
 				if (c.face == CUBEFACE_LAST)
 					return true;
 
-				const float			depth	= faces[c.face].getPixDepth(c.s, c.t);
+				const float			depth	= lookupDepth(faces[c.face], c.s, c.t);
 				const CmpResultSet	resSet	= execCompare(sampler.compare, depth, cmpReference, prec.referenceBits, isFixedPointDepth);
 
 				if (!isResultInSet(resSet, result[offNdx], prec.resultBits))
@@ -1360,6 +1369,8 @@
 	int			numPossibleFaces				= 0;
 	CubeFace	possibleFaces[CUBEFACE_LAST];
 
+	DE_ASSERT(isSamplerSupported(sampler));
+
 	getPossibleCubeFaces(coord, prec.coordBits, &possibleFaces[0], numPossibleFaces);
 
 	if (numPossibleFaces == 0)
diff --git a/framework/common/tcuTexture.hpp b/framework/common/tcuTexture.hpp
index 8b788c9..2fb0d6a 100644
--- a/framework/common/tcuTexture.hpp
+++ b/framework/common/tcuTexture.hpp
@@ -289,12 +289,16 @@
 	int						getWidth					(void) const	{ return m_size.x();				}
 	int						getHeight					(void) const	{ return m_size.y();				}
 	int						getDepth					(void) const	{ return m_size.z();				}
+	int						getPixelPitch				(void) const	{ return m_pitch.x();				}
 	int						getRowPitch					(void) const	{ return m_pitch.y();				}
 	int						getSlicePitch				(void) const	{ return m_pitch.z();				}
+	const IVec3&			getPitch					(void) const	{ return m_pitch;					}
 
 	const void*				getDataPtr					(void) const	{ return m_data;					}
 	int						getDataSize					(void) const	{ return m_size.z()*m_pitch.z();	}
 
+	const void*				getPixelPtr					(int x, int y, int z = 0) const { return (const deUint8*)m_data + x * m_pitch.x() + y * m_pitch.y() + z * m_pitch.z(); }
+
 	Vec4					getPixel					(int x, int y, int z = 0) const;
 	IVec4					getPixelInt					(int x, int y, int z = 0) const;
 	UVec4					getPixelUint				(int x, int y, int z = 0) const { return getPixelInt(x, y, z).cast<deUint32>(); }
@@ -343,6 +347,7 @@
 						PixelBufferAccess	(const TextureFormat& format, const IVec3& size, const IVec3& pitch, void* data);
 
 	void*				getDataPtr			(void) const { return m_data; }
+	void*				getPixelPtr			(int x, int y, int z = 0) const { return (deUint8*)m_data + x * m_pitch.x() + y * m_pitch.y() + z * m_pitch.z(); }
 
 	void				setPixels			(const void* buf, int bufSize) const;
 	void				setPixel			(const tcu::Vec4& color, int x, int y, int z = 0) const;
diff --git a/framework/common/tcuTextureUtil.cpp b/framework/common/tcuTextureUtil.cpp
index cf5475f..4c4aceb8d 100644
--- a/framework/common/tcuTextureUtil.cpp
+++ b/framework/common/tcuTextureUtil.cpp
@@ -138,8 +138,8 @@
 	DE_ASSERT(de::inBounds(z, 0, access.getDepth()));
 	DE_ASSERT(de::inRange(z+depth, z+1, access.getDepth()));
 
-	return ConstPixelBufferAccess(access.getFormat(), width, height, depth, access.getRowPitch(), access.getSlicePitch(),
-								  (const deUint8*)access.getDataPtr() + access.getFormat().getPixelSize()*x + access.getRowPitch()*y + access.getSlicePitch()*z);
+	return ConstPixelBufferAccess(access.getFormat(), tcu::IVec3(width, height, depth), access.getPitch(),
+								  (const deUint8*)access.getDataPtr() + access.getPixelPitch()*x + access.getRowPitch()*y + access.getSlicePitch()*z);
 }
 
 /*--------------------------------------------------------------------*//*!
@@ -164,8 +164,8 @@
 	DE_ASSERT(de::inBounds(z, 0, access.getDepth()));
 	DE_ASSERT(de::inRange(z+depth, z+1, access.getDepth()));
 
-	return PixelBufferAccess(access.getFormat(), width, height, depth, access.getRowPitch(), access.getSlicePitch(),
-							 (deUint8*)access.getDataPtr() + access.getFormat().getPixelSize()*x + access.getRowPitch()*y + access.getSlicePitch()*z);
+	return PixelBufferAccess(access.getFormat(), tcu::IVec3(width, height, depth), access.getPitch(),
+							 (deUint8*)access.getDataPtr() + access.getPixelPitch()*x + access.getRowPitch()*y + access.getSlicePitch()*z);
 }
 
 /*--------------------------------------------------------------------*//*!
@@ -203,11 +203,11 @@
  *//*--------------------------------------------------------------------*/
 PixelBufferAccess flipYAccess (const PixelBufferAccess& access)
 {
-	const int	rowPitch		= access.getRowPitch();
-	const int	offsetToLast	= rowPitch*(access.getHeight()-1);
+	const int			rowPitch		= access.getRowPitch();
+	const int			offsetToLast	= rowPitch*(access.getHeight()-1);
+	const tcu::IVec3	pitch			(access.getPixelPitch(), -rowPitch, access.getSlicePitch());
 
-	return PixelBufferAccess(access.getFormat(), access.getWidth(), access.getHeight(), access.getDepth(),
-							 -rowPitch, access.getSlicePitch(), (deUint8*)access.getDataPtr() + offsetToLast);
+	return PixelBufferAccess(access.getFormat(), access.getSize(), pitch, (deUint8*)access.getDataPtr() + offsetToLast);
 }
 
 /*--------------------------------------------------------------------*//*!
@@ -217,11 +217,11 @@
  *//*--------------------------------------------------------------------*/
 ConstPixelBufferAccess flipYAccess (const ConstPixelBufferAccess& access)
 {
-	const int	rowPitch		= access.getRowPitch();
-	const int	offsetToLast	= rowPitch*(access.getHeight()-1);
+	const int			rowPitch		= access.getRowPitch();
+	const int			offsetToLast	= rowPitch*(access.getHeight()-1);
+	const tcu::IVec3	pitch			(access.getPixelPitch(), -rowPitch, access.getSlicePitch());
 
-	return ConstPixelBufferAccess(access.getFormat(), access.getWidth(), access.getHeight(), access.getDepth(),
-								  -rowPitch, access.getSlicePitch(), (const deUint8*)access.getDataPtr() + offsetToLast);
+	return ConstPixelBufferAccess(access.getFormat(), access.getSize(), pitch, (deUint8*)access.getDataPtr() + offsetToLast);
 }
 
 static Vec2 getChannelValueRange (TextureFormat::ChannelType channelType)
@@ -422,6 +422,15 @@
 	return select(chnBits.swizzle(chnSwz.x(), chnSwz.y(), chnSwz.z(), chnSwz.w()), IVec4(0), chnMask);
 }
 
+BVec4 getTextureFormatChannelMask (const TextureFormat& format)
+{
+	const TextureSwizzle::Channel* const map = getChannelReadSwizzle(format.order).components;
+	return BVec4(deInRange32(map[0], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE,
+				 deInRange32(map[1], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE,
+				 deInRange32(map[2], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE,
+				 deInRange32(map[3], TextureSwizzle::CHANNEL_0, TextureSwizzle::CHANNEL_3) == DE_TRUE);
+}
+
 static inline float linearInterpolate (float t, float minVal, float maxVal)
 {
 	return minVal + (maxVal - minVal) * t;
@@ -469,9 +478,12 @@
 
 void clear (const PixelBufferAccess& access, const Vec4& color)
 {
-	int pixelSize = access.getFormat().getPixelSize();
+	const int	pixelSize				= access.getFormat().getPixelSize();
+	const int	pixelPitch				= access.getPixelPitch();
+	const bool	rowPixelsTightlyPacked	= (pixelSize == pixelPitch);
+
 	if (access.getWidth()*access.getHeight()*access.getDepth() >= CLEAR_OPTIMIZE_THRESHOLD &&
-		pixelSize < CLEAR_OPTIMIZE_MAX_PIXEL_SIZE)
+		pixelSize < CLEAR_OPTIMIZE_MAX_PIXEL_SIZE && rowPixelsTightlyPacked)
 	{
 		// Convert to destination format.
 		union
@@ -497,9 +509,12 @@
 
 void clear (const PixelBufferAccess& access, const IVec4& color)
 {
-	int pixelSize = access.getFormat().getPixelSize();
+	const int	pixelSize				= access.getFormat().getPixelSize();
+	const int	pixelPitch				= access.getPixelPitch();
+	const bool	rowPixelsTightlyPacked	= (pixelSize == pixelPitch);
+
 	if (access.getWidth()*access.getHeight()*access.getDepth() >= CLEAR_OPTIMIZE_THRESHOLD &&
-		pixelSize < CLEAR_OPTIMIZE_MAX_PIXEL_SIZE)
+		pixelSize < CLEAR_OPTIMIZE_MAX_PIXEL_SIZE && rowPixelsTightlyPacked)
 	{
 		// Convert to destination format.
 		union
@@ -530,9 +545,12 @@
 
 void clearDepth (const PixelBufferAccess& access, float depth)
 {
-	int pixelSize = access.getFormat().getPixelSize();
+	const int	pixelSize				= access.getFormat().getPixelSize();
+	const int	pixelPitch				= access.getPixelPitch();
+	const bool	rowPixelsTightlyPacked	= (pixelSize == pixelPitch);
+
 	if (access.getWidth()*access.getHeight()*access.getDepth() >= CLEAR_OPTIMIZE_THRESHOLD &&
-		pixelSize < CLEAR_OPTIMIZE_MAX_PIXEL_SIZE)
+		pixelSize < CLEAR_OPTIMIZE_MAX_PIXEL_SIZE && rowPixelsTightlyPacked)
 	{
 		// Convert to destination format.
 		union
@@ -558,9 +576,12 @@
 
 void clearStencil (const PixelBufferAccess& access, int stencil)
 {
-	int pixelSize = access.getFormat().getPixelSize();
+	const int	pixelSize				= access.getFormat().getPixelSize();
+	const int	pixelPitch				= access.getPixelPitch();
+	const bool	rowPixelsTightlyPacked	= (pixelSize == pixelPitch);
+
 	if (access.getWidth()*access.getHeight()*access.getDepth() >= CLEAR_OPTIMIZE_THRESHOLD &&
-		pixelSize < CLEAR_OPTIMIZE_MAX_PIXEL_SIZE)
+		pixelSize < CLEAR_OPTIMIZE_MAX_PIXEL_SIZE && rowPixelsTightlyPacked)
 	{
 		// Convert to destination format.
 		union
@@ -779,22 +800,33 @@
 
 void copy (const PixelBufferAccess& dst, const ConstPixelBufferAccess& src)
 {
-	int		width		= dst.getWidth();
-	int		height		= dst.getHeight();
-	int		depth		= dst.getDepth();
+	DE_ASSERT(src.getSize() == dst.getSize());
 
-	DE_ASSERT(src.getWidth() == width && src.getHeight() == height && src.getDepth() == depth);
+	const int	width				= dst.getWidth();
+	const int	height				= dst.getHeight();
+	const int	depth				= dst.getDepth();
 
-	if (src.getFormat() == dst.getFormat())
+	const int	srcPixelSize		= src.getFormat().getPixelSize();
+	const int	dstPixelSize		= dst.getFormat().getPixelSize();
+	const int	srcPixelPitch		= src.getPixelPitch();
+	const int	dstPixelPitch		= dst.getPixelPitch();
+	const bool	srcTightlyPacked	= (srcPixelSize == srcPixelPitch);
+	const bool	dstTightlyPacked	= (dstPixelSize == dstPixelPitch);
+
+	if (src.getFormat() == dst.getFormat() && srcTightlyPacked && dstTightlyPacked)
 	{
 		// Fast-path for matching formats.
-		int pixelSize = src.getFormat().getPixelSize();
-
 		for (int z = 0; z < depth; z++)
 		for (int y = 0; y < height; y++)
-			deMemcpy((deUint8*)dst.getDataPtr()			+ z*dst.getSlicePitch() + y*dst.getRowPitch(),
-					 (const deUint8*)src.getDataPtr()	+ z*src.getSlicePitch() + y*src.getRowPitch(),
-					 pixelSize*width);
+			deMemcpy(dst.getPixelPtr(0, y, z), src.getPixelPtr(0, y, z), srcPixelSize*width);
+	}
+	else if (src.getFormat() == dst.getFormat())
+	{
+		// Bit-exact copy for matching formats.
+		for (int z = 0; z < depth; z++)
+		for (int y = 0; y < height; y++)
+		for (int x = 0; x < width; x++)
+			deMemcpy(dst.getPixelPtr(x, y, z), src.getPixelPtr(x, y, z), srcPixelSize);
 	}
 	else
 	{
@@ -935,30 +967,6 @@
 	}
 }
 
-void copyRawPixels (const PixelBufferAccess& dst, const ConstPixelBufferAccess& src)
-{
-	DE_ASSERT(dst.getFormat().getPixelSize() == src.getFormat().getPixelSize());
-	DE_ASSERT(dst.getWidth() == src.getWidth());
-	DE_ASSERT(dst.getHeight() == src.getHeight());
-	DE_ASSERT(dst.getDepth() == src.getDepth());
-
-	const int pixelSize = dst.getFormat().getPixelSize();
-
-	for (int z = 0; z < dst.getDepth(); z++)
-	for (int y = 0; y < dst.getHeight(); y++)
-	{
-		const deUint8* const	srcPtr	= (const deUint8*)src.getDataPtr()
-										+ src.getRowPitch() * y
-										+ src.getSlicePitch() * z;
-
-		deUint8* const			dstPtr	= (deUint8*)dst.getDataPtr()
-										+ dst.getRowPitch() * y
-										+ dst.getSlicePitch() * z;
-
-		deMemcpy(dstPtr, srcPtr, dst.getWidth() * pixelSize);
-	}
-}
-
 deUint32 packRGB999E5 (const tcu::Vec4& color)
 {
 	const int	mBits	= 9;
diff --git a/framework/common/tcuTextureUtil.hpp b/framework/common/tcuTextureUtil.hpp
index 643a567..d9f07c8 100644
--- a/framework/common/tcuTextureUtil.hpp
+++ b/framework/common/tcuTextureUtil.hpp
@@ -82,6 +82,7 @@
 TextureFormatInfo	getTextureFormatInfo				(const TextureFormat& format);
 IVec4				getTextureFormatBitDepth			(const TextureFormat& format);
 IVec4				getTextureFormatMantissaBitDepth	(const TextureFormat& format);
+BVec4				getTextureFormatChannelMask			(const TextureFormat& format);
 
 // Texture fill.
 void	clear							(const PixelBufferAccess& access, const Vec4& color);
@@ -95,11 +96,10 @@
 void	fillWithMetaballs				(const PixelBufferAccess& access, int numMetaballs, deUint32 seed);
 void	fillWithRGBAQuads				(const PixelBufferAccess& access);
 
+//! Copies contents of src to dst. If formats of dst and src are equal, a bit-exact copy is made.
 void	copy							(const PixelBufferAccess& dst, const ConstPixelBufferAccess& src);
-void	scale							(const PixelBufferAccess& dst, const ConstPixelBufferAccess& src, Sampler::FilterMode filter);
 
-// Copy raw pixel data between buffers. Both buffers must have same pixel size.
-void	copyRawPixels					(const PixelBufferAccess& dst, const ConstPixelBufferAccess& src);
+void	scale							(const PixelBufferAccess& dst, const ConstPixelBufferAccess& src, Sampler::FilterMode filter);
 
 void	estimatePixelValueRange			(const ConstPixelBufferAccess& access, Vec4& minVal, Vec4& maxVal);
 void	computePixelScaleBias			(const ConstPixelBufferAccess& access, Vec4& scale, Vec4& bias);
diff --git a/framework/opengl/gluCallLogWrapper.inl b/framework/opengl/gluCallLogWrapper.inl
index c056cab..d95b415 100644
--- a/framework/opengl/gluCallLogWrapper.inl
+++ b/framework/opengl/gluCallLogWrapper.inl
@@ -1947,7 +1947,7 @@
 		m_log << TestLog::Message << "glGetSamplerParameterfv(" << sampler << ", " << getTextureParameterStr(pname) << ", " << toHex(reinterpret_cast<deUintptr>(static_cast<const void*>(params))) << ");" << TestLog::EndMessage;
 	m_gl.getSamplerParameterfv(sampler, pname, params);
 	if (m_enableLog)
-		m_log << TestLog::Message << "// params = " << getPointerStr(params, 1) << TestLog::EndMessage;
+		m_log << TestLog::Message << "// params = " << getPointerStr(params, getTextureParamQueryNumArgsOut(pname)) << TestLog::EndMessage;
 }
 
 void CallLogWrapper::glGetSamplerParameteriv (glw::GLuint sampler, glw::GLenum pname, glw::GLint *params)
@@ -1956,7 +1956,7 @@
 		m_log << TestLog::Message << "glGetSamplerParameteriv(" << sampler << ", " << getTextureParameterStr(pname) << ", " << toHex(reinterpret_cast<deUintptr>(static_cast<const void*>(params))) << ");" << TestLog::EndMessage;
 	m_gl.getSamplerParameteriv(sampler, pname, params);
 	if (m_enableLog)
-		m_log << TestLog::Message << "// params = " << getPointerStr(params, 1) << TestLog::EndMessage;
+		m_log << TestLog::Message << "// params = " << getPointerStr(params, getTextureParamQueryNumArgsOut(pname)) << TestLog::EndMessage;
 }
 
 void CallLogWrapper::glGetShaderInfoLog (glw::GLuint shader, glw::GLsizei bufSize, glw::GLsizei *length, glw::GLchar *infoLog)
@@ -2087,7 +2087,7 @@
 		m_log << TestLog::Message << "glGetTexParameterfv(" << getTextureTargetStr(target) << ", " << getTextureParameterStr(pname) << ", " << toHex(reinterpret_cast<deUintptr>(static_cast<const void*>(params))) << ");" << TestLog::EndMessage;
 	m_gl.getTexParameterfv(target, pname, params);
 	if (m_enableLog)
-		m_log << TestLog::Message << "// params = " << getPointerStr(params, 1) << TestLog::EndMessage;
+		m_log << TestLog::Message << "// params = " << getPointerStr(params, getTextureParamQueryNumArgsOut(pname)) << TestLog::EndMessage;
 }
 
 void CallLogWrapper::glGetTexParameteriv (glw::GLenum target, glw::GLenum pname, glw::GLint *params)
@@ -2096,7 +2096,7 @@
 		m_log << TestLog::Message << "glGetTexParameteriv(" << getTextureTargetStr(target) << ", " << getTextureParameterStr(pname) << ", " << toHex(reinterpret_cast<deUintptr>(static_cast<const void*>(params))) << ");" << TestLog::EndMessage;
 	m_gl.getTexParameteriv(target, pname, params);
 	if (m_enableLog)
-		m_log << TestLog::Message << "// params = " << getPointerStr(params, 1) << TestLog::EndMessage;
+		m_log << TestLog::Message << "// params = " << getPointerStr(params, getTextureParamQueryNumArgsOut(pname)) << TestLog::EndMessage;
 }
 
 void CallLogWrapper::glGetTextureImage (glw::GLuint texture, glw::GLint level, glw::GLenum format, glw::GLenum type, glw::GLsizei bufSize, void *pixels)
@@ -3362,7 +3362,7 @@
 void CallLogWrapper::glSamplerParameterfv (glw::GLuint sampler, glw::GLenum pname, const glw::GLfloat *param)
 {
 	if (m_enableLog)
-		m_log << TestLog::Message << "glSamplerParameterfv(" << sampler << ", " << getTextureParameterStr(pname) << ", " << getPointerStr(param, 1) << ");" << TestLog::EndMessage;
+		m_log << TestLog::Message << "glSamplerParameterfv(" << sampler << ", " << getTextureParameterStr(pname) << ", " << getPointerStr(param, getTextureParamNumArgs(pname)) << ");" << TestLog::EndMessage;
 	m_gl.samplerParameterfv(sampler, pname, param);
 }
 
@@ -3376,7 +3376,7 @@
 void CallLogWrapper::glSamplerParameteriv (glw::GLuint sampler, glw::GLenum pname, const glw::GLint *param)
 {
 	if (m_enableLog)
-		m_log << TestLog::Message << "glSamplerParameteriv(" << sampler << ", " << getTextureParameterStr(pname) << ", " << getPointerStr(param, 1) << ");" << TestLog::EndMessage;
+		m_log << TestLog::Message << "glSamplerParameteriv(" << sampler << ", " << getTextureParameterStr(pname) << ", " << getPointerStr(param, getTextureParamNumArgs(pname)) << ");" << TestLog::EndMessage;
 	m_gl.samplerParameteriv(sampler, pname, param);
 }
 
@@ -3544,7 +3544,7 @@
 void CallLogWrapper::glTexParameterfv (glw::GLenum target, glw::GLenum pname, const glw::GLfloat *params)
 {
 	if (m_enableLog)
-		m_log << TestLog::Message << "glTexParameterfv(" << getTextureTargetStr(target) << ", " << getTextureParameterStr(pname) << ", " << getPointerStr(params, 1) << ");" << TestLog::EndMessage;
+		m_log << TestLog::Message << "glTexParameterfv(" << getTextureTargetStr(target) << ", " << getTextureParameterStr(pname) << ", " << getPointerStr(params, getTextureParamNumArgs(pname)) << ");" << TestLog::EndMessage;
 	m_gl.texParameterfv(target, pname, params);
 }
 
@@ -3558,7 +3558,7 @@
 void CallLogWrapper::glTexParameteriv (glw::GLenum target, glw::GLenum pname, const glw::GLint *params)
 {
 	if (m_enableLog)
-		m_log << TestLog::Message << "glTexParameteriv(" << getTextureTargetStr(target) << ", " << getTextureParameterStr(pname) << ", " << getPointerStr(params, 1) << ");" << TestLog::EndMessage;
+		m_log << TestLog::Message << "glTexParameteriv(" << getTextureTargetStr(target) << ", " << getTextureParameterStr(pname) << ", " << getPointerStr(params, getTextureParamNumArgs(pname)) << ");" << TestLog::EndMessage;
 	m_gl.texParameteriv(target, pname, params);
 }
 
diff --git a/modules/gles2/functional/es2fFboApiTest.cpp b/modules/gles2/functional/es2fFboApiTest.cpp
index 9a9660a..62d4940 100644
--- a/modules/gles2/functional/es2fFboApiTest.cpp
+++ b/modules/gles2/functional/es2fFboApiTest.cpp
@@ -69,6 +69,17 @@
 		testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error code mismatch");
 }
 
+static void checkEitherError (tcu::TestContext& testCtx, sglr::Context& ctx, GLenum expectA, GLenum expectB)
+{
+	GLenum	result	= ctx.getError();
+	bool	isOk	= (result == expectA || result == expectB);
+
+	testCtx.getLog() << TestLog::Message << "// " << (isOk ? "Pass" : "Fail") << ", expected " << glu::getErrorStr(expectA) << " or " << glu::getErrorStr(expectB) << TestLog::EndMessage;
+
+	if (!isOk)
+		testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error code mismatch");
+}
+
 static const char* getAttachmentName (GLenum attachment)
 {
 	switch (attachment)
@@ -349,13 +360,13 @@
 	// Check that proper error codes are returned
 	GLint unused = 1;
 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &unused);
-	checkError(testCtx, ctx, GL_INVALID_OPERATION);
+	checkEitherError(testCtx, ctx, GL_INVALID_ENUM, GL_INVALID_OPERATION);
 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &unused);
-	checkError(testCtx, ctx, GL_INVALID_OPERATION);
+	checkEitherError(testCtx, ctx, GL_INVALID_ENUM, GL_INVALID_OPERATION);
 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &unused);
-	checkError(testCtx, ctx, GL_INVALID_OPERATION);
+	checkEitherError(testCtx, ctx, GL_INVALID_ENUM, GL_INVALID_OPERATION);
 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, &unused);
-	checkError(testCtx, ctx, GL_INVALID_OPERATION);
+	checkEitherError(testCtx, ctx, GL_INVALID_ENUM, GL_INVALID_OPERATION);
 }
 
 static void attachmentQueryEmptyFboTest (tcu::TestContext& testCtx, sglr::Context& ctx)
diff --git a/modules/gles3/functional/es3fFboApiTests.cpp b/modules/gles3/functional/es3fFboApiTests.cpp
index 3f57a8d..8314ec5 100644
--- a/modules/gles3/functional/es3fFboApiTests.cpp
+++ b/modules/gles3/functional/es3fFboApiTests.cpp
@@ -65,6 +65,17 @@
 		testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error code mismatch");
 }
 
+static void checkEitherError (tcu::TestContext& testCtx, sglr::Context& ctx, GLenum expectA, GLenum expectB)
+{
+	GLenum	result	= ctx.getError();
+	bool	isOk	= (result == expectA || result == expectB);
+
+	testCtx.getLog() << TestLog::Message << "// " << (isOk ? "Pass" : "Fail") << ", expected " << glu::getErrorStr(expectA) << " or " << glu::getErrorStr(expectB) << TestLog::EndMessage;
+
+	if (!isOk)
+		testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error code mismatch");
+}
+
 static const char* getAttachmentName (GLenum attachment)
 {
 	switch (attachment)
@@ -325,13 +336,13 @@
 	// Check that proper error codes are returned
 	GLint unused = -1;
 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &unused);
-	checkError(testCtx, ctx, GL_INVALID_ENUM);
+	checkEitherError(testCtx, ctx, GL_INVALID_ENUM, GL_INVALID_OPERATION);
 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &unused);
-	checkError(testCtx, ctx, GL_INVALID_ENUM);
+	checkEitherError(testCtx, ctx, GL_INVALID_ENUM, GL_INVALID_OPERATION);
 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, &unused);
-	checkError(testCtx, ctx, GL_INVALID_ENUM);
+	checkEitherError(testCtx, ctx, GL_INVALID_ENUM, GL_INVALID_OPERATION);
 	ctx.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, &unused);
-	checkError(testCtx, ctx, GL_INVALID_ENUM);
+	checkEitherError(testCtx, ctx, GL_INVALID_ENUM, GL_INVALID_OPERATION);
 }
 
 static void attachmentQueryEmptyFboTest (tcu::TestContext& testCtx, sglr::Context& ctx)
diff --git a/modules/gles3/functional/es3fNegativeTextureApiTests.cpp b/modules/gles3/functional/es3fNegativeTextureApiTests.cpp
index 8e4d61b..e1361ef 100644
--- a/modules/gles3/functional/es3fNegativeTextureApiTests.cpp
+++ b/modules/gles3/functional/es3fNegativeTextureApiTests.cpp
@@ -1986,9 +1986,10 @@
 			expectError(GL_INVALID_ENUM);
 			m_log << TestLog::EndSection;
 
-			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if internalFormat is not one of the accepted resolution and format symbolic constants.");
+			m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if internalFormat is not one of the accepted resolution and format symbolic constants "
+										  "or GL_INVALID_OPERATION is generated if internalformat, format and type are not compatible.");
 			glTexImage3D(GL_TEXTURE_3D, 0, 0, 1, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
-			expectError(GL_INVALID_VALUE);
+			expectError(GL_INVALID_VALUE, GL_INVALID_OPERATION);
 			m_log << TestLog::EndSection;
 
 			m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if target is GL_TEXTURE_3D and format is GL_DEPTH_COMPONENT, or GL_DEPTH_STENCIL.");
diff --git a/modules/glshared/glsTextureTestUtil.cpp b/modules/glshared/glsTextureTestUtil.cpp
index 328104e..85204b5 100644
--- a/modules/glshared/glsTextureTestUtil.cpp
+++ b/modules/glshared/glsTextureTestUtil.cpp
@@ -2814,6 +2814,9 @@
 				continue;
 			}
 
+			// Reference result is known to be a valid result, we can
+			// skip verification if thes results are equal
+			if (resPix.x() != refPix.x())
 			{
 				const float		wx		= (float)px + 0.5f;
 				const float		wy		= (float)py + 0.5f;
@@ -2917,6 +2920,7 @@
 			const tcu::Vec4	resPix	= result.getPixel(px, py);
 			const tcu::Vec4	refPix	= reference.getPixel(px, py);
 
+			// Other channels should trivially match to reference.
 			if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1,2,3) - resPix.swizzle(1,2,3)), nonShadowThreshold)))
 			{
 				errorMask.setPixel(tcu::RGBA::red.toVec(), px, py);
@@ -2924,6 +2928,9 @@
 				continue;
 			}
 
+			// Reference result is known to be a valid result, we can
+			// skip verification if thes results are equal
+			if (resPix.x() != refPix.x())
 			{
 				const float		wx		= (float)px + 0.5f;
 				const float		wy		= (float)py + 0.5f;
@@ -3035,6 +3042,7 @@
 			const tcu::Vec4	resPix	= result.getPixel(px, py);
 			const tcu::Vec4	refPix	= reference.getPixel(px, py);
 
+			// Other channels should trivially match to reference.
 			if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1,2,3) - resPix.swizzle(1,2,3)), nonShadowThreshold)))
 			{
 				errorMask.setPixel(tcu::RGBA::red.toVec(), px, py);
@@ -3042,6 +3050,9 @@
 				continue;
 			}
 
+			// Reference result is known to be a valid result, we can
+			// skip verification if thes results are equal
+			if (resPix.x() != refPix.x())
 			{
 				const float		wx		= (float)px + 0.5f;
 				const float		wy		= (float)py + 0.5f;
diff --git a/scripts/opengl/gen_call_log_wrapper.py b/scripts/opengl/gen_call_log_wrapper.py
index 731251a..c5f15e2 100644
--- a/scripts/opengl/gen_call_log_wrapper.py
+++ b/scripts/opengl/gen_call_log_wrapper.py
@@ -178,8 +178,8 @@
 	"glGetQueryObjecti64v":					LogSpec({1: enum("QueryObjectParam")}, argOutPrints = {2: pointer(size = "1")}),
 	"glGetQueryObjectui64v":				LogSpec({1: enum("QueryObjectParam")}, argOutPrints = {2: pointer(size = "1")}),
 	"glGetRenderbufferParameteriv":			LogSpec({0: enum("FramebufferTarget"), 1: enum("RenderbufferParameter")}),
-	"glGetSamplerParameterfv":				LogSpec({1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "1")}),
-	"glGetSamplerParameteriv":				LogSpec({1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "1")}),
+	"glGetSamplerParameterfv":				LogSpec({1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
+	"glGetSamplerParameteriv":				LogSpec({1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
 	"glGetSamplerParameterIiv":				LogSpec({1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
 	"glGetSamplerParameterIuiv":			LogSpec({1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
 	"glGetShaderiv":						LogSpec({1: enum("ShaderParam")}, argOutPrints = {2: pointer(size = "1")}),
@@ -188,8 +188,8 @@
 #	"glGetShaderSource":
 	"glGetString":							LogSpec({0: enum("GettableString")}, returnPrint=stringVal),
 	"glGetStringi":							LogSpec({0: enum("GettableString")}, returnPrint=stringVal),
-	"glGetTexParameterfv":					LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "1")}),
-	"glGetTexParameteriv":					LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "1")}),
+	"glGetTexParameterfv":					LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
+	"glGetTexParameteriv":					LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
 	"glGetTexParameterIiv":					LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
 	"glGetTexParameterIuiv":				LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter")}, argOutPrints = {2: pointer(size = "getTextureParamQueryNumArgsOut(pname)")}),
 	"glGetTexLevelParameterfv":				LogSpec({0: enum("TextureTarget"), 2: enum("TextureLevelParameter")}, argOutPrints = {3: pointer(size = "1")}),
@@ -225,15 +225,15 @@
 	"glTexStorage3DMultisample":			LogSpec({0: enum("TextureTarget"), 2: enum("PixelFormat"), 6: enum("Boolean")}),
 	# \todo [2012-03-08 pyry] Pointer values..
 	"glTexParameterf":						LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter")}),
-	"glTexParameterfv":						LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter"), 2: pointer(size = "1")}),
 	"glTexParameteri":						LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter"), 2: lambda name: "getTextureParameterValueStr(pname, %s)" % name}),
-	"glTexParameteriv":						LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter"), 2: pointer(size = "1")}),
+	"glTexParameterfv":						LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
+	"glTexParameteriv":						LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
 	"glTexParameterIiv":					LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
 	"glTexParameterIuiv":					LogSpec({0: enum("TextureTarget"), 1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
 	"glSamplerParameterf":					LogSpec({1: enum("TextureParameter")}),
-	"glSamplerParameterfv":					LogSpec({1: enum("TextureParameter"), 2: pointer(size = "1")}),
 	"glSamplerParameteri":					LogSpec({1: enum("TextureParameter"), 2: lambda name: "getTextureParameterValueStr(pname, %s)" % name}),
-	"glSamplerParameteriv":					LogSpec({1: enum("TextureParameter"), 2: pointer(size = "1")}),
+	"glSamplerParameterfv":					LogSpec({1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
+	"glSamplerParameteriv":					LogSpec({1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
 	"glSamplerParameterIiv":				LogSpec({1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
 	"glSamplerParameterIuiv":				LogSpec({1: enum("TextureParameter"), 2: pointer(size = "getTextureParamNumArgs(pname)")}),
 	"glTexSubImage1D":						LogSpec({0: enum("TextureTarget"), 4: enum("PixelFormat"), 5: enum("Type")}),