13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.0 Module
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 Vertex texture tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es3fVertexTextureTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsTextureTestUtil.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTexture.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTextureUtil.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuMatrix.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuImageCompare.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector>
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <limits>
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glw.h"
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec2;
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec3;
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4;
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec2;
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec3;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::IVec4;
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Mat3;
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace gls::TextureTestUtil;
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::TextureTestUtil::TEXTURETYPE_2D;
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::TextureTestUtil::TEXTURETYPE_CUBE;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::TextureTestUtil::TEXTURETYPE_2D_ARRAY;
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::TextureTestUtil::TEXTURETYPE_3D;
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles3
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int WIDTH_2D_ARRAY				= 128;
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int HEIGHT_2D_ARRAY			= 128;
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int LAYERS_2D_ARRAY			= 8;
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int WIDTH_3D					= 64;
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int HEIGHT_3D					= 64;
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int DEPTH_3D					= 64;
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// The 2D case draws four images.
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int MAX_2D_RENDER_WIDTH		= 128*2;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int MAX_2D_RENDER_HEIGHT		= 128*2;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// The cube map case draws four 3-by-2 image groups.
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int MAX_CUBE_RENDER_WIDTH		= 28*2*3;
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int MAX_CUBE_RENDER_HEIGHT		= 28*2*2;
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int MAX_2D_ARRAY_RENDER_WIDTH	= 128*2;
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int MAX_2D_ARRAY_RENDER_HEIGHT	= 128*2;
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int MAX_3D_RENDER_WIDTH		= 128*2;
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int MAX_3D_RENDER_HEIGHT		= 128*2;
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int GRID_SIZE_2D				= 127;
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int GRID_SIZE_CUBE				= 63;
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int GRID_SIZE_2D_ARRAY			= 127;
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int GRID_SIZE_3D				= 127;
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Helpers for making texture coordinates "safe", i.e. move them further from coordinate bounary.
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Moves x towards the closest K+targetFraction, where K is an integer.
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// E.g. moveTowardsFraction(x, 0.5f) moves x away from integer boundaries.
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float moveTowardsFraction (float x, float targetFraction)
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float strictness = 0.5f;
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(0.0f < strictness && strictness <= 1.0f);
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(de::inBounds(targetFraction, 0.0f, 1.0f));
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float y = x + 0.5f - targetFraction;
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deFloatFloor(y) + deFloatFrac(y)*(1.0f-strictness) + strictness*0.5f - 0.5f + targetFraction;
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline float safeCoord (float raw, int scale, float fraction)
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float scaleFloat = (float)scale;
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return moveTowardsFraction(raw*scaleFloat, fraction) / scaleFloat;
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size>
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline tcu::Vector<float, Size> safeCoords (const tcu::Vector<float, Size>& raw, const tcu::Vector<int, Size>& scale, const tcu::Vector<float, Size>& fraction)
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vector<float, Size> result;
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < Size; i++)
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result[i] = safeCoord(raw[i], scale[i], fraction[i]);
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Vec2 safe2DTexCoords (const Vec2& raw, const IVec2& textureSize)
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return safeCoords(raw, textureSize, Vec2(0.5f));
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Vec3 safe2DArrayTexCoords (const Vec3& raw, const IVec3& textureSize)
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return safeCoords(raw, textureSize, Vec3(0.5f, 0.5f, 0.0f));
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Vec3 safe3DTexCoords (const Vec3& raw, const IVec3& textureSize)
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return safeCoords(raw, textureSize, Vec3(0.5f));
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct Rect
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Rect	(int x_, int y_, int w_, int h_) : x(x_), y(y_), w(w_), h(h_) {}
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2	pos		(void) const { return IVec2(x, y); }
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IVec2	size	(void) const { return IVec2(w, h); }
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		x;
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		y;
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		w;
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int		h;
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <TextureType> struct TexTypeTcuClass;
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct TexTypeTcuClass<TEXTURETYPE_2D>			{ typedef tcu::Texture2D		t; };
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct TexTypeTcuClass<TEXTURETYPE_CUBE>		{ typedef tcu::TextureCube		t; };
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct TexTypeTcuClass<TEXTURETYPE_2D_ARRAY>	{ typedef tcu::Texture2DArray	t; };
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct TexTypeTcuClass<TEXTURETYPE_3D>			{ typedef tcu::Texture3D		t; };
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <TextureType> struct TexTypeSizeDims;
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct TexTypeSizeDims<TEXTURETYPE_2D>			{ enum { V = 2 }; };
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct TexTypeSizeDims<TEXTURETYPE_CUBE>		{ enum { V = 2 }; };
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct TexTypeSizeDims<TEXTURETYPE_2D_ARRAY>	{ enum { V = 3 }; };
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct TexTypeSizeDims<TEXTURETYPE_3D>			{ enum { V = 3 }; };
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <TextureType> struct TexTypeCoordDims;
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct TexTypeCoordDims<TEXTURETYPE_2D>			{ enum { V = 2 }; };
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct TexTypeCoordDims<TEXTURETYPE_CUBE>		{ enum { V = 3 }; };
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct TexTypeCoordDims<TEXTURETYPE_2D_ARRAY>	{ enum { V = 3 }; };
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct TexTypeCoordDims<TEXTURETYPE_3D>			{ enum { V = 3 }; };
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <TextureType TexType> struct TexTypeSizeIVec		{ typedef tcu::Vector<int,		TexTypeSizeDims<TexType>::V>	t; };
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <TextureType TexType> struct TexTypeCoordVec		{ typedef tcu::Vector<float,	TexTypeCoordDims<TexType>::V>	t; };
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <TextureType> struct TexTypeCoordParams;
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct
1783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexTypeCoordParams<TEXTURETYPE_2D>
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec2 scale;
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec2 bias;
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TexTypeCoordParams (const Vec2& scale_, const Vec2& bias_) : scale(scale_), bias(bias_) {}
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct
1873c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexTypeCoordParams<TEXTURETYPE_CUBE>
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec2			scale;
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec2			bias;
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::CubeFace	face;
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TexTypeCoordParams (const Vec2& scale_, const Vec2& bias_, tcu::CubeFace face_) : scale(scale_), bias(bias_), face(face_) {}
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct
1973c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexTypeCoordParams<TEXTURETYPE_2D_ARRAY>
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Mat3 transform;
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TexTypeCoordParams (const Mat3& transform_) : transform(transform_) {}
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <> struct
2053c827367444ee418f129b2c238299f49d3264554Jarkko PoyryTexTypeCoordParams<TEXTURETYPE_3D>
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Mat3 transform;
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TexTypeCoordParams (const Mat3& transform_) : transform(transform_) {}
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*--------------------------------------------------------------------*//*!
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Quad grid class containing position and texture coordinate data.
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * A quad grid of size S means a grid consisting of S*S quads (S rows and
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * S columns). The quads are rectangles with main axis aligned sides, and
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * each consists of two triangles. Note that although there are only
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * (S+1)*(S+1) distinct vertex positions, there are S*S*4 distinct vertices
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * because we want texture coordinates to be constant across the vertices
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * of a quad (to avoid interpolation issues), and thus each quad needs its
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * own 4 vertices.
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Pointers returned by get*Ptr() are suitable for gl calls such as
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * glVertexAttribPointer() (for position and tex coord) or glDrawElements()
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * (for indices).
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <TextureType TexType>
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass PosTexCoordQuadGrid
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum { TEX_COORD_DIMS = TexTypeCoordDims <TexType>::V };
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef typename TexTypeCoordVec<TexType>::t	TexCoordVec;
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef typename TexTypeSizeIVec<TexType>::t	TexSizeIVec;
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef TexTypeCoordParams<TexType>				TexCoordParams;
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							PosTexCoordQuadGrid		(int gridSize, const IVec2& renderSize, const TexSizeIVec& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords);
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						getSize					(void) const { return m_gridSize; }
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vec4					getQuadLDRU				(int col, int row) const; //!< Vec4(leftX, downY, rightX, upY)
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const TexCoordVec&		getQuadTexCoord			(int col, int row) const;
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						getNumIndices			(void) const { return m_gridSize*m_gridSize*3*2; }
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float*			getPositionPtr			(void) const { DE_STATIC_ASSERT(sizeof(Vec2) == 2*sizeof(float)); return (float*)&m_positions[0]; }
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float*			getTexCoordPtr			(void) const { DE_STATIC_ASSERT(sizeof(TexCoordVec) == TEX_COORD_DIMS*(int)sizeof(float)); return (float*)&m_texCoords[0]; }
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint16*			getIndexPtr				(void) const { return &m_indices[0]; }
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					initializeTexCoords		(const TexSizeIVec& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords);
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				m_gridSize;
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Vec2>			m_positions;
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<TexCoordVec>		m_texCoords;
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<deUint16>		m_indices;
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <TextureType TexType>
2583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVec4 PosTexCoordQuadGrid<TexType>::getQuadLDRU (int col, int row) const
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int ndx00 = (row*m_gridSize + col) * 4;
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int ndx11 = ndx00 + 3;
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return Vec4(m_positions[ndx00].x(),
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_positions[ndx00].y(),
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_positions[ndx11].x(),
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_positions[ndx11].y());
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <TextureType TexType>
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst typename TexTypeCoordVec<TexType>::t& PosTexCoordQuadGrid<TexType>::getQuadTexCoord (int col, int row) const
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_texCoords[(row*m_gridSize + col) * 4];
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <TextureType TexType>
2763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryPosTexCoordQuadGrid<TexType>::PosTexCoordQuadGrid (int gridSize, const IVec2& renderSize, const TexSizeIVec& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords)
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_gridSize(gridSize)
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_gridSize > 0 && m_gridSize*m_gridSize <= (int)std::numeric_limits<deUint16>::max() + 1);
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float gridSizeFloat = (float)m_gridSize;
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_positions.reserve(m_gridSize*m_gridSize*4);
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_indices.reserve(m_gridSize*m_gridSize*3*2);
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < m_gridSize; y++)
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < m_gridSize; x++)
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float fx0 = (float)(x+0) / gridSizeFloat;
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float fx1 = (float)(x+1) / gridSizeFloat;
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float fy0 = (float)(y+0) / gridSizeFloat;
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float fy1 = (float)(y+1) / gridSizeFloat;
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec2 quadVertices[4] = { Vec2(fx0, fy0), Vec2(fx1, fy0), Vec2(fx0, fy1), Vec2(fx1, fy1) };
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int firstNdx = (int)m_positions.size();
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < DE_LENGTH_OF_ARRAY(quadVertices); i++)
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_positions.push_back(safeCoords(quadVertices[i], renderSize, Vec2(0.0f)) * 2.0f - 1.0f);
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_indices.push_back(firstNdx + 0);
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_indices.push_back(firstNdx + 1);
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_indices.push_back(firstNdx + 2);
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_indices.push_back(firstNdx + 1);
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_indices.push_back(firstNdx + 3);
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_indices.push_back(firstNdx + 2);
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texCoords.reserve(m_gridSize*m_gridSize*4);
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	initializeTexCoords(textureSize, texCoordParams, useSafeTexCoords);
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((int)m_positions.size() == m_gridSize*m_gridSize*4);
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((int)m_indices.size() == m_gridSize*m_gridSize*3*2);
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT((int)m_texCoords.size() == m_gridSize*m_gridSize*4);
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <>
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PosTexCoordQuadGrid<TEXTURETYPE_2D>::initializeTexCoords (const IVec2& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords)
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_texCoords.empty());
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float gridSizeFloat = (float)m_gridSize;
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < m_gridSize; y++)
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < m_gridSize; x++)
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec2 rawCoord = Vec2((float)x / gridSizeFloat, (float)y / gridSizeFloat) * texCoordParams.scale + texCoordParams.bias;
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_texCoords.push_back(useSafeTexCoords ? safe2DTexCoords(rawCoord, textureSize) : rawCoord);
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <>
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PosTexCoordQuadGrid<TEXTURETYPE_CUBE>::initializeTexCoords (const IVec2& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords)
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_texCoords.empty());
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float		gridSizeFloat	= (float)m_gridSize;
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>	texBoundaries;
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	computeQuadTexCoordCube(texBoundaries, texCoordParams.face);
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec3		coordA			= Vec3(texBoundaries[0], texBoundaries[1], texBoundaries[2]);
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec3		coordB			= Vec3(texBoundaries[3], texBoundaries[4], texBoundaries[5]);
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec3		coordC			= Vec3(texBoundaries[6], texBoundaries[7], texBoundaries[8]);
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec3		coordAB			= coordB - coordA;
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec3		coordAC			= coordC - coordA;
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < m_gridSize; y++)
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < m_gridSize; x++)
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec2 rawFaceCoord		= texCoordParams.scale * Vec2((float)x / gridSizeFloat, (float)y / gridSizeFloat) + texCoordParams.bias;
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec2 safeFaceCoord	= useSafeTexCoords ? safe2DTexCoords(rawFaceCoord, textureSize) : rawFaceCoord;
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec3 texCoord			= coordA + coordAC*safeFaceCoord.x() + coordAB*safeFaceCoord.y();
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_texCoords.push_back(texCoord);
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <>
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PosTexCoordQuadGrid<TEXTURETYPE_2D_ARRAY>::initializeTexCoords (const IVec3& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords)
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_texCoords.empty());
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float gridSizeFloat = (float)m_gridSize;
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < m_gridSize; y++)
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < m_gridSize; x++)
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec3 rawCoord = texCoordParams.transform * Vec3((float)x / gridSizeFloat, (float)y / gridSizeFloat, 1.0f);
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_texCoords.push_back(useSafeTexCoords ? safe2DArrayTexCoords(rawCoord, textureSize) : rawCoord);
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <>
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid PosTexCoordQuadGrid<TEXTURETYPE_3D>::initializeTexCoords (const IVec3& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords)
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_texCoords.empty());
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float gridSizeFloat = (float)m_gridSize;
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < m_gridSize; y++)
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < m_gridSize; x++)
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vec3 rawCoord = texCoordParams.transform * Vec3((float)x / gridSizeFloat, (float)y / gridSizeFloat, 1.0f);
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_texCoords.push_back(useSafeTexCoords ? safe3DTexCoords(rawCoord, textureSize) : rawCoord);
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline bool isLevelNearest (deUint32 filter)
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return filter == GL_NEAREST || filter == GL_NEAREST_MIPMAP_NEAREST || filter == GL_NEAREST_MIPMAP_LINEAR;
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline IVec2 getTextureSize (const glu::Texture2D& tex)
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Texture2D& ref = tex.getRefTexture();
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return IVec2(ref.getWidth(), ref.getHeight());
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline IVec2 getTextureSize (const glu::TextureCube& tex)
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureCube& ref = tex.getRefTexture();
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return IVec2(ref.getSize(), ref.getSize());
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline IVec3 getTextureSize (const glu::Texture2DArray& tex)
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Texture2DArray& ref = tex.getRefTexture();
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return IVec3(ref.getWidth(), ref.getHeight(), ref.getNumLayers());
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline IVec3 getTextureSize (const glu::Texture3D& tex)
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Texture3D& ref = tex.getRefTexture();
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return IVec3(ref.getWidth(), ref.getHeight(), ref.getDepth());
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <TextureType TexType>
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void setPixelColors (const vector<Vec4>& quadColors, const Rect& region, const PosTexCoordQuadGrid<TexType>& grid, tcu::Surface& dst)
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int gridSize = grid.getSize();
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < gridSize; y++)
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < gridSize; x++)
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec4	color	= quadColors[y*gridSize + x];
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec4	ldru	= grid.getQuadLDRU(x, y) * 0.5f + 0.5f; // [-1, 1] -> [0, 1]
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	ix0		= deCeilFloatToInt32(ldru.x() * (float)region.w - 0.5f);
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	ix1		= deCeilFloatToInt32(ldru.z() * (float)region.w - 0.5f);
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	iy0		= deCeilFloatToInt32(ldru.y() * (float)region.h - 0.5f);
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	iy1		= deCeilFloatToInt32(ldru.w() * (float)region.h - 0.5f);
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int iy = iy0; iy < iy1; iy++)
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ix = ix0; ix < ix1; ix++)
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(deInBounds32(ix + region.x, 0, dst.getWidth()));
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(deInBounds32(iy + region.y, 0, dst.getHeight()));
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			dst.setPixel(ix + region.x, iy + region.y, toRGBA(color));
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Vec4 sample (const tcu::Texture2D&		tex, const Vec2& coord, float lod, const tcu::Sampler& sam) { return tex.sample(sam, coord.x(), coord.y(), lod); }
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Vec4 sample (const tcu::TextureCube&		tex, const Vec3& coord, float lod, const tcu::Sampler& sam) { return tex.sample(sam, coord.x(), coord.y(), coord.z(), lod); }
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Vec4 sample (const tcu::Texture2DArray&	tex, const Vec3& coord, float lod, const tcu::Sampler& sam) { return tex.sample(sam, coord.x(), coord.y(), coord.z(), lod); }
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline Vec4 sample (const tcu::Texture3D&		tex, const Vec3& coord, float lod, const tcu::Sampler& sam) { return tex.sample(sam, coord.x(), coord.y(), coord.z(), lod); }
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <TextureType TexType>
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid computeReference (const typename TexTypeTcuClass<TexType>::t& texture, float lod, const tcu::Sampler& sampler, const PosTexCoordQuadGrid<TexType>& grid, tcu::Surface& dst, const Rect& dstRegion)
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		gridSize	= grid.getSize();
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Vec4>	quadColors	(gridSize*gridSize);
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int y = 0; y < gridSize; y++)
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int x = 0; x < gridSize; x++)
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int										ndx		= y*gridSize + x;
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const typename TexTypeCoordVec<TexType>::t&		coord	= grid.getQuadTexCoord(x, y);
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		quadColors[ndx] = sample(texture, coord, lod, sampler);
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setPixelColors(quadColors, dstRegion, grid, dst);
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool compareImages (const glu::RenderContext& renderCtx, tcu::TestLog& log, const tcu::Surface& ref, const tcu::Surface& res)
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(renderCtx.getRenderTarget().getNumSamples() == 0);
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RGBA threshold = renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(15,15,15,15);
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::pixelThresholdCompare(log, "Result", "Image compare result", ref, res, threshold, tcu::COMPARE_LOG_RESULT);
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Vertex2DTextureCase : public TestCase
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Vertex2DTextureCase		(Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT);
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~Vertex2DTextureCase	(void);
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						init					(void);
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						deinit					(void);
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate					(void);
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef PosTexCoordQuadGrid<TEXTURETYPE_2D> Grid;
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Vertex2DTextureCase		(const Vertex2DTextureCase& other);
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vertex2DTextureCase&		operator=				(const Vertex2DTextureCase& other);
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						calculateLod			(const Vec2& texScale, const Vec2& dstSize, int textureNdx) const;
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						setupShaderInputs		(int textureNdx, float lod, const Grid& grid) const;
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						renderCell				(int textureNdx, float lod, const Grid& grid) const;
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						computeReferenceCell	(int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const;
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_minFilter;
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_magFilter;
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_wrapS;
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_wrapT;
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderProgram*	m_program;
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture2D*				m_textures[2];	// 2 textures, a gradient texture and a grid texture.
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5133c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertex2DTextureCase::Vertex2DTextureCase (Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT)
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(testCtx, tcu::NODETYPE_SELF_VALIDATE, name, desc)
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter			(minFilter)
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter			(magFilter)
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS				(wrapS)
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT				(wrapT)
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program				(DE_NULL)
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures[0] = DE_NULL;
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures[1] = DE_NULL;
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5253c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertex2DTextureCase::~Vertex2DTextureCase(void)
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vertex2DTextureCase::deinit();
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Vertex2DTextureCase::init (void)
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* const vertexShader =
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in highp vec2 a_position;\n"
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in highp vec2 a_texCoord;\n"
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform highp sampler2D u_texture;\n"
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform highp float u_lod;\n"
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"out mediump vec4 v_color;\n"
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_color = textureLod(u_texture, a_texCoord, u_lod);\n"
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* const fragmentShader =
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in mediump vec4 v_color;\n"
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	dEQP_FragColor = v_color;\n"
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_context.getRenderTarget().getNumSamples() != 0)
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("MSAA config not supported by this test");
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_program);
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShader, fragmentShader));
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if(!m_program->isOk())
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << *m_program;
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint maxVertexTextures;
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextures);
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (maxVertexTextures < 1)
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Vertex texture image units not supported", "", __FILE__, __LINE__);
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Failed to compile shader");
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Make the textures.
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compute suitable power-of-two sizes (for mipmaps).
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texWidth		= 1 << deLog2Ceil32(MAX_2D_RENDER_WIDTH / 2);
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texHeight		= 1 << deLog2Ceil32(MAX_2D_RENDER_HEIGHT / 2);
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 2; i++)
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(!m_textures[i]);
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[i] = new glu::Texture2D(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, texWidth, texHeight);
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool						mipmaps		= (deIsPowerOfTwo32(texWidth) && deIsPowerOfTwo32(texHeight));
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int						numLevels	= mipmaps ? deLog2Floor32(de::max(texWidth, texHeight))+1 : 1;
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec4						cBias		= fmtInfo.valueMin;
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec4						cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill first with gradient texture.
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4 gMin = Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias;
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4 gMax = Vec4( 1.0f,  1.0f,  1.0f, 0.0f)*cScale + cBias;
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[0]->getRefTexture().allocLevel(levelNdx);
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevel(levelNdx), gMin, gMax);
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill second with grid texture.
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32 step		= 0x00ffffff / numLevels;
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32 rgb		= step*levelNdx;
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32 colorA	= 0xff000000 | rgb;
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32 colorB	= 0xff000000 | ~rgb;
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[1]->getRefTexture().allocLevel(levelNdx);
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevel(levelNdx), 4, toVec4(tcu::RGBA(colorA))*cScale + cBias, toVec4(tcu::RGBA(colorB))*cScale + cBias);
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Upload.
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 2; i++)
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[i]->upload();
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const std::exception&)
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up to save memory.
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vertex2DTextureCase::deinit();
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Vertex2DTextureCase::deinit (void)
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 2; i++)
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_textures[i];
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures[i] = DE_NULL;
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_program;
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = DE_NULL;
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Vertex2DTextureCase::calculateLod (const Vec2& texScale, const Vec2& dstSize, int textureNdx) const
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Texture2D&		refTexture	= m_textures[textureNdx]->getRefTexture();
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2					srcSize		= Vec2((float)refTexture.getWidth(), (float)refTexture.getHeight());
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2					sizeRatio	= texScale*srcSize / dstSize;
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note In this particular case dv/dx and du/dy are zero, simplifying the expression.
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deFloatLog2(de::max(sizeRatio.x(), sizeRatio.y()));
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertex2DTextureCase::IterateResult Vertex2DTextureCase::iterate (void)
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportWidth		= deMin32(m_context.getRenderTarget().getWidth(), MAX_2D_RENDER_WIDTH);
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportHeight		= deMin32(m_context.getRenderTarget().getHeight(), MAX_2D_RENDER_HEIGHT);
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportXOffsetMax	= m_context.getRenderTarget().getWidth() - viewportWidth;
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportYOffsetMax	= m_context.getRenderTarget().getHeight() - viewportHeight;
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random	rnd					(deStringHash(getName()));
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportXOffset		= rnd.getInt(0, viewportXOffsetMax);
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportYOffset		= rnd.getInt(0, viewportYOffsetMax);
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glUseProgram(m_program->getProgram());
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Divide viewport into 4 cells.
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int leftWidth		= viewportWidth / 2;
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int rightWidth	= viewportWidth - leftWidth;
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int bottomHeight	= viewportHeight / 2;
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int topHeight		= viewportHeight - bottomHeight;
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clear.
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glClearColor(0.125f, 0.25f, 0.5f, 1.0f);
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glClear(GL_COLOR_BUFFER_BIT);
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Texture scaling and offsetting vectors.
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2 texMinScale		(+1.8f, +1.8f);
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2 texMinOffset		(-0.3f, -0.2f);
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2 texMagScale		(+0.3f, +0.3f);
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2 texMagOffset		(+0.9f, +0.8f);
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Surface for the reference image.
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface refImage(viewportWidth, viewportHeight);
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const struct Render
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Rect	region;
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int			textureNdx;
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec2	texCoordScale;
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec2	texCoordOffset;
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render (const Rect& r, int tN, const Vec2& tS, const Vec2& tO) : region(r), textureNdx(tN), texCoordScale(tS), texCoordOffset(tO) {}
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} renders[] =
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(0,				0,				leftWidth,	bottomHeight),	0, texMinScale, texMinOffset),
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(leftWidth,		0,				rightWidth,	bottomHeight),	0, texMagScale, texMagOffset),
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(0,				bottomHeight,	leftWidth,	topHeight),		1, texMinScale, texMinOffset),
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(leftWidth,		bottomHeight,	rightWidth,	topHeight),		1, texMagScale, texMagOffset)
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renders); renderNdx++)
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Render&	rend				= renders[renderNdx];
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float		lod					= calculateLod(rend.texCoordScale, rend.region.size().asFloat(), rend.textureNdx);
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool		useSafeTexCoords	= isLevelNearest(lod > 0.0f ? m_minFilter : m_magFilter);
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Grid		grid				(GRID_SIZE_2D, rend.region.size(), getTextureSize(*m_textures[rend.textureNdx]),
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 TexTypeCoordParams<TEXTURETYPE_2D>(rend.texCoordScale, rend.texCoordOffset), useSafeTexCoords);
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glViewport(viewportXOffset + rend.region.x, viewportYOffset + rend.region.y, rend.region.w, rend.region.h);
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderCell				(rend.textureNdx, lod, grid);
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			computeReferenceCell	(rend.textureNdx, lod, grid, refImage, rend.region);
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read back rendered results.
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface resImage(viewportWidth, viewportHeight);
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewportXOffset, viewportYOffset, resImage.getAccess());
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glUseProgram(0);
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare and log.
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool isOk = compareImages(m_context.getRenderContext(), m_testCtx.getLog(), refImage, resImage);
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								isOk ? "Pass"				: "Image comparison failed");
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Vertex2DTextureCase::setupShaderInputs (int textureNdx, float lod, const Grid& grid) const
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32 programID = m_program->getProgram();
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// SETUP ATTRIBUTES.
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int positionLoc = glGetAttribLocation(programID, "a_position");
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (positionLoc != -1)
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glEnableVertexAttribArray(positionLoc);
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getPositionPtr());
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texCoordLoc = glGetAttribLocation(programID, "a_texCoord");
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texCoordLoc != -1)
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glEnableVertexAttribArray(texCoordLoc);
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getTexCoordPtr());
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// SETUP UNIFORMS.
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int lodLoc = glGetUniformLocation(programID, "u_lod");
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (lodLoc != -1)
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glUniform1f(lodLoc, lod);
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glActiveTexture(GL_TEXTURE0);
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glBindTexture(GL_TEXTURE_2D, m_textures[textureNdx]->getGLTexture());
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	m_magFilter);
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texLoc = glGetUniformLocation(programID, "u_texture");
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texLoc != -1)
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glUniform1i(texLoc, 0);
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Renders one sub-image with given parameters.
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Vertex2DTextureCase::renderCell (int textureNdx, float lod, const Grid& grid) const
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setupShaderInputs(textureNdx, lod, grid);
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glDrawElements(GL_TRIANGLES, grid.getNumIndices(), GL_UNSIGNED_SHORT, grid.getIndexPtr());
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Vertex2DTextureCase::computeReferenceCell (int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	computeReference(m_textures[textureNdx]->getRefTexture(), lod, glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter), grid, dst, dstRegion);
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass VertexCubeTextureCase : public TestCase
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								VertexCubeTextureCase	(Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT);
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~VertexCubeTextureCase	(void);
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						init					(void);
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						deinit					(void);
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate					(void);
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef PosTexCoordQuadGrid<TEXTURETYPE_CUBE> Grid;
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								VertexCubeTextureCase	(const VertexCubeTextureCase& other);
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VertexCubeTextureCase&		operator=				(const VertexCubeTextureCase& other);
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						calculateLod			(const Vec2& texScale, const Vec2& dstSize, int textureNdx) const;
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						setupShaderInputs		(int textureNdx, float lod, const Grid& grid) const;
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						renderCell				(int textureNdx, float lod, const Grid& grid) const;
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						computeReferenceCell	(int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const;
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_minFilter;
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_magFilter;
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_wrapS;
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_wrapT;
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderProgram*	m_program;
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::TextureCube*			m_textures[2];	// 2 textures, a gradient texture and a grid texture.
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8193c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexCubeTextureCase::VertexCubeTextureCase (Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT)
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(testCtx, tcu::NODETYPE_SELF_VALIDATE, name, desc)
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter			(minFilter)
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter			(magFilter)
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS				(wrapS)
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT				(wrapT)
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program				(DE_NULL)
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures[0] = DE_NULL;
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures[1] = DE_NULL;
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8313c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexCubeTextureCase::~VertexCubeTextureCase(void)
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	VertexCubeTextureCase::deinit();
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VertexCubeTextureCase::init (void)
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* const vertexShader =
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in highp vec2 a_position;\n"
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in highp vec3 a_texCoord;\n"
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform highp samplerCube u_texture;\n"
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform highp float u_lod;\n"
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"out mediump vec4 v_color;\n"
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_color = textureLod(u_texture, a_texCoord, u_lod);\n"
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* const fragmentShader =
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in mediump vec4 v_color;\n"
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	dEQP_FragColor = v_color;\n"
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_context.getRenderTarget().getNumSamples() != 0)
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("MSAA config not supported by this test");
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_program);
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShader, fragmentShader));
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if(!m_program->isOk())
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << *m_program;
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint maxVertexTextures;
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextures);
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (maxVertexTextures < 1)
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Vertex texture image units not supported", "", __FILE__, __LINE__);
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Failed to compile shader");
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Make the textures.
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Compute suitable power-of-two sizes (for mipmaps).
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texWidth		= 1 << deLog2Ceil32(MAX_CUBE_RENDER_WIDTH / 3 / 2);
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texHeight		= 1 << deLog2Ceil32(MAX_CUBE_RENDER_HEIGHT / 2 / 2);
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(texWidth == texHeight);
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_UNREF(texHeight);
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 2; i++)
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(!m_textures[i]);
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[i] = new glu::TextureCube(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, texWidth);
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool						mipmaps		= deIsPowerOfTwo32(texWidth) != DE_FALSE;
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int						numLevels	= mipmaps ? deLog2Floor32(texWidth)+1 : 1;
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec4						cBias		= fmtInfo.valueMin;
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec4						cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill first with gradient texture.
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const Vec4 gradients[tcu::CUBEFACE_LAST][2] =
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ Vec4(-1.0f, -1.0f, -1.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ Vec4( 0.0f, -1.0f, -1.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ Vec4(-1.0f,  0.0f, -1.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ Vec4(-1.0f, -1.0f,  0.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ Vec4(-1.0f, -1.0f, -1.0f, 0.0f), Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{ Vec4( 0.0f,  0.0f,  0.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f) }  // positive z
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures[0]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), gradients[face][0]*cScale + cBias, gradients[face][1]*cScale + cBias);
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill second with grid texture.
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32 step		= 0x00ffffff / (numLevels*tcu::CUBEFACE_LAST);
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32 rgb		= step*levelNdx*face;
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32 colorA	= 0xff000000 | rgb;
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const deUint32 colorB	= 0xff000000 | ~rgb;
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				m_textures[1]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), 4, toVec4(tcu::RGBA(colorA))*cScale + cBias, toVec4(tcu::RGBA(colorB))*cScale + cBias);
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Upload.
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 2; i++)
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[i]->upload();
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const std::exception&)
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up to save memory.
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		VertexCubeTextureCase::deinit();
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VertexCubeTextureCase::deinit (void)
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 2; i++)
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_textures[i];
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures[i] = DE_NULL;
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_program;
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = DE_NULL;
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat VertexCubeTextureCase::calculateLod (const Vec2& texScale, const Vec2& dstSize, int textureNdx) const
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::TextureCube&		refTexture	= m_textures[textureNdx]->getRefTexture();
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2					srcSize		= Vec2((float)refTexture.getSize(), (float)refTexture.getSize());
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2					sizeRatio	= texScale*srcSize / dstSize;
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note In this particular case, dv/dx and du/dy are zero, simplifying the expression.
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deFloatLog2(de::max(sizeRatio.x(), sizeRatio.y()));
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9713c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexCubeTextureCase::IterateResult VertexCubeTextureCase::iterate (void)
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportWidth		= deMin32(m_context.getRenderTarget().getWidth(), MAX_CUBE_RENDER_WIDTH);
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportHeight		= deMin32(m_context.getRenderTarget().getHeight(), MAX_CUBE_RENDER_HEIGHT);
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportXOffsetMax	= m_context.getRenderTarget().getWidth() - viewportWidth;
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportYOffsetMax	= m_context.getRenderTarget().getHeight() - viewportHeight;
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random	rnd					(deStringHash(getName()));
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportXOffset		= rnd.getInt(0, viewportXOffsetMax);
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportYOffset		= rnd.getInt(0, viewportYOffsetMax);
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glUseProgram(m_program->getProgram());
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Divide viewport into 4 areas.
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int leftWidth		= viewportWidth / 2;
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int rightWidth	= viewportWidth - leftWidth;
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int bottomHeight	= viewportHeight / 2;
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int topHeight		= viewportHeight - bottomHeight;
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clear.
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glClearColor(0.125f, 0.25f, 0.5f, 1.0f);
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glClear(GL_COLOR_BUFFER_BIT);
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Texture scaling and offsetting vectors.
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2 texMinScale		(1.0f, 1.0f);
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2 texMinOffset		(0.0f, 0.0f);
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2 texMagScale		(0.3f, 0.3f);
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2 texMagOffset		(0.5f, 0.3f);
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Surface for the reference image.
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface refImage(viewportWidth, viewportHeight);
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Each of the four areas is divided into 6 cells.
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int defCellWidth	= viewportWidth / 2 / 3;
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int defCellHeight	= viewportHeight / 2 / 2;
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < tcu::CUBEFACE_LAST; i++)
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	cellOffsetX			= defCellWidth * (i % 3);
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	cellOffsetY			= defCellHeight * (i / 3);
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	isRightmostCell		= i == 2 || i == 5;
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool	isTopCell			= i >= 3;
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	leftCellWidth		= isRightmostCell	? leftWidth		- cellOffsetX : defCellWidth;
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	rightCellWidth		= isRightmostCell	? rightWidth	- cellOffsetX : defCellWidth;
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	bottomCellHeight	= isTopCell			? bottomHeight	- cellOffsetY : defCellHeight;
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int	topCellHeight		= isTopCell			? topHeight		- cellOffsetY : defCellHeight;
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const struct Render
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Rect	region;
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int			textureNdx;
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec2	texCoordScale;
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec2	texCoordOffset;
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render (const Rect& r, int tN, const Vec2& tS, const Vec2& tO) : region(r), textureNdx(tN), texCoordScale(tS), texCoordOffset(tO) {}
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} renders[] =
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(cellOffsetX + 0,			cellOffsetY + 0,				leftCellWidth,	bottomCellHeight),	0, texMinScale, texMinOffset),
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(cellOffsetX + leftWidth,	cellOffsetY + 0,				rightCellWidth,	bottomCellHeight),	0, texMagScale, texMagOffset),
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(cellOffsetX + 0,			cellOffsetY + bottomHeight,		leftCellWidth,	topCellHeight),		1, texMinScale, texMinOffset),
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(cellOffsetX + leftWidth,	cellOffsetY + bottomHeight,		rightCellWidth,	topCellHeight),		1, texMagScale, texMagOffset)
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renders); renderNdx++)
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Render&	rend				= renders[renderNdx];
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float		lod					= calculateLod(rend.texCoordScale, rend.region.size().asFloat(), rend.textureNdx);
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool		useSafeTexCoords	= isLevelNearest(lod > 0.0f ? m_minFilter : m_magFilter);
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Grid		grid				(GRID_SIZE_CUBE, rend.region.size(), getTextureSize(*m_textures[rend.textureNdx]),
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 TexTypeCoordParams<TEXTURETYPE_CUBE>(rend.texCoordScale, rend.texCoordOffset, (tcu::CubeFace)i), useSafeTexCoords);
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glViewport(viewportXOffset + rend.region.x, viewportYOffset + rend.region.y, rend.region.w, rend.region.h);
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderCell				(rend.textureNdx, lod, grid);
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			computeReferenceCell	(rend.textureNdx, lod, grid, refImage, rend.region);
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read back rendered results.
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface resImage(viewportWidth, viewportHeight);
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewportXOffset, viewportYOffset, resImage.getAccess());
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glUseProgram(0);
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare and log.
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool isOk = compareImages(m_context.getRenderContext(), m_testCtx.getLog(), refImage, resImage);
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								isOk ? "Pass"				: "Image comparison failed");
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VertexCubeTextureCase::setupShaderInputs (int textureNdx, float lod, const Grid& grid) const
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32 programID = m_program->getProgram();
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// SETUP ATTRIBUTES.
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int positionLoc = glGetAttribLocation(programID, "a_position");
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (positionLoc != -1)
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glEnableVertexAttribArray(positionLoc);
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getPositionPtr());
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texCoordLoc = glGetAttribLocation(programID, "a_texCoord");
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texCoordLoc != -1)
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glEnableVertexAttribArray(texCoordLoc);
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glVertexAttribPointer(texCoordLoc, 3, GL_FLOAT, GL_FALSE, 0, grid.getTexCoordPtr());
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// SETUP UNIFORMS.
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int lodLoc = glGetUniformLocation(programID, "u_lod");
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (lodLoc != -1)
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glUniform1f(lodLoc, lod);
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glActiveTexture(GL_TEXTURE0);
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glBindTexture(GL_TEXTURE_CUBE_MAP, m_textures[textureNdx]->getGLTexture());
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	m_minFilter);
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	m_magFilter);
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texLoc = glGetUniformLocation(programID, "u_texture");
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texLoc != -1)
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glUniform1i(texLoc, 0);
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Renders one cube face with given parameters.
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VertexCubeTextureCase::renderCell (int textureNdx, float lod, const Grid& grid) const
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setupShaderInputs(textureNdx, lod, grid);
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glDrawElements(GL_TRIANGLES, grid.getNumIndices(), GL_UNSIGNED_SHORT, grid.getIndexPtr());
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Computes reference for one cube face with given parameters.
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VertexCubeTextureCase::computeReferenceCell (int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Sampler sampler = glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	sampler.seamlessCubeMap = true;
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	computeReference(m_textures[textureNdx]->getRefTexture(), lod, sampler, grid, dst, dstRegion);
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Vertex2DArrayTextureCase : public TestCase
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Vertex2DArrayTextureCase	(Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT);
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~Vertex2DArrayTextureCase	(void);
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						init						(void);
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						deinit						(void);
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate						(void);
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef PosTexCoordQuadGrid<TEXTURETYPE_2D_ARRAY> Grid;
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Vertex2DArrayTextureCase	(const Vertex2DArrayTextureCase& other);
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vertex2DArrayTextureCase&	operator=					(const Vertex2DArrayTextureCase& other);
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						calculateLod				(const Mat3& transf, const Vec2& dstSize, int textureNdx) const;
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						setupShaderInputs			(int textureNdx, float lod, const Grid& grid) const;
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						renderCell					(int textureNdx, float lod, const Grid& grid) const;
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						computeReferenceCell		(int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const;
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_minFilter;
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_magFilter;
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_wrapS;
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_wrapT;
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderProgram*	m_program;
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture2DArray*		m_textures[2];	// 2 textures, a gradient texture and a grid texture.
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11573c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertex2DArrayTextureCase::Vertex2DArrayTextureCase (Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT)
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(testCtx, tcu::NODETYPE_SELF_VALIDATE, name, desc)
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter			(minFilter)
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter			(magFilter)
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS				(wrapS)
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT				(wrapT)
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program				(DE_NULL)
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures[0] = DE_NULL;
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures[1] = DE_NULL;
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11693c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertex2DArrayTextureCase::~Vertex2DArrayTextureCase(void)
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vertex2DArrayTextureCase::deinit();
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Vertex2DArrayTextureCase::init (void)
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* const vertexShaderSource =
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in highp vec2 a_position;\n"
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in highp vec3 a_texCoord;\n"
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform highp sampler2DArray u_texture;\n"
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform highp float u_lod;\n"
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"out mediump vec4 v_color;\n"
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_color = textureLod(u_texture, a_texCoord, u_lod);\n"
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* const fragmentShaderSource =
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in mediump vec4 v_color;\n"
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	dEQP_FragColor = v_color;\n"
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_context.getRenderTarget().getNumSamples() != 0)
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("MSAA config not supported by this test");
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create shader.
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_program);
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if(!m_program->isOk())
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << *m_program;
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint maxVertexTextures;
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextures);
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (maxVertexTextures < 1)
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Vertex texture image units not supported", "", __FILE__, __LINE__);
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Failed to compile shader");
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Make the textures.
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texWidth	= WIDTH_2D_ARRAY;
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texHeight	= HEIGHT_2D_ARRAY;
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texLayers	= LAYERS_2D_ARRAY;
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 2; i++)
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(!m_textures[i]);
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[i] = new glu::Texture2DArray(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, texWidth, texHeight, texLayers);
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int						numLevels	= deLog2Floor32(de::max(texWidth, texHeight)) + 1;
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec4						cBias		= fmtInfo.valueMin;
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec4						cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill first with gradient texture.
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4 gMin = Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias;
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4 gMax = Vec4( 1.0f,  1.0f,  1.0f, 0.0f)*cScale + cBias;
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[0]->getRefTexture().allocLevel(levelNdx);
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevel(levelNdx), gMin, gMax);
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill second with grid texture.
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32 step		= 0x00ffffff / numLevels;
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32 rgb		= step*levelNdx;
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32 colorA	= 0xff000000 | rgb;
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32 colorB	= 0xff000000 | ~rgb;
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[1]->getRefTexture().allocLevel(levelNdx);
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevel(levelNdx), 4, toVec4(tcu::RGBA(colorA))*cScale + cBias, toVec4(tcu::RGBA(colorB))*cScale + cBias);
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Upload.
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 2; i++)
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[i]->upload();
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const std::exception&)
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up to save memory.
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vertex2DArrayTextureCase::deinit();
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Vertex2DArrayTextureCase::deinit (void)
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 2; i++)
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_textures[i];
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures[i] = DE_NULL;
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_program;
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = DE_NULL;
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Vertex2DArrayTextureCase::calculateLod (const Mat3& transf, const Vec2& dstSize, int textureNdx) const
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Texture2DArray&	refTexture	= m_textures[textureNdx]->getRefTexture();
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					texWidth	= refTexture.getWidth();
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int					texHeight	= refTexture.getHeight();
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Calculate transformed coordinates of three screen corners.
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2					trans00		= (transf * Vec3(0.0f, 0.0f, 1.0f)).xy();
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2					trans01		= (transf * Vec3(0.0f, 1.0f, 1.0f)).xy();
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec2					trans10		= (transf * Vec3(1.0f, 0.0f, 1.0f)).xy();
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Derivates.
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dudx = (trans10.x() - trans00.x()) * (float)texWidth / dstSize.x();
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dudy = (trans01.x() - trans00.x()) * (float)texWidth / dstSize.y();
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dvdx = (trans10.y() - trans00.y()) * (float)texHeight / dstSize.x();
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dvdy = (trans01.y() - trans00.y()) * (float)texHeight / dstSize.y();
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deFloatLog2(deFloatSqrt(de::max(dudx*dudx + dvdx*dvdx, dudy*dudy + dvdy*dvdy)));
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13063c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertex2DArrayTextureCase::IterateResult Vertex2DArrayTextureCase::iterate (void)
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportWidth		= deMin32(m_context.getRenderTarget().getWidth(), MAX_2D_ARRAY_RENDER_WIDTH);
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportHeight		= deMin32(m_context.getRenderTarget().getHeight(), MAX_2D_ARRAY_RENDER_HEIGHT);
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportXOffsetMax	= m_context.getRenderTarget().getWidth() - viewportWidth;
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportYOffsetMax	= m_context.getRenderTarget().getHeight() - viewportHeight;
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random	rnd					(deStringHash(getName()));
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportXOffset		= rnd.getInt(0, viewportXOffsetMax);
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportYOffset		= rnd.getInt(0, viewportYOffsetMax);
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glUseProgram(m_program->getProgram());
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Divide viewport into 4 cells.
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int leftWidth		= viewportWidth / 2;
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int rightWidth	= viewportWidth - leftWidth;
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int bottomHeight	= viewportHeight / 2;
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int topHeight		= viewportHeight - bottomHeight;
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clear.
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glClearColor(0.125f, 0.25f, 0.5f, 1.0f);
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glClear(GL_COLOR_BUFFER_BIT);
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Shear by layer count to get all layers visible.
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const float layerShearTransfData[] =
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		1.0f,					0.0f, 0.0f,
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.0f,					1.0f, 0.0f,
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(float)LAYERS_2D_ARRAY, 0.0f, 0.0f
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Minification and magnification transformations.
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const float texMinTransfData[] =
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		2.1f,  0.0f, -0.3f,
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.0f,  2.1f, -0.3f,
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.0f,  0.0f,  1.0f
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const float texMagTransfData[] =
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.4f,  0.0f,  0.8f,
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.0f,  0.4f,  0.8f,
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.0f,  0.0f,  1.0f
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Transformation matrices for minification and magnification.
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Mat3 texMinTransf = Mat3(layerShearTransfData) * Mat3(texMinTransfData);
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Mat3 texMagTransf = Mat3(layerShearTransfData) * Mat3(texMagTransfData);
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Surface for the reference image.
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface refImage(viewportWidth, viewportHeight);
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const struct Render
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Rect	region;
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int			textureNdx;
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Mat3	texTransform;
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render (const Rect& r, int tN, const Mat3& tT) : region(r), textureNdx(tN), texTransform(tT) {}
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} renders[] =
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(0,				0,				leftWidth,	bottomHeight),	0, texMinTransf),
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(leftWidth,		0,				rightWidth,	bottomHeight),	0, texMagTransf),
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(0,				bottomHeight,	leftWidth,	topHeight),		1, texMinTransf),
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(leftWidth,		bottomHeight,	rightWidth,	topHeight),		1, texMagTransf)
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renders); renderNdx++)
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Render&	rend				= renders[renderNdx];
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float		lod					= calculateLod(rend.texTransform, rend.region.size().asFloat(), rend.textureNdx);
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool		useSafeTexCoords	= isLevelNearest(lod > 0.0f ? m_minFilter : m_magFilter);
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Grid		grid				(GRID_SIZE_2D_ARRAY, rend.region.size(), getTextureSize(*m_textures[rend.textureNdx]),
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 TexTypeCoordParams<TEXTURETYPE_2D_ARRAY>(rend.texTransform), useSafeTexCoords);
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glViewport(viewportXOffset + rend.region.x, viewportYOffset + rend.region.y, rend.region.w, rend.region.h);
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderCell				(rend.textureNdx, lod, grid);
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			computeReferenceCell	(rend.textureNdx, lod, grid, refImage, rend.region);
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read back rendered results.
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface resImage(viewportWidth, viewportHeight);
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewportXOffset, viewportYOffset, resImage.getAccess());
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glUseProgram(0);
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare and log.
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool isOk = compareImages(m_context.getRenderContext(), m_testCtx.getLog(), refImage, resImage);
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								isOk ? "Pass"				: "Image comparison failed");
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Vertex2DArrayTextureCase::setupShaderInputs (int textureNdx, float lod, const Grid& grid) const
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32 programID = m_program->getProgram();
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// SETUP ATTRIBUTES.
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int positionLoc = glGetAttribLocation(programID, "a_position");
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (positionLoc != -1)
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glEnableVertexAttribArray(positionLoc);
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getPositionPtr());
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texCoordLoc = glGetAttribLocation(programID, "a_texCoord");
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texCoordLoc != -1)
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glEnableVertexAttribArray(texCoordLoc);
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glVertexAttribPointer(texCoordLoc, 3, GL_FLOAT, GL_FALSE, 0, grid.getTexCoordPtr());
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// SETUP UNIFORMS.
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int lodLoc = glGetUniformLocation(programID, "u_lod");
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (lodLoc != -1)
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glUniform1f(lodLoc, lod);
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glActiveTexture(GL_TEXTURE0);
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glBindTexture(GL_TEXTURE_2D_ARRAY, m_textures[textureNdx]->getGLTexture());
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S,		m_wrapS);
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T,		m_wrapT);
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER,	m_minFilter);
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,	m_magFilter);
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texLoc = glGetUniformLocation(programID, "u_texture");
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texLoc != -1)
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glUniform1i(texLoc, 0);
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Renders one sub-image with given parameters.
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Vertex2DArrayTextureCase::renderCell (int textureNdx, float lod, const Grid& grid) const
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setupShaderInputs(textureNdx, lod, grid);
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glDrawElements(GL_TRIANGLES, grid.getNumIndices(), GL_UNSIGNED_SHORT, grid.getIndexPtr());
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Computes reference for one sub-image with given parameters.
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Vertex2DArrayTextureCase::computeReferenceCell (int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	computeReference(m_textures[textureNdx]->getRefTexture(), lod, glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter), grid, dst, dstRegion);
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Vertex3DTextureCase : public TestCase
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Vertex3DTextureCase		(Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 wrapR);
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~Vertex3DTextureCase	(void);
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						init					(void);
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						deinit					(void);
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate					(void);
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	typedef PosTexCoordQuadGrid<TEXTURETYPE_3D> Grid;
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								Vertex3DTextureCase		(const Vertex3DTextureCase& other);
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vertex3DTextureCase&		operator=				(const Vertex3DTextureCase& other);
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float						calculateLod			(const Mat3& transf, const Vec2& dstSize, int textureNdx) const;
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						setupShaderInputs		(int textureNdx, float lod, const Grid& grid) const;
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						renderCell				(int textureNdx, float lod, const Grid& grid) const;
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						computeReferenceCell	(int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const;
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_minFilter;
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_magFilter;
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_wrapS;
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_wrapT;
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32				m_wrapR;
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::ShaderProgram*	m_program;
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture3D*				m_textures[2];	// 2 textures, a gradient texture and a grid texture.
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14963c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertex3DTextureCase::Vertex3DTextureCase (Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 wrapR)
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase				(testCtx, tcu::NODETYPE_SELF_VALIDATE, name, desc)
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_minFilter			(minFilter)
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_magFilter			(magFilter)
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapS				(wrapS)
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapT				(wrapT)
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_wrapR				(wrapR)
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_program				(DE_NULL)
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures[0] = DE_NULL;
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures[1] = DE_NULL;
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertex3DTextureCase::~Vertex3DTextureCase(void)
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Vertex3DTextureCase::deinit();
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Vertex3DTextureCase::init (void)
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* const vertexShaderSource =
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in highp vec2 a_position;\n"
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in highp vec3 a_texCoord;\n"
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform highp sampler3D u_texture;\n"
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform highp float u_lod;\n"
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"out mediump vec4 v_color;\n"
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_color = textureLod(u_texture, a_texCoord, u_lod);\n"
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* const fragmentShaderSource =
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#version 300 es\n"
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"in mediump vec4 v_color;\n"
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	dEQP_FragColor = v_color;\n"
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n";
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_context.getRenderTarget().getNumSamples() != 0)
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::NotSupportedError("MSAA config not supported by this test");
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Create shader.
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!m_program);
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if(!m_program->isOk())
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.getLog() << *m_program;
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLint maxVertexTextures;
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextures);
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (maxVertexTextures < 1)
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			throw tcu::NotSupportedError("Vertex texture image units not supported", "", __FILE__, __LINE__);
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Failed to compile shader");
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Make the textures.
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	try
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texWidth	= WIDTH_3D;
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texHeight	= HEIGHT_3D;
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texDepth	= DEPTH_3D;
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 2; i++)
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(!m_textures[i]);
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[i] = new glu::Texture3D(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, texWidth, texHeight, texDepth);
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int						numLevels	= deLog2Floor32(de::max(de::max(texWidth, texHeight), texDepth)) + 1;
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec4						cBias		= fmtInfo.valueMin;
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec4						cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill first with gradient texture.
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4 gMin = Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias;
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Vec4 gMax = Vec4( 1.0f,  1.0f,  1.0f, 0.0f)*cScale + cBias;
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[0]->getRefTexture().allocLevel(levelNdx);
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevel(levelNdx), gMin, gMax);
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Fill second with grid texture.
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32 step		= 0x00ffffff / numLevels;
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32 rgb		= step*levelNdx;
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32 colorA	= 0xff000000 | rgb;
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32 colorB	= 0xff000000 | ~rgb;
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[1]->getRefTexture().allocLevel(levelNdx);
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevel(levelNdx), 4, toVec4(tcu::RGBA(colorA))*cScale + cBias, toVec4(tcu::RGBA(colorB))*cScale + cBias);
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Upload.
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 2; i++)
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_textures[i]->upload();
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	catch (const std::exception&)
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Clean up to save memory.
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Vertex3DTextureCase::deinit();
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw;
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Vertex3DTextureCase::deinit (void)
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < 2; i++)
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete m_textures[i];
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures[i] = DE_NULL;
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_program;
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_program = DE_NULL;
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryfloat Vertex3DTextureCase::calculateLod (const Mat3& transf, const Vec2& dstSize, int textureNdx) const
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::Texture3D&	refTexture	= m_textures[textureNdx]->getRefTexture();
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				srcWidth	= refTexture.getWidth();
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				srcHeight	= refTexture.getHeight();
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int				srcDepth	= refTexture.getDepth();
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Calculate transformed coordinates of three screen corners.
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec3				trans00		= transf * Vec3(0.0f, 0.0f, 1.0f);
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec3				trans01		= transf * Vec3(0.0f, 1.0f, 1.0f);
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Vec3				trans10		= transf * Vec3(1.0f, 0.0f, 1.0f);
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Derivates.
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dudx = (trans10.x() - trans00.x()) * (float)srcWidth / dstSize.x();
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dudy = (trans01.x() - trans00.x()) * (float)srcWidth / dstSize.y();
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dvdx = (trans10.y() - trans00.y()) * (float)srcHeight / dstSize.x();
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dvdy = (trans01.y() - trans00.y()) * (float)srcHeight / dstSize.y();
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dwdx = (trans10.z() - trans00.z()) * (float)srcDepth / dstSize.x();
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const float dwdy = (trans01.z() - trans00.z()) * (float)srcDepth / dstSize.y();
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deFloatLog2(deFloatSqrt(de::max(dudx*dudx + dvdx*dvdx + dwdx*dwdx, dudy*dudy + dvdy*dvdy + dwdy*dwdy)));
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16493c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertex3DTextureCase::IterateResult Vertex3DTextureCase::iterate (void)
16503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportWidth		= deMin32(m_context.getRenderTarget().getWidth(), MAX_3D_RENDER_WIDTH);
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportHeight		= deMin32(m_context.getRenderTarget().getHeight(), MAX_3D_RENDER_HEIGHT);
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportXOffsetMax	= m_context.getRenderTarget().getWidth() - viewportWidth;
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportYOffsetMax	= m_context.getRenderTarget().getHeight() - viewportHeight;
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random	rnd					(deStringHash(getName()));
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportXOffset		= rnd.getInt(0, viewportXOffsetMax);
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int	viewportYOffset		= rnd.getInt(0, viewportYOffsetMax);
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glUseProgram(m_program->getProgram());
16633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Divide viewport into 4 cells.
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int leftWidth		= viewportWidth / 2;
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int rightWidth		= viewportWidth - leftWidth;
16673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int bottomHeight	= viewportHeight / 2;
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int topHeight		= viewportHeight - bottomHeight;
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Clear.
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glClearColor(0.125f, 0.25f, 0.5f, 1.0f);
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glClear(GL_COLOR_BUFFER_BIT);
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Shear to get all slices visible.
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const float depthShearTransfData[] =
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		1.0f, 0.0f, 0.0f,
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.0f, 1.0f, 0.0f,
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		1.0f, 1.0f, 0.0f
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Minification and magnification transformations.
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const float texMinTransfData[] =
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		2.2f,  0.0f, -0.3f,
16863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.0f,  2.2f, -0.3f,
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.0f,  0.0f,  1.0f
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const float texMagTransfData[] =
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.4f,  0.0f,  0.8f,
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.0f,  0.4f,  0.8f,
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0.0f,  0.0f,  1.0f
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Transformation matrices for minification and magnification.
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Mat3 texMinTransf = Mat3(depthShearTransfData) * Mat3(texMinTransfData);
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Mat3 texMagTransf = Mat3(depthShearTransfData) * Mat3(texMagTransfData);
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Surface for the reference image.
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface refImage(viewportWidth, viewportHeight);
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const struct Render
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Rect	region;
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int			textureNdx;
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Mat3		texTransform;
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render (const Rect& r, int tN, const Mat3& tT) : region(r), textureNdx(tN), texTransform(tT) {}
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		} renders[] =
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(0,				0,				leftWidth,	bottomHeight),	0, texMinTransf),
17133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(leftWidth,		0,				rightWidth,	bottomHeight),	0, texMagTransf),
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(0,				bottomHeight,	leftWidth,	topHeight),		1, texMinTransf),
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			Render(Rect(leftWidth,		bottomHeight,	rightWidth,	topHeight),		1, texMagTransf)
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renders); renderNdx++)
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Render&	rend				= renders[renderNdx];
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float		lod					= calculateLod(rend.texTransform, rend.region.size().asFloat(), rend.textureNdx);
17223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool		useSafeTexCoords	= isLevelNearest(lod > 0.0f ? m_minFilter : m_magFilter);
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Grid		grid				(GRID_SIZE_3D, rend.region.size(), getTextureSize(*m_textures[rend.textureNdx]),
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 TexTypeCoordParams<TEXTURETYPE_3D>(rend.texTransform), useSafeTexCoords);
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glViewport(viewportXOffset + rend.region.x, viewportYOffset + rend.region.y, rend.region.w, rend.region.h);
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			renderCell				(rend.textureNdx, lod, grid);
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			computeReferenceCell	(rend.textureNdx, lod, grid, refImage, rend.region);
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Read back rendered results.
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Surface resImage(viewportWidth, viewportHeight);
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::readPixels(m_context.getRenderContext(), viewportXOffset, viewportYOffset, resImage.getAccess());
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glUseProgram(0);
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Compare and log.
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool isOk = compareImages(m_context.getRenderContext(), m_testCtx.getLog(), refImage, resImage);
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								isOk ? "Pass"				: "Image comparison failed");
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return STOP;
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Vertex3DTextureCase::setupShaderInputs (int textureNdx, float lod, const Grid& grid) const
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const deUint32 programID = m_program->getProgram();
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// SETUP ATTRIBUTES.
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int positionLoc = glGetAttribLocation(programID, "a_position");
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (positionLoc != -1)
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glEnableVertexAttribArray(positionLoc);
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getPositionPtr());
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texCoordLoc = glGetAttribLocation(programID, "a_texCoord");
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texCoordLoc != -1)
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glEnableVertexAttribArray(texCoordLoc);
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glVertexAttribPointer(texCoordLoc, 3, GL_FLOAT, GL_FALSE, 0, grid.getTexCoordPtr());
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// SETUP UNIFORMS.
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int lodLoc = glGetUniformLocation(programID, "u_lod");
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (lodLoc != -1)
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glUniform1f(lodLoc, lod);
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glActiveTexture(GL_TEXTURE0);
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glBindTexture(GL_TEXTURE_3D, m_textures[textureNdx]->getGLTexture());
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,		m_wrapS);
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,		m_wrapT);
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,		m_wrapR);
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,	m_magFilter);
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int texLoc = glGetUniformLocation(programID, "u_texture");
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (texLoc != -1)
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			glUniform1i(texLoc, 0);
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Renders one sub-image with given parameters.
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Vertex3DTextureCase::renderCell (int textureNdx, float lod, const Grid& grid) const
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	setupShaderInputs(textureNdx, lod, grid);
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glDrawElements(GL_TRIANGLES, grid.getNumIndices(), GL_UNSIGNED_SHORT, grid.getIndexPtr());
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Computes reference for one sub-image with given parameters.
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Vertex3DTextureCase::computeReferenceCell (int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	computeReference(m_textures[textureNdx]->getRefTexture(), lod, glu::mapGLSampler(m_wrapS, m_wrapT, m_wrapR, m_minFilter, m_magFilter), grid, dst, dstRegion);
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18093c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexTextureTests::VertexTextureTests (Context& context)
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "vertex", "Vertex Texture Tests")
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18143c827367444ee418f129b2c238299f49d3264554Jarkko PoyryVertexTextureTests::~VertexTextureTests(void)
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid VertexTextureTests::init (void)
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 2D and cube map groups, and their filtering and wrap sub-groups.
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const group2D				= new TestCaseGroup(m_context, "2d",			"2D Vertex Texture Tests");
18223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const groupCube				= new TestCaseGroup(m_context, "cube",			"Cube Map Vertex Texture Tests");
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const group2DArray			= new TestCaseGroup(m_context, "2d_array",		"2D Array Vertex Texture Tests");
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const group3D				= new TestCaseGroup(m_context, "3d",			"3D Vertex Texture Tests");
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const filteringGroup2D		= new TestCaseGroup(m_context, "filtering",		"2D Vertex Texture Filtering Tests");
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const wrapGroup2D			= new TestCaseGroup(m_context, "wrap",			"2D Vertex Texture Wrap Tests");
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const filteringGroupCube		= new TestCaseGroup(m_context, "filtering",		"Cube Map Vertex Texture Filtering Tests");
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const wrapGroupCube			= new TestCaseGroup(m_context, "wrap",			"Cube Map Vertex Texture Wrap Tests");
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const filteringGroup2DArray	= new TestCaseGroup(m_context, "filtering",		"2D Array Vertex Texture Filtering Tests");
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const wrapGroup2DArray		= new TestCaseGroup(m_context, "wrap",			"2D Array Vertex Texture Wrap Tests");
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const filteringGroup3D		= new TestCaseGroup(m_context, "filtering",		"3D Vertex Texture Filtering Tests");
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const wrapGroup3D			= new TestCaseGroup(m_context, "wrap",			"3D Vertex Texture Wrap Tests");
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	group2D->addChild(filteringGroup2D);
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	group2D->addChild(wrapGroup2D);
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	groupCube->addChild(filteringGroupCube);
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	groupCube->addChild(wrapGroupCube);
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	group2DArray->addChild(filteringGroup2DArray);
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	group2DArray->addChild(wrapGroup2DArray);
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	group3D->addChild(filteringGroup3D);
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	group3D->addChild(wrapGroup3D);
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(group2D);
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(groupCube);
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(group2DArray);
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(group3D);
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLenum			mode;
18523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} wrapModes[] =
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "clamp",		GL_CLAMP_TO_EDGE	},
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "repeat",		GL_REPEAT			},
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "mirror",		GL_MIRRORED_REPEAT	}
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLenum			mode;
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} minFilterModes[] =
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest",				GL_NEAREST					},
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear",					GL_LINEAR					},
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest_mipmap_nearest",	GL_NEAREST_MIPMAP_NEAREST	},
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear_mipmap_nearest",	GL_LINEAR_MIPMAP_NEAREST	},
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest_mipmap_linear",	GL_NEAREST_MIPMAP_LINEAR	},
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear_mipmap_linear",	GL_LINEAR_MIPMAP_LINEAR		}
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const struct
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char*		name;
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLenum			mode;
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	} magFilterModes[] =
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "nearest",	GL_NEAREST	},
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{ "linear",		GL_LINEAR	}
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define FOR_EACH(ITERATOR, ARRAY, BODY)	\
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ITERATOR = 0; ITERATOR < DE_LENGTH_OF_ARRAY(ARRAY); ITERATOR++)	\
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BODY
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 2D cases.
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(minFilter,		minFilterModes,
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(magFilter,		magFilterModes,
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapMode,		wrapModes,
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name;
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			filteringGroup2D->addChild(new Vertex2DTextureCase(m_context,
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   name.c_str(), "",
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   minFilterModes[minFilter].mode,
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   magFilterModes[magFilter].mode,
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   wrapModes[wrapMode].mode,
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   wrapModes[wrapMode].mode));
19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		})));
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapSMode,		wrapModes,
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapTMode,		wrapModes,
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string name = string("") + wrapModes[wrapSMode].name + "_" + wrapModes[wrapTMode].name;
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			wrapGroup2D->addChild(new Vertex2DTextureCase(m_context,
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														  name.c_str(), "",
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														  GL_LINEAR_MIPMAP_LINEAR,
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														  GL_LINEAR,
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														  wrapModes[wrapSMode].mode,
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														  wrapModes[wrapTMode].mode));
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}));
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Cube map cases.
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(minFilter,		minFilterModes,
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(magFilter,		magFilterModes,
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapMode,		wrapModes,
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name;
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			filteringGroupCube->addChild(new VertexCubeTextureCase(m_context,
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																   name.c_str(), "",
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																   minFilterModes[minFilter].mode,
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																   magFilterModes[magFilter].mode,
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																   wrapModes[wrapMode].mode,
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																   wrapModes[wrapMode].mode));
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		})));
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapSMode,		wrapModes,
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapTMode,		wrapModes,
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string name = string("") + wrapModes[wrapSMode].name + "_" + wrapModes[wrapTMode].name;
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			wrapGroupCube->addChild(new VertexCubeTextureCase(m_context,
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															  name.c_str(), "",
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															  GL_LINEAR_MIPMAP_LINEAR,
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															  GL_LINEAR,
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															  wrapModes[wrapSMode].mode,
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															  wrapModes[wrapTMode].mode));
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}));
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 2D array cases.
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(minFilter,		minFilterModes,
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(magFilter,		magFilterModes,
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapMode,		wrapModes,
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name;
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			filteringGroup2DArray->addChild(new Vertex2DArrayTextureCase(m_context,
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 name.c_str(), "",
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 minFilterModes[minFilter].mode,
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 magFilterModes[magFilter].mode,
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 wrapModes[wrapMode].mode,
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		 wrapModes[wrapMode].mode));
19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		})));
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapSMode,		wrapModes,
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapTMode,		wrapModes,
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string name = string("") + wrapModes[wrapSMode].name + "_" + wrapModes[wrapTMode].name;
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			wrapGroup2DArray->addChild(new Vertex2DArrayTextureCase(m_context,
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	name.c_str(), "",
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	GL_LINEAR_MIPMAP_LINEAR,
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	GL_LINEAR,
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	wrapModes[wrapSMode].mode,
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	wrapModes[wrapTMode].mode));
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}));
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// 3D cases.
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(minFilter,		minFilterModes,
19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(magFilter,		magFilterModes,
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapMode,		wrapModes,
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name;
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			filteringGroup3D->addChild(new Vertex3DTextureCase(m_context,
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   name.c_str(), "",
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   minFilterModes[minFilter].mode,
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   magFilterModes[magFilter].mode,
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   wrapModes[wrapMode].mode,
19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   wrapModes[wrapMode].mode,
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															   wrapModes[wrapMode].mode));
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		})));
19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapSMode,		wrapModes,
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapTMode,		wrapModes,
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FOR_EACH(wrapRMode,		wrapModes,
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string name = string("") + wrapModes[wrapSMode].name + "_" + wrapModes[wrapTMode].name + "_" + wrapModes[wrapRMode].name;
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			wrapGroup3D->addChild(new Vertex3DTextureCase(m_context,
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														  name.c_str(), "",
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														  GL_LINEAR_MIPMAP_LINEAR,
20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														  GL_LINEAR,
20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														  wrapModes[wrapSMode].mode,
20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														  wrapModes[wrapTMode].mode,
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														  wrapModes[wrapRMode].mode));
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		})));
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional
20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles3
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
2010