xref: /aosp_15_r20/external/deqp/modules/gles2/functional/es2fVertexTextureTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 2.0 Module
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Vertex texture tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es2fVertexTextureTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "glsTextureTestUtil.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "gluTexture.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "gluTextureUtil.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuVector.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuMatrix.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "tcuTexVerifierUtil.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "deString.h"
36*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
37*35238bceSAndroid Build Coastguard Worker 
38*35238bceSAndroid Build Coastguard Worker #include <string>
39*35238bceSAndroid Build Coastguard Worker #include <vector>
40*35238bceSAndroid Build Coastguard Worker 
41*35238bceSAndroid Build Coastguard Worker #include <limits>
42*35238bceSAndroid Build Coastguard Worker 
43*35238bceSAndroid Build Coastguard Worker #include "glw.h"
44*35238bceSAndroid Build Coastguard Worker 
45*35238bceSAndroid Build Coastguard Worker using std::string;
46*35238bceSAndroid Build Coastguard Worker using std::vector;
47*35238bceSAndroid Build Coastguard Worker using tcu::IVec2;
48*35238bceSAndroid Build Coastguard Worker using tcu::IVec3;
49*35238bceSAndroid Build Coastguard Worker using tcu::IVec4;
50*35238bceSAndroid Build Coastguard Worker using tcu::Mat3;
51*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
52*35238bceSAndroid Build Coastguard Worker using tcu::Vec2;
53*35238bceSAndroid Build Coastguard Worker using tcu::Vec3;
54*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
55*35238bceSAndroid Build Coastguard Worker 
56*35238bceSAndroid Build Coastguard Worker namespace deqp
57*35238bceSAndroid Build Coastguard Worker {
58*35238bceSAndroid Build Coastguard Worker 
59*35238bceSAndroid Build Coastguard Worker using namespace gls::TextureTestUtil;
60*35238bceSAndroid Build Coastguard Worker using namespace glu::TextureTestUtil;
61*35238bceSAndroid Build Coastguard Worker 
62*35238bceSAndroid Build Coastguard Worker using glu::TextureTestUtil::TEXTURETYPE_2D;
63*35238bceSAndroid Build Coastguard Worker using glu::TextureTestUtil::TEXTURETYPE_CUBE;
64*35238bceSAndroid Build Coastguard Worker 
65*35238bceSAndroid Build Coastguard Worker namespace gles2
66*35238bceSAndroid Build Coastguard Worker {
67*35238bceSAndroid Build Coastguard Worker namespace Functional
68*35238bceSAndroid Build Coastguard Worker {
69*35238bceSAndroid Build Coastguard Worker 
70*35238bceSAndroid Build Coastguard Worker // The 2D case draws four images.
71*35238bceSAndroid Build Coastguard Worker static const int MAX_2D_RENDER_WIDTH  = 128 * 2;
72*35238bceSAndroid Build Coastguard Worker static const int MAX_2D_RENDER_HEIGHT = 128 * 2;
73*35238bceSAndroid Build Coastguard Worker 
74*35238bceSAndroid Build Coastguard Worker // The cube map case draws four 3-by-2 image groups.
75*35238bceSAndroid Build Coastguard Worker static const int MAX_CUBE_RENDER_WIDTH  = 28 * 2 * 3;
76*35238bceSAndroid Build Coastguard Worker static const int MAX_CUBE_RENDER_HEIGHT = 28 * 2 * 2;
77*35238bceSAndroid Build Coastguard Worker 
78*35238bceSAndroid Build Coastguard Worker static const int GRID_SIZE_2D   = 127;
79*35238bceSAndroid Build Coastguard Worker static const int GRID_SIZE_CUBE = 63;
80*35238bceSAndroid Build Coastguard Worker 
81*35238bceSAndroid Build Coastguard Worker // Helpers for making texture coordinates "safe", i.e. move them further from coordinate bounary.
82*35238bceSAndroid Build Coastguard Worker 
83*35238bceSAndroid Build Coastguard Worker // Moves x towards the closest K+targetFraction, where K is an integer.
84*35238bceSAndroid Build Coastguard Worker // E.g. moveTowardsFraction(x, 0.5f) moves x away from integer boundaries.
moveTowardsFraction(float x,float targetFraction)85*35238bceSAndroid Build Coastguard Worker static inline float moveTowardsFraction(float x, float targetFraction)
86*35238bceSAndroid Build Coastguard Worker {
87*35238bceSAndroid Build Coastguard Worker     const float strictness = 0.5f;
88*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(0.0f < strictness && strictness <= 1.0f);
89*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inBounds(targetFraction, 0.0f, 1.0f));
90*35238bceSAndroid Build Coastguard Worker     const float y = x + 0.5f - targetFraction;
91*35238bceSAndroid Build Coastguard Worker     return deFloatFloor(y) + deFloatFrac(y) * (1.0f - strictness) + strictness * 0.5f - 0.5f + targetFraction;
92*35238bceSAndroid Build Coastguard Worker }
93*35238bceSAndroid Build Coastguard Worker 
safeCoord(float raw,int scale,float fraction)94*35238bceSAndroid Build Coastguard Worker static inline float safeCoord(float raw, int scale, float fraction)
95*35238bceSAndroid Build Coastguard Worker {
96*35238bceSAndroid Build Coastguard Worker     const float scaleFloat = (float)scale;
97*35238bceSAndroid Build Coastguard Worker     return moveTowardsFraction(raw * scaleFloat, fraction) / scaleFloat;
98*35238bceSAndroid Build Coastguard Worker }
99*35238bceSAndroid Build Coastguard Worker 
100*35238bceSAndroid Build Coastguard Worker template <int Size>
safeCoords(const tcu::Vector<float,Size> & raw,const tcu::Vector<int,Size> & scale,const tcu::Vector<float,Size> & fraction)101*35238bceSAndroid Build Coastguard Worker static inline tcu::Vector<float, Size> safeCoords(const tcu::Vector<float, Size> &raw,
102*35238bceSAndroid Build Coastguard Worker                                                   const tcu::Vector<int, Size> &scale,
103*35238bceSAndroid Build Coastguard Worker                                                   const tcu::Vector<float, Size> &fraction)
104*35238bceSAndroid Build Coastguard Worker {
105*35238bceSAndroid Build Coastguard Worker     tcu::Vector<float, Size> result;
106*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < Size; i++)
107*35238bceSAndroid Build Coastguard Worker         result[i] = safeCoord(raw[i], scale[i], fraction[i]);
108*35238bceSAndroid Build Coastguard Worker     return result;
109*35238bceSAndroid Build Coastguard Worker }
110*35238bceSAndroid Build Coastguard Worker 
safe2DTexCoords(const Vec2 & raw,const IVec2 & textureSize)111*35238bceSAndroid Build Coastguard Worker static inline Vec2 safe2DTexCoords(const Vec2 &raw, const IVec2 &textureSize)
112*35238bceSAndroid Build Coastguard Worker {
113*35238bceSAndroid Build Coastguard Worker     return safeCoords(raw, textureSize, Vec2(0.5f));
114*35238bceSAndroid Build Coastguard Worker }
115*35238bceSAndroid Build Coastguard Worker 
116*35238bceSAndroid Build Coastguard Worker namespace
117*35238bceSAndroid Build Coastguard Worker {
118*35238bceSAndroid Build Coastguard Worker 
119*35238bceSAndroid Build Coastguard Worker struct Rect
120*35238bceSAndroid Build Coastguard Worker {
Rectdeqp::gles2::Functional::__anon5fadc2590111::Rect121*35238bceSAndroid Build Coastguard Worker     Rect(int x_, int y_, int w_, int h_) : x(x_), y(y_), w(w_), h(h_)
122*35238bceSAndroid Build Coastguard Worker     {
123*35238bceSAndroid Build Coastguard Worker     }
posdeqp::gles2::Functional::__anon5fadc2590111::Rect124*35238bceSAndroid Build Coastguard Worker     IVec2 pos(void) const
125*35238bceSAndroid Build Coastguard Worker     {
126*35238bceSAndroid Build Coastguard Worker         return IVec2(x, y);
127*35238bceSAndroid Build Coastguard Worker     }
sizedeqp::gles2::Functional::__anon5fadc2590111::Rect128*35238bceSAndroid Build Coastguard Worker     IVec2 size(void) const
129*35238bceSAndroid Build Coastguard Worker     {
130*35238bceSAndroid Build Coastguard Worker         return IVec2(w, h);
131*35238bceSAndroid Build Coastguard Worker     }
132*35238bceSAndroid Build Coastguard Worker 
133*35238bceSAndroid Build Coastguard Worker     int x;
134*35238bceSAndroid Build Coastguard Worker     int y;
135*35238bceSAndroid Build Coastguard Worker     int w;
136*35238bceSAndroid Build Coastguard Worker     int h;
137*35238bceSAndroid Build Coastguard Worker };
138*35238bceSAndroid Build Coastguard Worker 
139*35238bceSAndroid Build Coastguard Worker template <TextureType>
140*35238bceSAndroid Build Coastguard Worker struct TexTypeTcuClass;
141*35238bceSAndroid Build Coastguard Worker template <>
142*35238bceSAndroid Build Coastguard Worker struct TexTypeTcuClass<TEXTURETYPE_2D>
143*35238bceSAndroid Build Coastguard Worker {
144*35238bceSAndroid Build Coastguard Worker     typedef tcu::Texture2D t;
145*35238bceSAndroid Build Coastguard Worker };
146*35238bceSAndroid Build Coastguard Worker template <>
147*35238bceSAndroid Build Coastguard Worker struct TexTypeTcuClass<TEXTURETYPE_CUBE>
148*35238bceSAndroid Build Coastguard Worker {
149*35238bceSAndroid Build Coastguard Worker     typedef tcu::TextureCube t;
150*35238bceSAndroid Build Coastguard Worker };
151*35238bceSAndroid Build Coastguard Worker 
152*35238bceSAndroid Build Coastguard Worker template <TextureType>
153*35238bceSAndroid Build Coastguard Worker struct TexTypeSizeDims;
154*35238bceSAndroid Build Coastguard Worker template <>
155*35238bceSAndroid Build Coastguard Worker struct TexTypeSizeDims<TEXTURETYPE_2D>
156*35238bceSAndroid Build Coastguard Worker {
157*35238bceSAndroid Build Coastguard Worker     enum
158*35238bceSAndroid Build Coastguard Worker     {
159*35238bceSAndroid Build Coastguard Worker         V = 2
160*35238bceSAndroid Build Coastguard Worker     };
161*35238bceSAndroid Build Coastguard Worker };
162*35238bceSAndroid Build Coastguard Worker template <>
163*35238bceSAndroid Build Coastguard Worker struct TexTypeSizeDims<TEXTURETYPE_CUBE>
164*35238bceSAndroid Build Coastguard Worker {
165*35238bceSAndroid Build Coastguard Worker     enum
166*35238bceSAndroid Build Coastguard Worker     {
167*35238bceSAndroid Build Coastguard Worker         V = 2
168*35238bceSAndroid Build Coastguard Worker     };
169*35238bceSAndroid Build Coastguard Worker };
170*35238bceSAndroid Build Coastguard Worker 
171*35238bceSAndroid Build Coastguard Worker template <TextureType>
172*35238bceSAndroid Build Coastguard Worker struct TexTypeCoordDims;
173*35238bceSAndroid Build Coastguard Worker template <>
174*35238bceSAndroid Build Coastguard Worker struct TexTypeCoordDims<TEXTURETYPE_2D>
175*35238bceSAndroid Build Coastguard Worker {
176*35238bceSAndroid Build Coastguard Worker     enum
177*35238bceSAndroid Build Coastguard Worker     {
178*35238bceSAndroid Build Coastguard Worker         V = 2
179*35238bceSAndroid Build Coastguard Worker     };
180*35238bceSAndroid Build Coastguard Worker };
181*35238bceSAndroid Build Coastguard Worker template <>
182*35238bceSAndroid Build Coastguard Worker struct TexTypeCoordDims<TEXTURETYPE_CUBE>
183*35238bceSAndroid Build Coastguard Worker {
184*35238bceSAndroid Build Coastguard Worker     enum
185*35238bceSAndroid Build Coastguard Worker     {
186*35238bceSAndroid Build Coastguard Worker         V = 3
187*35238bceSAndroid Build Coastguard Worker     };
188*35238bceSAndroid Build Coastguard Worker };
189*35238bceSAndroid Build Coastguard Worker 
190*35238bceSAndroid Build Coastguard Worker template <TextureType TexType>
191*35238bceSAndroid Build Coastguard Worker struct TexTypeSizeIVec
192*35238bceSAndroid Build Coastguard Worker {
193*35238bceSAndroid Build Coastguard Worker     typedef tcu::Vector<int, TexTypeSizeDims<TexType>::V> t;
194*35238bceSAndroid Build Coastguard Worker };
195*35238bceSAndroid Build Coastguard Worker template <TextureType TexType>
196*35238bceSAndroid Build Coastguard Worker struct TexTypeCoordVec
197*35238bceSAndroid Build Coastguard Worker {
198*35238bceSAndroid Build Coastguard Worker     typedef tcu::Vector<float, TexTypeCoordDims<TexType>::V> t;
199*35238bceSAndroid Build Coastguard Worker };
200*35238bceSAndroid Build Coastguard Worker 
201*35238bceSAndroid Build Coastguard Worker template <TextureType>
202*35238bceSAndroid Build Coastguard Worker struct TexTypeCoordParams;
203*35238bceSAndroid Build Coastguard Worker 
204*35238bceSAndroid Build Coastguard Worker template <>
205*35238bceSAndroid Build Coastguard Worker struct TexTypeCoordParams<TEXTURETYPE_2D>
206*35238bceSAndroid Build Coastguard Worker {
207*35238bceSAndroid Build Coastguard Worker     Vec2 scale;
208*35238bceSAndroid Build Coastguard Worker     Vec2 bias;
209*35238bceSAndroid Build Coastguard Worker 
TexTypeCoordParamsdeqp::gles2::Functional::__anon5fadc2590111::TexTypeCoordParams210*35238bceSAndroid Build Coastguard Worker     TexTypeCoordParams(const Vec2 &scale_, const Vec2 &bias_) : scale(scale_), bias(bias_)
211*35238bceSAndroid Build Coastguard Worker     {
212*35238bceSAndroid Build Coastguard Worker     }
213*35238bceSAndroid Build Coastguard Worker };
214*35238bceSAndroid Build Coastguard Worker 
215*35238bceSAndroid Build Coastguard Worker template <>
216*35238bceSAndroid Build Coastguard Worker struct TexTypeCoordParams<TEXTURETYPE_CUBE>
217*35238bceSAndroid Build Coastguard Worker {
218*35238bceSAndroid Build Coastguard Worker     Vec2 scale;
219*35238bceSAndroid Build Coastguard Worker     Vec2 bias;
220*35238bceSAndroid Build Coastguard Worker     tcu::CubeFace face;
221*35238bceSAndroid Build Coastguard Worker 
TexTypeCoordParamsdeqp::gles2::Functional::__anon5fadc2590111::TexTypeCoordParams222*35238bceSAndroid Build Coastguard Worker     TexTypeCoordParams(const Vec2 &scale_, const Vec2 &bias_, tcu::CubeFace face_)
223*35238bceSAndroid Build Coastguard Worker         : scale(scale_)
224*35238bceSAndroid Build Coastguard Worker         , bias(bias_)
225*35238bceSAndroid Build Coastguard Worker         , face(face_)
226*35238bceSAndroid Build Coastguard Worker     {
227*35238bceSAndroid Build Coastguard Worker     }
228*35238bceSAndroid Build Coastguard Worker };
229*35238bceSAndroid Build Coastguard Worker 
230*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
231*35238bceSAndroid Build Coastguard Worker  * \brief Quad grid class containing position and texture coordinate data.
232*35238bceSAndroid Build Coastguard Worker  *
233*35238bceSAndroid Build Coastguard Worker  * A quad grid of size S means a grid consisting of S*S quads (S rows and
234*35238bceSAndroid Build Coastguard Worker  * S columns). The quads are rectangles with main axis aligned sides, and
235*35238bceSAndroid Build Coastguard Worker  * each consists of two triangles. Note that although there are only
236*35238bceSAndroid Build Coastguard Worker  * (S+1)*(S+1) distinct vertex positions, there are S*S*4 distinct vertices
237*35238bceSAndroid Build Coastguard Worker  * because we want texture coordinates to be constant across the vertices
238*35238bceSAndroid Build Coastguard Worker  * of a quad (to avoid interpolation issues), and thus each quad needs its
239*35238bceSAndroid Build Coastguard Worker  * own 4 vertices.
240*35238bceSAndroid Build Coastguard Worker  *
241*35238bceSAndroid Build Coastguard Worker  * Pointers returned by get*Ptr() are suitable for gl calls such as
242*35238bceSAndroid Build Coastguard Worker  * glVertexAttribPointer() (for position and tex coord) or glDrawElements()
243*35238bceSAndroid Build Coastguard Worker  * (for indices).
244*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
245*35238bceSAndroid Build Coastguard Worker template <TextureType TexType>
246*35238bceSAndroid Build Coastguard Worker class PosTexCoordQuadGrid
247*35238bceSAndroid Build Coastguard Worker {
248*35238bceSAndroid Build Coastguard Worker private:
249*35238bceSAndroid Build Coastguard Worker     enum
250*35238bceSAndroid Build Coastguard Worker     {
251*35238bceSAndroid Build Coastguard Worker         TEX_COORD_DIMS = TexTypeCoordDims<TexType>::V
252*35238bceSAndroid Build Coastguard Worker     };
253*35238bceSAndroid Build Coastguard Worker     typedef typename TexTypeCoordVec<TexType>::t TexCoordVec;
254*35238bceSAndroid Build Coastguard Worker     typedef typename TexTypeSizeIVec<TexType>::t TexSizeIVec;
255*35238bceSAndroid Build Coastguard Worker     typedef TexTypeCoordParams<TexType> TexCoordParams;
256*35238bceSAndroid Build Coastguard Worker 
257*35238bceSAndroid Build Coastguard Worker public:
258*35238bceSAndroid Build Coastguard Worker     PosTexCoordQuadGrid(int gridSize, const IVec2 &renderSize, const TexSizeIVec &textureSize,
259*35238bceSAndroid Build Coastguard Worker                         const TexCoordParams &texCoordParams, bool useSafeTexCoords);
260*35238bceSAndroid Build Coastguard Worker 
getSize(void) const261*35238bceSAndroid Build Coastguard Worker     int getSize(void) const
262*35238bceSAndroid Build Coastguard Worker     {
263*35238bceSAndroid Build Coastguard Worker         return m_gridSize;
264*35238bceSAndroid Build Coastguard Worker     }
265*35238bceSAndroid Build Coastguard Worker     Vec4 getQuadLDRU(int col, int row) const; //!< Vec4(leftX, downY, rightX, upY)
266*35238bceSAndroid Build Coastguard Worker     const TexCoordVec &getQuadTexCoord(int col, int row) const;
267*35238bceSAndroid Build Coastguard Worker 
getNumIndices(void) const268*35238bceSAndroid Build Coastguard Worker     int getNumIndices(void) const
269*35238bceSAndroid Build Coastguard Worker     {
270*35238bceSAndroid Build Coastguard Worker         return m_gridSize * m_gridSize * 3 * 2;
271*35238bceSAndroid Build Coastguard Worker     }
getPositionPtr(void) const272*35238bceSAndroid Build Coastguard Worker     const float *getPositionPtr(void) const
273*35238bceSAndroid Build Coastguard Worker     {
274*35238bceSAndroid Build Coastguard Worker         DE_STATIC_ASSERT(sizeof(Vec2) == 2 * sizeof(float));
275*35238bceSAndroid Build Coastguard Worker         return (float *)&m_positions[0];
276*35238bceSAndroid Build Coastguard Worker     }
getTexCoordPtr(void) const277*35238bceSAndroid Build Coastguard Worker     const float *getTexCoordPtr(void) const
278*35238bceSAndroid Build Coastguard Worker     {
279*35238bceSAndroid Build Coastguard Worker         DE_STATIC_ASSERT(sizeof(TexCoordVec) == TEX_COORD_DIMS * (int)sizeof(float));
280*35238bceSAndroid Build Coastguard Worker         return (float *)&m_texCoords[0];
281*35238bceSAndroid Build Coastguard Worker     }
getIndexPtr(void) const282*35238bceSAndroid Build Coastguard Worker     const uint16_t *getIndexPtr(void) const
283*35238bceSAndroid Build Coastguard Worker     {
284*35238bceSAndroid Build Coastguard Worker         return &m_indices[0];
285*35238bceSAndroid Build Coastguard Worker     }
286*35238bceSAndroid Build Coastguard Worker 
287*35238bceSAndroid Build Coastguard Worker private:
288*35238bceSAndroid Build Coastguard Worker     void initializeTexCoords(const TexSizeIVec &textureSize, const TexCoordParams &texCoordParams,
289*35238bceSAndroid Build Coastguard Worker                              bool useSafeTexCoords);
290*35238bceSAndroid Build Coastguard Worker 
291*35238bceSAndroid Build Coastguard Worker     const int m_gridSize;
292*35238bceSAndroid Build Coastguard Worker     vector<Vec2> m_positions;
293*35238bceSAndroid Build Coastguard Worker     vector<TexCoordVec> m_texCoords;
294*35238bceSAndroid Build Coastguard Worker     vector<uint16_t> m_indices;
295*35238bceSAndroid Build Coastguard Worker };
296*35238bceSAndroid Build Coastguard Worker 
297*35238bceSAndroid Build Coastguard Worker template <TextureType TexType>
getQuadLDRU(int col,int row) const298*35238bceSAndroid Build Coastguard Worker Vec4 PosTexCoordQuadGrid<TexType>::getQuadLDRU(int col, int row) const
299*35238bceSAndroid Build Coastguard Worker {
300*35238bceSAndroid Build Coastguard Worker     int ndx00 = (row * m_gridSize + col) * 4;
301*35238bceSAndroid Build Coastguard Worker     int ndx11 = ndx00 + 3;
302*35238bceSAndroid Build Coastguard Worker 
303*35238bceSAndroid Build Coastguard Worker     return Vec4(m_positions[ndx00].x(), m_positions[ndx00].y(), m_positions[ndx11].x(), m_positions[ndx11].y());
304*35238bceSAndroid Build Coastguard Worker }
305*35238bceSAndroid Build Coastguard Worker 
306*35238bceSAndroid Build Coastguard Worker template <TextureType TexType>
getQuadTexCoord(int col,int row) const307*35238bceSAndroid Build Coastguard Worker const typename TexTypeCoordVec<TexType>::t &PosTexCoordQuadGrid<TexType>::getQuadTexCoord(int col, int row) const
308*35238bceSAndroid Build Coastguard Worker {
309*35238bceSAndroid Build Coastguard Worker     return m_texCoords[(row * m_gridSize + col) * 4];
310*35238bceSAndroid Build Coastguard Worker }
311*35238bceSAndroid Build Coastguard Worker 
312*35238bceSAndroid Build Coastguard Worker template <TextureType TexType>
PosTexCoordQuadGrid(int gridSize,const IVec2 & renderSize,const TexSizeIVec & textureSize,const TexCoordParams & texCoordParams,bool useSafeTexCoords)313*35238bceSAndroid Build Coastguard Worker PosTexCoordQuadGrid<TexType>::PosTexCoordQuadGrid(int gridSize, const IVec2 &renderSize, const TexSizeIVec &textureSize,
314*35238bceSAndroid Build Coastguard Worker                                                   const TexCoordParams &texCoordParams, bool useSafeTexCoords)
315*35238bceSAndroid Build Coastguard Worker     : m_gridSize(gridSize)
316*35238bceSAndroid Build Coastguard Worker {
317*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_gridSize > 0 && m_gridSize * m_gridSize <= (int)std::numeric_limits<uint16_t>::max() + 1);
318*35238bceSAndroid Build Coastguard Worker 
319*35238bceSAndroid Build Coastguard Worker     const float gridSizeFloat = (float)m_gridSize;
320*35238bceSAndroid Build Coastguard Worker 
321*35238bceSAndroid Build Coastguard Worker     m_positions.reserve(m_gridSize * m_gridSize * 4);
322*35238bceSAndroid Build Coastguard Worker     m_indices.reserve(m_gridSize * m_gridSize * 3 * 2);
323*35238bceSAndroid Build Coastguard Worker 
324*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < m_gridSize; y++)
325*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < m_gridSize; x++)
326*35238bceSAndroid Build Coastguard Worker         {
327*35238bceSAndroid Build Coastguard Worker             float fx0 = (float)(x + 0) / gridSizeFloat;
328*35238bceSAndroid Build Coastguard Worker             float fx1 = (float)(x + 1) / gridSizeFloat;
329*35238bceSAndroid Build Coastguard Worker             float fy0 = (float)(y + 0) / gridSizeFloat;
330*35238bceSAndroid Build Coastguard Worker             float fy1 = (float)(y + 1) / gridSizeFloat;
331*35238bceSAndroid Build Coastguard Worker 
332*35238bceSAndroid Build Coastguard Worker             Vec2 quadVertices[4] = {Vec2(fx0, fy0), Vec2(fx1, fy0), Vec2(fx0, fy1), Vec2(fx1, fy1)};
333*35238bceSAndroid Build Coastguard Worker 
334*35238bceSAndroid Build Coastguard Worker             int firstNdx = (int)m_positions.size();
335*35238bceSAndroid Build Coastguard Worker 
336*35238bceSAndroid Build Coastguard Worker             for (int i = 0; i < DE_LENGTH_OF_ARRAY(quadVertices); i++)
337*35238bceSAndroid Build Coastguard Worker                 m_positions.push_back(safeCoords(quadVertices[i], renderSize, Vec2(0.0f)) * 2.0f - 1.0f);
338*35238bceSAndroid Build Coastguard Worker 
339*35238bceSAndroid Build Coastguard Worker             m_indices.push_back(uint16_t(firstNdx + 0));
340*35238bceSAndroid Build Coastguard Worker             m_indices.push_back(uint16_t(firstNdx + 1));
341*35238bceSAndroid Build Coastguard Worker             m_indices.push_back(uint16_t(firstNdx + 2));
342*35238bceSAndroid Build Coastguard Worker 
343*35238bceSAndroid Build Coastguard Worker             m_indices.push_back(uint16_t(firstNdx + 1));
344*35238bceSAndroid Build Coastguard Worker             m_indices.push_back(uint16_t(firstNdx + 3));
345*35238bceSAndroid Build Coastguard Worker             m_indices.push_back(uint16_t(firstNdx + 2));
346*35238bceSAndroid Build Coastguard Worker         }
347*35238bceSAndroid Build Coastguard Worker 
348*35238bceSAndroid Build Coastguard Worker     m_texCoords.reserve(m_gridSize * m_gridSize * 4);
349*35238bceSAndroid Build Coastguard Worker     initializeTexCoords(textureSize, texCoordParams, useSafeTexCoords);
350*35238bceSAndroid Build Coastguard Worker 
351*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((int)m_positions.size() == m_gridSize * m_gridSize * 4);
352*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((int)m_indices.size() == m_gridSize * m_gridSize * 3 * 2);
353*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((int)m_texCoords.size() == m_gridSize * m_gridSize * 4);
354*35238bceSAndroid Build Coastguard Worker }
355*35238bceSAndroid Build Coastguard Worker 
356*35238bceSAndroid Build Coastguard Worker template <>
initializeTexCoords(const IVec2 & textureSize,const TexCoordParams & texCoordParams,bool useSafeTexCoords)357*35238bceSAndroid Build Coastguard Worker void PosTexCoordQuadGrid<TEXTURETYPE_2D>::initializeTexCoords(const IVec2 &textureSize,
358*35238bceSAndroid Build Coastguard Worker                                                               const TexCoordParams &texCoordParams,
359*35238bceSAndroid Build Coastguard Worker                                                               bool useSafeTexCoords)
360*35238bceSAndroid Build Coastguard Worker {
361*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_texCoords.empty());
362*35238bceSAndroid Build Coastguard Worker 
363*35238bceSAndroid Build Coastguard Worker     const float gridSizeFloat = (float)m_gridSize;
364*35238bceSAndroid Build Coastguard Worker 
365*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < m_gridSize; y++)
366*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < m_gridSize; x++)
367*35238bceSAndroid Build Coastguard Worker         {
368*35238bceSAndroid Build Coastguard Worker             Vec2 rawCoord =
369*35238bceSAndroid Build Coastguard Worker                 Vec2((float)x / gridSizeFloat, (float)y / gridSizeFloat) * texCoordParams.scale + texCoordParams.bias;
370*35238bceSAndroid Build Coastguard Worker 
371*35238bceSAndroid Build Coastguard Worker             for (int i = 0; i < 4; i++)
372*35238bceSAndroid Build Coastguard Worker                 m_texCoords.push_back(useSafeTexCoords ? safe2DTexCoords(rawCoord, textureSize) : rawCoord);
373*35238bceSAndroid Build Coastguard Worker         }
374*35238bceSAndroid Build Coastguard Worker }
375*35238bceSAndroid Build Coastguard Worker 
376*35238bceSAndroid Build Coastguard Worker template <>
initializeTexCoords(const IVec2 & textureSize,const TexCoordParams & texCoordParams,bool useSafeTexCoords)377*35238bceSAndroid Build Coastguard Worker void PosTexCoordQuadGrid<TEXTURETYPE_CUBE>::initializeTexCoords(const IVec2 &textureSize,
378*35238bceSAndroid Build Coastguard Worker                                                                 const TexCoordParams &texCoordParams,
379*35238bceSAndroid Build Coastguard Worker                                                                 bool useSafeTexCoords)
380*35238bceSAndroid Build Coastguard Worker {
381*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_texCoords.empty());
382*35238bceSAndroid Build Coastguard Worker 
383*35238bceSAndroid Build Coastguard Worker     const float gridSizeFloat = (float)m_gridSize;
384*35238bceSAndroid Build Coastguard Worker     vector<float> texBoundaries;
385*35238bceSAndroid Build Coastguard Worker     computeQuadTexCoordCube(texBoundaries, texCoordParams.face);
386*35238bceSAndroid Build Coastguard Worker     const Vec3 coordA  = Vec3(texBoundaries[0], texBoundaries[1], texBoundaries[2]);
387*35238bceSAndroid Build Coastguard Worker     const Vec3 coordB  = Vec3(texBoundaries[3], texBoundaries[4], texBoundaries[5]);
388*35238bceSAndroid Build Coastguard Worker     const Vec3 coordC  = Vec3(texBoundaries[6], texBoundaries[7], texBoundaries[8]);
389*35238bceSAndroid Build Coastguard Worker     const Vec3 coordAB = coordB - coordA;
390*35238bceSAndroid Build Coastguard Worker     const Vec3 coordAC = coordC - coordA;
391*35238bceSAndroid Build Coastguard Worker 
392*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < m_gridSize; y++)
393*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < m_gridSize; x++)
394*35238bceSAndroid Build Coastguard Worker         {
395*35238bceSAndroid Build Coastguard Worker             const Vec2 rawFaceCoord =
396*35238bceSAndroid Build Coastguard Worker                 texCoordParams.scale * Vec2((float)x / gridSizeFloat, (float)y / gridSizeFloat) + texCoordParams.bias;
397*35238bceSAndroid Build Coastguard Worker             const Vec2 safeFaceCoord = useSafeTexCoords ? safe2DTexCoords(rawFaceCoord, textureSize) : rawFaceCoord;
398*35238bceSAndroid Build Coastguard Worker             const Vec3 texCoord      = coordA + coordAC * safeFaceCoord.x() + coordAB * safeFaceCoord.y();
399*35238bceSAndroid Build Coastguard Worker 
400*35238bceSAndroid Build Coastguard Worker             for (int i = 0; i < 4; i++)
401*35238bceSAndroid Build Coastguard Worker                 m_texCoords.push_back(texCoord);
402*35238bceSAndroid Build Coastguard Worker         }
403*35238bceSAndroid Build Coastguard Worker }
404*35238bceSAndroid Build Coastguard Worker 
405*35238bceSAndroid Build Coastguard Worker } // namespace
406*35238bceSAndroid Build Coastguard Worker 
isLevelNearest(uint32_t filter)407*35238bceSAndroid Build Coastguard Worker static inline bool isLevelNearest(uint32_t filter)
408*35238bceSAndroid Build Coastguard Worker {
409*35238bceSAndroid Build Coastguard Worker     return filter == GL_NEAREST || filter == GL_NEAREST_MIPMAP_NEAREST || filter == GL_NEAREST_MIPMAP_LINEAR;
410*35238bceSAndroid Build Coastguard Worker }
411*35238bceSAndroid Build Coastguard Worker 
getTextureSize(const glu::Texture2D & tex)412*35238bceSAndroid Build Coastguard Worker static inline IVec2 getTextureSize(const glu::Texture2D &tex)
413*35238bceSAndroid Build Coastguard Worker {
414*35238bceSAndroid Build Coastguard Worker     const tcu::Texture2D &ref = tex.getRefTexture();
415*35238bceSAndroid Build Coastguard Worker     return IVec2(ref.getWidth(), ref.getHeight());
416*35238bceSAndroid Build Coastguard Worker }
417*35238bceSAndroid Build Coastguard Worker 
getTextureSize(const glu::TextureCube & tex)418*35238bceSAndroid Build Coastguard Worker static inline IVec2 getTextureSize(const glu::TextureCube &tex)
419*35238bceSAndroid Build Coastguard Worker {
420*35238bceSAndroid Build Coastguard Worker     const tcu::TextureCube &ref = tex.getRefTexture();
421*35238bceSAndroid Build Coastguard Worker     return IVec2(ref.getSize(), ref.getSize());
422*35238bceSAndroid Build Coastguard Worker }
423*35238bceSAndroid Build Coastguard Worker 
424*35238bceSAndroid Build Coastguard Worker template <TextureType TexType>
setPixelColors(const vector<Vec4> & quadColors,const Rect & region,const PosTexCoordQuadGrid<TexType> & grid,tcu::Surface & dst)425*35238bceSAndroid Build Coastguard Worker static void setPixelColors(const vector<Vec4> &quadColors, const Rect &region, const PosTexCoordQuadGrid<TexType> &grid,
426*35238bceSAndroid Build Coastguard Worker                            tcu::Surface &dst)
427*35238bceSAndroid Build Coastguard Worker {
428*35238bceSAndroid Build Coastguard Worker     const int gridSize = grid.getSize();
429*35238bceSAndroid Build Coastguard Worker 
430*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < gridSize; y++)
431*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < gridSize; x++)
432*35238bceSAndroid Build Coastguard Worker         {
433*35238bceSAndroid Build Coastguard Worker             const Vec4 color = quadColors[y * gridSize + x];
434*35238bceSAndroid Build Coastguard Worker             const Vec4 ldru  = grid.getQuadLDRU(x, y) * 0.5f + 0.5f; // [-1, 1] -> [0, 1]
435*35238bceSAndroid Build Coastguard Worker             const int ix0    = deCeilFloatToInt32(ldru.x() * (float)region.w - 0.5f);
436*35238bceSAndroid Build Coastguard Worker             const int ix1    = deCeilFloatToInt32(ldru.z() * (float)region.w - 0.5f);
437*35238bceSAndroid Build Coastguard Worker             const int iy0    = deCeilFloatToInt32(ldru.y() * (float)region.h - 0.5f);
438*35238bceSAndroid Build Coastguard Worker             const int iy1    = deCeilFloatToInt32(ldru.w() * (float)region.h - 0.5f);
439*35238bceSAndroid Build Coastguard Worker 
440*35238bceSAndroid Build Coastguard Worker             for (int iy = iy0; iy < iy1; iy++)
441*35238bceSAndroid Build Coastguard Worker                 for (int ix = ix0; ix < ix1; ix++)
442*35238bceSAndroid Build Coastguard Worker                 {
443*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(deInBounds32(ix + region.x, 0, dst.getWidth()));
444*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(deInBounds32(iy + region.y, 0, dst.getHeight()));
445*35238bceSAndroid Build Coastguard Worker 
446*35238bceSAndroid Build Coastguard Worker                     dst.setPixel(ix + region.x, iy + region.y, tcu::RGBA(color));
447*35238bceSAndroid Build Coastguard Worker                 }
448*35238bceSAndroid Build Coastguard Worker         }
449*35238bceSAndroid Build Coastguard Worker }
450*35238bceSAndroid Build Coastguard Worker 
sample(const tcu::Texture2D & tex,const Vec2 & coord,float lod,const tcu::Sampler & sam)451*35238bceSAndroid Build Coastguard Worker static inline Vec4 sample(const tcu::Texture2D &tex, const Vec2 &coord, float lod, const tcu::Sampler &sam)
452*35238bceSAndroid Build Coastguard Worker {
453*35238bceSAndroid Build Coastguard Worker     return tex.sample(sam, coord.x(), coord.y(), lod);
454*35238bceSAndroid Build Coastguard Worker }
sample(const tcu::TextureCube & tex,const Vec3 & coord,float lod,const tcu::Sampler & sam)455*35238bceSAndroid Build Coastguard Worker static inline Vec4 sample(const tcu::TextureCube &tex, const Vec3 &coord, float lod, const tcu::Sampler &sam)
456*35238bceSAndroid Build Coastguard Worker {
457*35238bceSAndroid Build Coastguard Worker     return tex.sample(sam, coord.x(), coord.y(), coord.z(), lod);
458*35238bceSAndroid Build Coastguard Worker }
459*35238bceSAndroid Build Coastguard Worker 
460*35238bceSAndroid Build Coastguard Worker template <TextureType TexType>
computeReference(const typename TexTypeTcuClass<TexType>::t & texture,float lod,const tcu::Sampler & sampler,const PosTexCoordQuadGrid<TexType> & grid,tcu::Surface & dst,const Rect & dstRegion)461*35238bceSAndroid Build Coastguard Worker void computeReference(const typename TexTypeTcuClass<TexType>::t &texture, float lod, const tcu::Sampler &sampler,
462*35238bceSAndroid Build Coastguard Worker                       const PosTexCoordQuadGrid<TexType> &grid, tcu::Surface &dst, const Rect &dstRegion)
463*35238bceSAndroid Build Coastguard Worker {
464*35238bceSAndroid Build Coastguard Worker     const int gridSize = grid.getSize();
465*35238bceSAndroid Build Coastguard Worker     vector<Vec4> quadColors(gridSize * gridSize);
466*35238bceSAndroid Build Coastguard Worker 
467*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < gridSize; y++)
468*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < gridSize; x++)
469*35238bceSAndroid Build Coastguard Worker         {
470*35238bceSAndroid Build Coastguard Worker             const int ndx                                     = y * gridSize + x;
471*35238bceSAndroid Build Coastguard Worker             const typename TexTypeCoordVec<TexType>::t &coord = grid.getQuadTexCoord(x, y);
472*35238bceSAndroid Build Coastguard Worker 
473*35238bceSAndroid Build Coastguard Worker             quadColors[ndx] = sample(texture, coord, lod, sampler);
474*35238bceSAndroid Build Coastguard Worker         }
475*35238bceSAndroid Build Coastguard Worker 
476*35238bceSAndroid Build Coastguard Worker     setPixelColors(quadColors, dstRegion, grid, dst);
477*35238bceSAndroid Build Coastguard Worker }
478*35238bceSAndroid Build Coastguard Worker 
compareImages(const glu::RenderContext & renderCtx,tcu::TestLog & log,const tcu::Surface & ref,const tcu::Surface & res)479*35238bceSAndroid Build Coastguard Worker static bool compareImages(const glu::RenderContext &renderCtx, tcu::TestLog &log, const tcu::Surface &ref,
480*35238bceSAndroid Build Coastguard Worker                           const tcu::Surface &res)
481*35238bceSAndroid Build Coastguard Worker {
482*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(renderCtx.getRenderTarget().getNumSamples() == 0);
483*35238bceSAndroid Build Coastguard Worker 
484*35238bceSAndroid Build Coastguard Worker     const tcu::RGBA threshold =
485*35238bceSAndroid Build Coastguard Worker         renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(15, 15, 15, 15);
486*35238bceSAndroid Build Coastguard Worker     return tcu::pixelThresholdCompare(log, "Result", "Image compare result", ref, res, threshold,
487*35238bceSAndroid Build Coastguard Worker                                       tcu::COMPARE_LOG_RESULT);
488*35238bceSAndroid Build Coastguard Worker }
489*35238bceSAndroid Build Coastguard Worker 
490*35238bceSAndroid Build Coastguard Worker class Vertex2DTextureCase : public TestCase
491*35238bceSAndroid Build Coastguard Worker {
492*35238bceSAndroid Build Coastguard Worker public:
493*35238bceSAndroid Build Coastguard Worker     Vertex2DTextureCase(Context &testCtx, const char *name, const char *desc, uint32_t minFilter, uint32_t magFilter,
494*35238bceSAndroid Build Coastguard Worker                         uint32_t wrapS, uint32_t wrapT);
495*35238bceSAndroid Build Coastguard Worker     ~Vertex2DTextureCase(void);
496*35238bceSAndroid Build Coastguard Worker 
497*35238bceSAndroid Build Coastguard Worker     void init(void);
498*35238bceSAndroid Build Coastguard Worker     void deinit(void);
499*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
500*35238bceSAndroid Build Coastguard Worker 
501*35238bceSAndroid Build Coastguard Worker private:
502*35238bceSAndroid Build Coastguard Worker     typedef PosTexCoordQuadGrid<TEXTURETYPE_2D> Grid;
503*35238bceSAndroid Build Coastguard Worker 
504*35238bceSAndroid Build Coastguard Worker     Vertex2DTextureCase(const Vertex2DTextureCase &other);
505*35238bceSAndroid Build Coastguard Worker     Vertex2DTextureCase &operator=(const Vertex2DTextureCase &other);
506*35238bceSAndroid Build Coastguard Worker 
507*35238bceSAndroid Build Coastguard Worker     float calculateLod(const Vec2 &texScale, const Vec2 &dstSize, int textureNdx) const;
508*35238bceSAndroid Build Coastguard Worker     void setupShaderInputs(int textureNdx, float lod, const Grid &grid) const;
509*35238bceSAndroid Build Coastguard Worker     void renderCell(int textureNdx, float lod, const Grid &grid) const;
510*35238bceSAndroid Build Coastguard Worker     void computeReferenceCell(int textureNdx, float lod, const Grid &grid, tcu::Surface &dst,
511*35238bceSAndroid Build Coastguard Worker                               const Rect &dstRegion) const;
512*35238bceSAndroid Build Coastguard Worker 
513*35238bceSAndroid Build Coastguard Worker     const uint32_t m_minFilter;
514*35238bceSAndroid Build Coastguard Worker     const uint32_t m_magFilter;
515*35238bceSAndroid Build Coastguard Worker     const uint32_t m_wrapS;
516*35238bceSAndroid Build Coastguard Worker     const uint32_t m_wrapT;
517*35238bceSAndroid Build Coastguard Worker 
518*35238bceSAndroid Build Coastguard Worker     const glu::ShaderProgram *m_program;
519*35238bceSAndroid Build Coastguard Worker     glu::Texture2D *m_textures[2]; // 2 textures, a gradient texture and a grid texture.
520*35238bceSAndroid Build Coastguard Worker };
521*35238bceSAndroid Build Coastguard Worker 
Vertex2DTextureCase(Context & testCtx,const char * name,const char * desc,uint32_t minFilter,uint32_t magFilter,uint32_t wrapS,uint32_t wrapT)522*35238bceSAndroid Build Coastguard Worker Vertex2DTextureCase::Vertex2DTextureCase(Context &testCtx, const char *name, const char *desc, uint32_t minFilter,
523*35238bceSAndroid Build Coastguard Worker                                          uint32_t magFilter, uint32_t wrapS, uint32_t wrapT)
524*35238bceSAndroid Build Coastguard Worker     : TestCase(testCtx, tcu::NODETYPE_SELF_VALIDATE, name, desc)
525*35238bceSAndroid Build Coastguard Worker     , m_minFilter(minFilter)
526*35238bceSAndroid Build Coastguard Worker     , m_magFilter(magFilter)
527*35238bceSAndroid Build Coastguard Worker     , m_wrapS(wrapS)
528*35238bceSAndroid Build Coastguard Worker     , m_wrapT(wrapT)
529*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
530*35238bceSAndroid Build Coastguard Worker {
531*35238bceSAndroid Build Coastguard Worker     m_textures[0] = DE_NULL;
532*35238bceSAndroid Build Coastguard Worker     m_textures[1] = DE_NULL;
533*35238bceSAndroid Build Coastguard Worker }
534*35238bceSAndroid Build Coastguard Worker 
~Vertex2DTextureCase(void)535*35238bceSAndroid Build Coastguard Worker Vertex2DTextureCase::~Vertex2DTextureCase(void)
536*35238bceSAndroid Build Coastguard Worker {
537*35238bceSAndroid Build Coastguard Worker     Vertex2DTextureCase::deinit();
538*35238bceSAndroid Build Coastguard Worker }
539*35238bceSAndroid Build Coastguard Worker 
init(void)540*35238bceSAndroid Build Coastguard Worker void Vertex2DTextureCase::init(void)
541*35238bceSAndroid Build Coastguard Worker {
542*35238bceSAndroid Build Coastguard Worker     const char *const vertexShader = "attribute highp vec2 a_position;\n"
543*35238bceSAndroid Build Coastguard Worker                                      "attribute highp vec2 a_texCoord;\n"
544*35238bceSAndroid Build Coastguard Worker                                      "uniform highp sampler2D u_texture;\n"
545*35238bceSAndroid Build Coastguard Worker                                      "uniform highp float u_lod;\n"
546*35238bceSAndroid Build Coastguard Worker                                      "varying mediump vec4 v_color;\n"
547*35238bceSAndroid Build Coastguard Worker                                      "\n"
548*35238bceSAndroid Build Coastguard Worker                                      "void main()\n"
549*35238bceSAndroid Build Coastguard Worker                                      "{\n"
550*35238bceSAndroid Build Coastguard Worker                                      "    gl_Position = vec4(a_position, 0.0, 1.0);\n"
551*35238bceSAndroid Build Coastguard Worker                                      "    v_color = texture2DLod(u_texture, a_texCoord, u_lod);\n"
552*35238bceSAndroid Build Coastguard Worker                                      "}\n";
553*35238bceSAndroid Build Coastguard Worker 
554*35238bceSAndroid Build Coastguard Worker     const char *const fragmentShader = "varying mediump vec4 v_color;\n"
555*35238bceSAndroid Build Coastguard Worker                                        "\n"
556*35238bceSAndroid Build Coastguard Worker                                        "void main()\n"
557*35238bceSAndroid Build Coastguard Worker                                        "{\n"
558*35238bceSAndroid Build Coastguard Worker                                        "    gl_FragColor = v_color;\n"
559*35238bceSAndroid Build Coastguard Worker                                        "}\n";
560*35238bceSAndroid Build Coastguard Worker 
561*35238bceSAndroid Build Coastguard Worker     if (m_context.getRenderTarget().getNumSamples() != 0)
562*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("MSAA config not supported by this test");
563*35238bceSAndroid Build Coastguard Worker 
564*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_program);
565*35238bceSAndroid Build Coastguard Worker     m_program =
566*35238bceSAndroid Build Coastguard Worker         new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShader, fragmentShader));
567*35238bceSAndroid Build Coastguard Worker 
568*35238bceSAndroid Build Coastguard Worker     if (!m_program->isOk())
569*35238bceSAndroid Build Coastguard Worker     {
570*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << *m_program;
571*35238bceSAndroid Build Coastguard Worker 
572*35238bceSAndroid Build Coastguard Worker         GLint maxVertexTextures;
573*35238bceSAndroid Build Coastguard Worker         glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextures);
574*35238bceSAndroid Build Coastguard Worker 
575*35238bceSAndroid Build Coastguard Worker         if (maxVertexTextures < 1)
576*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("Vertex texture image units not supported", "", __FILE__, __LINE__);
577*35238bceSAndroid Build Coastguard Worker         else
578*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Failed to compile shader");
579*35238bceSAndroid Build Coastguard Worker     }
580*35238bceSAndroid Build Coastguard Worker 
581*35238bceSAndroid Build Coastguard Worker     // Make the textures.
582*35238bceSAndroid Build Coastguard Worker     try
583*35238bceSAndroid Build Coastguard Worker     {
584*35238bceSAndroid Build Coastguard Worker         // Compute suitable power-of-two sizes (for mipmaps).
585*35238bceSAndroid Build Coastguard Worker         const int texWidth  = 1 << deLog2Ceil32(MAX_2D_RENDER_WIDTH / 2);
586*35238bceSAndroid Build Coastguard Worker         const int texHeight = 1 << deLog2Ceil32(MAX_2D_RENDER_HEIGHT / 2);
587*35238bceSAndroid Build Coastguard Worker 
588*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < 2; i++)
589*35238bceSAndroid Build Coastguard Worker         {
590*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(!m_textures[i]);
591*35238bceSAndroid Build Coastguard Worker             m_textures[i] =
592*35238bceSAndroid Build Coastguard Worker                 new glu::Texture2D(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, texWidth, texHeight);
593*35238bceSAndroid Build Coastguard Worker         }
594*35238bceSAndroid Build Coastguard Worker 
595*35238bceSAndroid Build Coastguard Worker         const bool mipmaps                   = (deIsPowerOfTwo32(texWidth) && deIsPowerOfTwo32(texHeight));
596*35238bceSAndroid Build Coastguard Worker         const int numLevels                  = mipmaps ? deLog2Floor32(de::max(texWidth, texHeight)) + 1 : 1;
597*35238bceSAndroid Build Coastguard Worker         const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
598*35238bceSAndroid Build Coastguard Worker         const Vec4 cBias                     = fmtInfo.valueMin;
599*35238bceSAndroid Build Coastguard Worker         const Vec4 cScale                    = fmtInfo.valueMax - fmtInfo.valueMin;
600*35238bceSAndroid Build Coastguard Worker 
601*35238bceSAndroid Build Coastguard Worker         // Fill first with gradient texture.
602*35238bceSAndroid Build Coastguard Worker         for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
603*35238bceSAndroid Build Coastguard Worker         {
604*35238bceSAndroid Build Coastguard Worker             const Vec4 gMin = Vec4(-0.5f, -0.5f, -0.5f, 2.0f) * cScale + cBias;
605*35238bceSAndroid Build Coastguard Worker             const Vec4 gMax = Vec4(1.0f, 1.0f, 1.0f, 0.0f) * cScale + cBias;
606*35238bceSAndroid Build Coastguard Worker 
607*35238bceSAndroid Build Coastguard Worker             m_textures[0]->getRefTexture().allocLevel(levelNdx);
608*35238bceSAndroid Build Coastguard Worker             tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevel(levelNdx), gMin, gMax);
609*35238bceSAndroid Build Coastguard Worker         }
610*35238bceSAndroid Build Coastguard Worker 
611*35238bceSAndroid Build Coastguard Worker         // Fill second with grid texture.
612*35238bceSAndroid Build Coastguard Worker         for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
613*35238bceSAndroid Build Coastguard Worker         {
614*35238bceSAndroid Build Coastguard Worker             const uint32_t step   = 0x00ffffff / numLevels;
615*35238bceSAndroid Build Coastguard Worker             const uint32_t rgb    = step * levelNdx;
616*35238bceSAndroid Build Coastguard Worker             const uint32_t colorA = 0xff000000 | rgb;
617*35238bceSAndroid Build Coastguard Worker             const uint32_t colorB = 0xff000000 | ~rgb;
618*35238bceSAndroid Build Coastguard Worker 
619*35238bceSAndroid Build Coastguard Worker             m_textures[1]->getRefTexture().allocLevel(levelNdx);
620*35238bceSAndroid Build Coastguard Worker             tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevel(levelNdx), 4,
621*35238bceSAndroid Build Coastguard Worker                               tcu::RGBA(colorA).toVec() * cScale + cBias, tcu::RGBA(colorB).toVec() * cScale + cBias);
622*35238bceSAndroid Build Coastguard Worker         }
623*35238bceSAndroid Build Coastguard Worker 
624*35238bceSAndroid Build Coastguard Worker         // Upload.
625*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < 2; i++)
626*35238bceSAndroid Build Coastguard Worker             m_textures[i]->upload();
627*35238bceSAndroid Build Coastguard Worker     }
628*35238bceSAndroid Build Coastguard Worker     catch (const std::exception &)
629*35238bceSAndroid Build Coastguard Worker     {
630*35238bceSAndroid Build Coastguard Worker         // Clean up to save memory.
631*35238bceSAndroid Build Coastguard Worker         Vertex2DTextureCase::deinit();
632*35238bceSAndroid Build Coastguard Worker         throw;
633*35238bceSAndroid Build Coastguard Worker     }
634*35238bceSAndroid Build Coastguard Worker }
635*35238bceSAndroid Build Coastguard Worker 
deinit(void)636*35238bceSAndroid Build Coastguard Worker void Vertex2DTextureCase::deinit(void)
637*35238bceSAndroid Build Coastguard Worker {
638*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < 2; i++)
639*35238bceSAndroid Build Coastguard Worker     {
640*35238bceSAndroid Build Coastguard Worker         delete m_textures[i];
641*35238bceSAndroid Build Coastguard Worker         m_textures[i] = DE_NULL;
642*35238bceSAndroid Build Coastguard Worker     }
643*35238bceSAndroid Build Coastguard Worker 
644*35238bceSAndroid Build Coastguard Worker     delete m_program;
645*35238bceSAndroid Build Coastguard Worker     m_program = DE_NULL;
646*35238bceSAndroid Build Coastguard Worker }
647*35238bceSAndroid Build Coastguard Worker 
calculateLod(const Vec2 & texScale,const Vec2 & dstSize,int textureNdx) const648*35238bceSAndroid Build Coastguard Worker float Vertex2DTextureCase::calculateLod(const Vec2 &texScale, const Vec2 &dstSize, int textureNdx) const
649*35238bceSAndroid Build Coastguard Worker {
650*35238bceSAndroid Build Coastguard Worker     const tcu::Texture2D &refTexture = m_textures[textureNdx]->getRefTexture();
651*35238bceSAndroid Build Coastguard Worker     const Vec2 srcSize               = Vec2((float)refTexture.getWidth(), (float)refTexture.getHeight());
652*35238bceSAndroid Build Coastguard Worker     const Vec2 sizeRatio             = texScale * srcSize / dstSize;
653*35238bceSAndroid Build Coastguard Worker 
654*35238bceSAndroid Build Coastguard Worker     // \note In this particular case dv/dx and du/dy are zero, simplifying the expression.
655*35238bceSAndroid Build Coastguard Worker     return deFloatLog2(de::max(sizeRatio.x(), sizeRatio.y()));
656*35238bceSAndroid Build Coastguard Worker }
657*35238bceSAndroid Build Coastguard Worker 
iterate(void)658*35238bceSAndroid Build Coastguard Worker Vertex2DTextureCase::IterateResult Vertex2DTextureCase::iterate(void)
659*35238bceSAndroid Build Coastguard Worker {
660*35238bceSAndroid Build Coastguard Worker     const int viewportWidth  = deMin32(m_context.getRenderTarget().getWidth(), MAX_2D_RENDER_WIDTH);
661*35238bceSAndroid Build Coastguard Worker     const int viewportHeight = deMin32(m_context.getRenderTarget().getHeight(), MAX_2D_RENDER_HEIGHT);
662*35238bceSAndroid Build Coastguard Worker 
663*35238bceSAndroid Build Coastguard Worker     const int viewportXOffsetMax = m_context.getRenderTarget().getWidth() - viewportWidth;
664*35238bceSAndroid Build Coastguard Worker     const int viewportYOffsetMax = m_context.getRenderTarget().getHeight() - viewportHeight;
665*35238bceSAndroid Build Coastguard Worker 
666*35238bceSAndroid Build Coastguard Worker     de::Random rnd(deStringHash(getName()));
667*35238bceSAndroid Build Coastguard Worker 
668*35238bceSAndroid Build Coastguard Worker     const int viewportXOffset = rnd.getInt(0, viewportXOffsetMax);
669*35238bceSAndroid Build Coastguard Worker     const int viewportYOffset = rnd.getInt(0, viewportYOffsetMax);
670*35238bceSAndroid Build Coastguard Worker 
671*35238bceSAndroid Build Coastguard Worker     glUseProgram(m_program->getProgram());
672*35238bceSAndroid Build Coastguard Worker 
673*35238bceSAndroid Build Coastguard Worker     // Divide viewport into 4 cells.
674*35238bceSAndroid Build Coastguard Worker     const int leftWidth    = viewportWidth / 2;
675*35238bceSAndroid Build Coastguard Worker     const int rightWidth   = viewportWidth - leftWidth;
676*35238bceSAndroid Build Coastguard Worker     const int bottomHeight = viewportHeight / 2;
677*35238bceSAndroid Build Coastguard Worker     const int topHeight    = viewportHeight - bottomHeight;
678*35238bceSAndroid Build Coastguard Worker 
679*35238bceSAndroid Build Coastguard Worker     // Clear.
680*35238bceSAndroid Build Coastguard Worker     glClearColor(0.125f, 0.25f, 0.5f, 1.0f);
681*35238bceSAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
682*35238bceSAndroid Build Coastguard Worker 
683*35238bceSAndroid Build Coastguard Worker     // Texture scaling and offsetting vectors.
684*35238bceSAndroid Build Coastguard Worker     const Vec2 texMinScale(+1.8f, +1.8f);
685*35238bceSAndroid Build Coastguard Worker     const Vec2 texMinOffset(-0.3f, -0.2f);
686*35238bceSAndroid Build Coastguard Worker     const Vec2 texMagScale(+0.3f, +0.3f);
687*35238bceSAndroid Build Coastguard Worker     const Vec2 texMagOffset(+0.9f, +0.8f);
688*35238bceSAndroid Build Coastguard Worker 
689*35238bceSAndroid Build Coastguard Worker     // Surface for the reference image.
690*35238bceSAndroid Build Coastguard Worker     tcu::Surface refImage(viewportWidth, viewportHeight);
691*35238bceSAndroid Build Coastguard Worker 
692*35238bceSAndroid Build Coastguard Worker     {
693*35238bceSAndroid Build Coastguard Worker         const struct Render
694*35238bceSAndroid Build Coastguard Worker         {
695*35238bceSAndroid Build Coastguard Worker             const Rect region;
696*35238bceSAndroid Build Coastguard Worker             int textureNdx;
697*35238bceSAndroid Build Coastguard Worker             const Vec2 texCoordScale;
698*35238bceSAndroid Build Coastguard Worker             const Vec2 texCoordOffset;
699*35238bceSAndroid Build Coastguard Worker             Render(const Rect &r, int tN, const Vec2 &tS, const Vec2 &tO)
700*35238bceSAndroid Build Coastguard Worker                 : region(r)
701*35238bceSAndroid Build Coastguard Worker                 , textureNdx(tN)
702*35238bceSAndroid Build Coastguard Worker                 , texCoordScale(tS)
703*35238bceSAndroid Build Coastguard Worker                 , texCoordOffset(tO)
704*35238bceSAndroid Build Coastguard Worker             {
705*35238bceSAndroid Build Coastguard Worker             }
706*35238bceSAndroid Build Coastguard Worker         } renders[] = {Render(Rect(0, 0, leftWidth, bottomHeight), 0, texMinScale, texMinOffset),
707*35238bceSAndroid Build Coastguard Worker                        Render(Rect(leftWidth, 0, rightWidth, bottomHeight), 0, texMagScale, texMagOffset),
708*35238bceSAndroid Build Coastguard Worker                        Render(Rect(0, bottomHeight, leftWidth, topHeight), 1, texMinScale, texMinOffset),
709*35238bceSAndroid Build Coastguard Worker                        Render(Rect(leftWidth, bottomHeight, rightWidth, topHeight), 1, texMagScale, texMagOffset)};
710*35238bceSAndroid Build Coastguard Worker 
711*35238bceSAndroid Build Coastguard Worker         for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renders); renderNdx++)
712*35238bceSAndroid Build Coastguard Worker         {
713*35238bceSAndroid Build Coastguard Worker             const Render &rend = renders[renderNdx];
714*35238bceSAndroid Build Coastguard Worker             const float lod    = calculateLod(rend.texCoordScale, rend.region.size().asFloat(), rend.textureNdx);
715*35238bceSAndroid Build Coastguard Worker             const bool useSafeTexCoords = isLevelNearest(lod > 0.0f ? m_minFilter : m_magFilter);
716*35238bceSAndroid Build Coastguard Worker             const Grid grid(GRID_SIZE_2D, rend.region.size(), getTextureSize(*m_textures[rend.textureNdx]),
717*35238bceSAndroid Build Coastguard Worker                             TexTypeCoordParams<TEXTURETYPE_2D>(rend.texCoordScale, rend.texCoordOffset),
718*35238bceSAndroid Build Coastguard Worker                             useSafeTexCoords);
719*35238bceSAndroid Build Coastguard Worker 
720*35238bceSAndroid Build Coastguard Worker             glViewport(viewportXOffset + rend.region.x, viewportYOffset + rend.region.y, rend.region.w, rend.region.h);
721*35238bceSAndroid Build Coastguard Worker             renderCell(rend.textureNdx, lod, grid);
722*35238bceSAndroid Build Coastguard Worker             computeReferenceCell(rend.textureNdx, lod, grid, refImage, rend.region);
723*35238bceSAndroid Build Coastguard Worker         }
724*35238bceSAndroid Build Coastguard Worker     }
725*35238bceSAndroid Build Coastguard Worker 
726*35238bceSAndroid Build Coastguard Worker     // Read back rendered results.
727*35238bceSAndroid Build Coastguard Worker     tcu::Surface resImage(viewportWidth, viewportHeight);
728*35238bceSAndroid Build Coastguard Worker     glu::readPixels(m_context.getRenderContext(), viewportXOffset, viewportYOffset, resImage.getAccess());
729*35238bceSAndroid Build Coastguard Worker 
730*35238bceSAndroid Build Coastguard Worker     glUseProgram(0);
731*35238bceSAndroid Build Coastguard Worker 
732*35238bceSAndroid Build Coastguard Worker     // Compare and log.
733*35238bceSAndroid Build Coastguard Worker     {
734*35238bceSAndroid Build Coastguard Worker         const bool isOk = compareImages(m_context.getRenderContext(), m_testCtx.getLog(), refImage, resImage);
735*35238bceSAndroid Build Coastguard Worker 
736*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
737*35238bceSAndroid Build Coastguard Worker                                 isOk ? "Pass" : "Image comparison failed");
738*35238bceSAndroid Build Coastguard Worker     }
739*35238bceSAndroid Build Coastguard Worker 
740*35238bceSAndroid Build Coastguard Worker     return STOP;
741*35238bceSAndroid Build Coastguard Worker }
742*35238bceSAndroid Build Coastguard Worker 
setupShaderInputs(int textureNdx,float lod,const Grid & grid) const743*35238bceSAndroid Build Coastguard Worker void Vertex2DTextureCase::setupShaderInputs(int textureNdx, float lod, const Grid &grid) const
744*35238bceSAndroid Build Coastguard Worker {
745*35238bceSAndroid Build Coastguard Worker     const uint32_t programID = m_program->getProgram();
746*35238bceSAndroid Build Coastguard Worker 
747*35238bceSAndroid Build Coastguard Worker     // SETUP ATTRIBUTES.
748*35238bceSAndroid Build Coastguard Worker 
749*35238bceSAndroid Build Coastguard Worker     {
750*35238bceSAndroid Build Coastguard Worker         const int positionLoc = glGetAttribLocation(programID, "a_position");
751*35238bceSAndroid Build Coastguard Worker         if (positionLoc != -1)
752*35238bceSAndroid Build Coastguard Worker         {
753*35238bceSAndroid Build Coastguard Worker             glEnableVertexAttribArray(positionLoc);
754*35238bceSAndroid Build Coastguard Worker             glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getPositionPtr());
755*35238bceSAndroid Build Coastguard Worker         }
756*35238bceSAndroid Build Coastguard Worker     }
757*35238bceSAndroid Build Coastguard Worker 
758*35238bceSAndroid Build Coastguard Worker     {
759*35238bceSAndroid Build Coastguard Worker         const int texCoordLoc = glGetAttribLocation(programID, "a_texCoord");
760*35238bceSAndroid Build Coastguard Worker         if (texCoordLoc != -1)
761*35238bceSAndroid Build Coastguard Worker         {
762*35238bceSAndroid Build Coastguard Worker             glEnableVertexAttribArray(texCoordLoc);
763*35238bceSAndroid Build Coastguard Worker             glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getTexCoordPtr());
764*35238bceSAndroid Build Coastguard Worker         }
765*35238bceSAndroid Build Coastguard Worker     }
766*35238bceSAndroid Build Coastguard Worker 
767*35238bceSAndroid Build Coastguard Worker     // SETUP UNIFORMS.
768*35238bceSAndroid Build Coastguard Worker 
769*35238bceSAndroid Build Coastguard Worker     {
770*35238bceSAndroid Build Coastguard Worker         const int lodLoc = glGetUniformLocation(programID, "u_lod");
771*35238bceSAndroid Build Coastguard Worker         if (lodLoc != -1)
772*35238bceSAndroid Build Coastguard Worker             glUniform1f(lodLoc, lod);
773*35238bceSAndroid Build Coastguard Worker     }
774*35238bceSAndroid Build Coastguard Worker 
775*35238bceSAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
776*35238bceSAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, m_textures[textureNdx]->getGLTexture());
777*35238bceSAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, m_wrapS);
778*35238bceSAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, m_wrapT);
779*35238bceSAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, m_minFilter);
780*35238bceSAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, m_magFilter);
781*35238bceSAndroid Build Coastguard Worker 
782*35238bceSAndroid Build Coastguard Worker     {
783*35238bceSAndroid Build Coastguard Worker         const int texLoc = glGetUniformLocation(programID, "u_texture");
784*35238bceSAndroid Build Coastguard Worker         if (texLoc != -1)
785*35238bceSAndroid Build Coastguard Worker             glUniform1i(texLoc, 0);
786*35238bceSAndroid Build Coastguard Worker     }
787*35238bceSAndroid Build Coastguard Worker }
788*35238bceSAndroid Build Coastguard Worker 
789*35238bceSAndroid Build Coastguard Worker // Renders one sub-image with given parameters.
renderCell(int textureNdx,float lod,const Grid & grid) const790*35238bceSAndroid Build Coastguard Worker void Vertex2DTextureCase::renderCell(int textureNdx, float lod, const Grid &grid) const
791*35238bceSAndroid Build Coastguard Worker {
792*35238bceSAndroid Build Coastguard Worker     setupShaderInputs(textureNdx, lod, grid);
793*35238bceSAndroid Build Coastguard Worker     glDrawElements(GL_TRIANGLES, grid.getNumIndices(), GL_UNSIGNED_SHORT, grid.getIndexPtr());
794*35238bceSAndroid Build Coastguard Worker }
795*35238bceSAndroid Build Coastguard Worker 
computeReferenceCell(int textureNdx,float lod,const Grid & grid,tcu::Surface & dst,const Rect & dstRegion) const796*35238bceSAndroid Build Coastguard Worker void Vertex2DTextureCase::computeReferenceCell(int textureNdx, float lod, const Grid &grid, tcu::Surface &dst,
797*35238bceSAndroid Build Coastguard Worker                                                const Rect &dstRegion) const
798*35238bceSAndroid Build Coastguard Worker {
799*35238bceSAndroid Build Coastguard Worker     computeReference(m_textures[textureNdx]->getRefTexture(), lod,
800*35238bceSAndroid Build Coastguard Worker                      glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter), grid, dst, dstRegion);
801*35238bceSAndroid Build Coastguard Worker }
802*35238bceSAndroid Build Coastguard Worker 
803*35238bceSAndroid Build Coastguard Worker class VertexCubeTextureCase : public TestCase
804*35238bceSAndroid Build Coastguard Worker {
805*35238bceSAndroid Build Coastguard Worker public:
806*35238bceSAndroid Build Coastguard Worker     VertexCubeTextureCase(Context &testCtx, const char *name, const char *desc, uint32_t minFilter, uint32_t magFilter,
807*35238bceSAndroid Build Coastguard Worker                           uint32_t wrapS, uint32_t wrapT);
808*35238bceSAndroid Build Coastguard Worker     ~VertexCubeTextureCase(void);
809*35238bceSAndroid Build Coastguard Worker 
810*35238bceSAndroid Build Coastguard Worker     void init(void);
811*35238bceSAndroid Build Coastguard Worker     void deinit(void);
812*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
813*35238bceSAndroid Build Coastguard Worker 
814*35238bceSAndroid Build Coastguard Worker private:
815*35238bceSAndroid Build Coastguard Worker     typedef PosTexCoordQuadGrid<TEXTURETYPE_CUBE> Grid;
816*35238bceSAndroid Build Coastguard Worker 
817*35238bceSAndroid Build Coastguard Worker     VertexCubeTextureCase(const VertexCubeTextureCase &other);
818*35238bceSAndroid Build Coastguard Worker     VertexCubeTextureCase &operator=(const VertexCubeTextureCase &other);
819*35238bceSAndroid Build Coastguard Worker 
820*35238bceSAndroid Build Coastguard Worker     float calculateLod(const Vec2 &texScale, const Vec2 &dstSize, int textureNdx) const;
821*35238bceSAndroid Build Coastguard Worker     void setupShaderInputs(int textureNdx, float lod, const Grid &grid) const;
822*35238bceSAndroid Build Coastguard Worker     void renderCell(int textureNdx, float lod, const Grid &grid) const;
823*35238bceSAndroid Build Coastguard Worker     void computeReferenceCell(int textureNdx, float lod, const Grid &grid, tcu::Surface &dst,
824*35238bceSAndroid Build Coastguard Worker                               const Rect &dstRegion) const;
825*35238bceSAndroid Build Coastguard Worker 
826*35238bceSAndroid Build Coastguard Worker     const uint32_t m_minFilter;
827*35238bceSAndroid Build Coastguard Worker     const uint32_t m_magFilter;
828*35238bceSAndroid Build Coastguard Worker     const uint32_t m_wrapS;
829*35238bceSAndroid Build Coastguard Worker     const uint32_t m_wrapT;
830*35238bceSAndroid Build Coastguard Worker 
831*35238bceSAndroid Build Coastguard Worker     const glu::ShaderProgram *m_program;
832*35238bceSAndroid Build Coastguard Worker     glu::TextureCube *m_textures[2]; // 2 textures, a gradient texture and a grid texture.
833*35238bceSAndroid Build Coastguard Worker 
834*35238bceSAndroid Build Coastguard Worker     bool m_isES3Capable;
835*35238bceSAndroid Build Coastguard Worker };
836*35238bceSAndroid Build Coastguard Worker 
VertexCubeTextureCase(Context & testCtx,const char * name,const char * desc,uint32_t minFilter,uint32_t magFilter,uint32_t wrapS,uint32_t wrapT)837*35238bceSAndroid Build Coastguard Worker VertexCubeTextureCase::VertexCubeTextureCase(Context &testCtx, const char *name, const char *desc, uint32_t minFilter,
838*35238bceSAndroid Build Coastguard Worker                                              uint32_t magFilter, uint32_t wrapS, uint32_t wrapT)
839*35238bceSAndroid Build Coastguard Worker     : TestCase(testCtx, tcu::NODETYPE_SELF_VALIDATE, name, desc)
840*35238bceSAndroid Build Coastguard Worker     , m_minFilter(minFilter)
841*35238bceSAndroid Build Coastguard Worker     , m_magFilter(magFilter)
842*35238bceSAndroid Build Coastguard Worker     , m_wrapS(wrapS)
843*35238bceSAndroid Build Coastguard Worker     , m_wrapT(wrapT)
844*35238bceSAndroid Build Coastguard Worker     , m_program(DE_NULL)
845*35238bceSAndroid Build Coastguard Worker     , m_isES3Capable(false)
846*35238bceSAndroid Build Coastguard Worker {
847*35238bceSAndroid Build Coastguard Worker     m_textures[0] = DE_NULL;
848*35238bceSAndroid Build Coastguard Worker     m_textures[1] = DE_NULL;
849*35238bceSAndroid Build Coastguard Worker }
850*35238bceSAndroid Build Coastguard Worker 
~VertexCubeTextureCase(void)851*35238bceSAndroid Build Coastguard Worker VertexCubeTextureCase::~VertexCubeTextureCase(void)
852*35238bceSAndroid Build Coastguard Worker {
853*35238bceSAndroid Build Coastguard Worker     VertexCubeTextureCase::deinit();
854*35238bceSAndroid Build Coastguard Worker }
855*35238bceSAndroid Build Coastguard Worker 
init(void)856*35238bceSAndroid Build Coastguard Worker void VertexCubeTextureCase::init(void)
857*35238bceSAndroid Build Coastguard Worker {
858*35238bceSAndroid Build Coastguard Worker     const char *const vertexShader = "attribute highp vec2 a_position;\n"
859*35238bceSAndroid Build Coastguard Worker                                      "attribute highp vec3 a_texCoord;\n"
860*35238bceSAndroid Build Coastguard Worker                                      "uniform highp samplerCube u_texture;\n"
861*35238bceSAndroid Build Coastguard Worker                                      "uniform highp float u_lod;\n"
862*35238bceSAndroid Build Coastguard Worker                                      "varying mediump vec4 v_color;\n"
863*35238bceSAndroid Build Coastguard Worker                                      "\n"
864*35238bceSAndroid Build Coastguard Worker                                      "void main()\n"
865*35238bceSAndroid Build Coastguard Worker                                      "{\n"
866*35238bceSAndroid Build Coastguard Worker                                      "    gl_Position = vec4(a_position, 0.0, 1.0);\n"
867*35238bceSAndroid Build Coastguard Worker                                      "    v_color = textureCubeLod(u_texture, a_texCoord, u_lod);\n"
868*35238bceSAndroid Build Coastguard Worker                                      "}\n";
869*35238bceSAndroid Build Coastguard Worker 
870*35238bceSAndroid Build Coastguard Worker     const char *const fragmentShader = "varying mediump vec4 v_color;\n"
871*35238bceSAndroid Build Coastguard Worker                                        "\n"
872*35238bceSAndroid Build Coastguard Worker                                        "void main()\n"
873*35238bceSAndroid Build Coastguard Worker                                        "{\n"
874*35238bceSAndroid Build Coastguard Worker                                        "    gl_FragColor = v_color;\n"
875*35238bceSAndroid Build Coastguard Worker                                        "}\n";
876*35238bceSAndroid Build Coastguard Worker 
877*35238bceSAndroid Build Coastguard Worker     m_isES3Capable = glu::IsES3Compatible(m_context.getRenderContext().getFunctions());
878*35238bceSAndroid Build Coastguard Worker 
879*35238bceSAndroid Build Coastguard Worker     if (m_context.getRenderTarget().getNumSamples() != 0)
880*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("MSAA config not supported by this test");
881*35238bceSAndroid Build Coastguard Worker 
882*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_program);
883*35238bceSAndroid Build Coastguard Worker     m_program =
884*35238bceSAndroid Build Coastguard Worker         new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShader, fragmentShader));
885*35238bceSAndroid Build Coastguard Worker 
886*35238bceSAndroid Build Coastguard Worker     if (!m_program->isOk())
887*35238bceSAndroid Build Coastguard Worker     {
888*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << *m_program;
889*35238bceSAndroid Build Coastguard Worker 
890*35238bceSAndroid Build Coastguard Worker         GLint maxVertexTextures;
891*35238bceSAndroid Build Coastguard Worker         glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextures);
892*35238bceSAndroid Build Coastguard Worker 
893*35238bceSAndroid Build Coastguard Worker         if (maxVertexTextures < 1)
894*35238bceSAndroid Build Coastguard Worker             throw tcu::NotSupportedError("Vertex texture image units not supported", "", __FILE__, __LINE__);
895*35238bceSAndroid Build Coastguard Worker         else
896*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Failed to compile shader");
897*35238bceSAndroid Build Coastguard Worker     }
898*35238bceSAndroid Build Coastguard Worker 
899*35238bceSAndroid Build Coastguard Worker     // Make the textures.
900*35238bceSAndroid Build Coastguard Worker     try
901*35238bceSAndroid Build Coastguard Worker     {
902*35238bceSAndroid Build Coastguard Worker         // Compute suitable power-of-two sizes (for mipmaps).
903*35238bceSAndroid Build Coastguard Worker         const int texWidth  = 1 << deLog2Ceil32(MAX_CUBE_RENDER_WIDTH / 3 / 2);
904*35238bceSAndroid Build Coastguard Worker         const int texHeight = 1 << deLog2Ceil32(MAX_CUBE_RENDER_HEIGHT / 2 / 2);
905*35238bceSAndroid Build Coastguard Worker 
906*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(texWidth == texHeight);
907*35238bceSAndroid Build Coastguard Worker         DE_UNREF(texHeight);
908*35238bceSAndroid Build Coastguard Worker 
909*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < 2; i++)
910*35238bceSAndroid Build Coastguard Worker         {
911*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(!m_textures[i]);
912*35238bceSAndroid Build Coastguard Worker             m_textures[i] = new glu::TextureCube(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, texWidth);
913*35238bceSAndroid Build Coastguard Worker         }
914*35238bceSAndroid Build Coastguard Worker 
915*35238bceSAndroid Build Coastguard Worker         const bool mipmaps                   = deIsPowerOfTwo32(texWidth) != false;
916*35238bceSAndroid Build Coastguard Worker         const int numLevels                  = mipmaps ? deLog2Floor32(texWidth) + 1 : 1;
917*35238bceSAndroid Build Coastguard Worker         const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
918*35238bceSAndroid Build Coastguard Worker         const Vec4 cBias                     = fmtInfo.valueMin;
919*35238bceSAndroid Build Coastguard Worker         const Vec4 cScale                    = fmtInfo.valueMax - fmtInfo.valueMin;
920*35238bceSAndroid Build Coastguard Worker 
921*35238bceSAndroid Build Coastguard Worker         // Fill first with gradient texture.
922*35238bceSAndroid Build Coastguard Worker         static const Vec4 gradients[tcu::CUBEFACE_LAST][2] = {
923*35238bceSAndroid Build Coastguard Worker             {Vec4(-1.0f, -1.0f, -1.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f)}, // negative x
924*35238bceSAndroid Build Coastguard Worker             {Vec4(0.0f, -1.0f, -1.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f)},  // positive x
925*35238bceSAndroid Build Coastguard Worker             {Vec4(-1.0f, 0.0f, -1.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f)},  // negative y
926*35238bceSAndroid Build Coastguard Worker             {Vec4(-1.0f, -1.0f, 0.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f)},  // positive y
927*35238bceSAndroid Build Coastguard Worker             {Vec4(-1.0f, -1.0f, -1.0f, 0.0f), Vec4(1.0f, 1.0f, 1.0f, 1.0f)}, // negative z
928*35238bceSAndroid Build Coastguard Worker             {Vec4(0.0f, 0.0f, 0.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f)}     // positive z
929*35238bceSAndroid Build Coastguard Worker         };
930*35238bceSAndroid Build Coastguard Worker         for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
931*35238bceSAndroid Build Coastguard Worker         {
932*35238bceSAndroid Build Coastguard Worker             for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
933*35238bceSAndroid Build Coastguard Worker             {
934*35238bceSAndroid Build Coastguard Worker                 m_textures[0]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
935*35238bceSAndroid Build Coastguard Worker                 tcu::fillWithComponentGradients(
936*35238bceSAndroid Build Coastguard Worker                     m_textures[0]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face),
937*35238bceSAndroid Build Coastguard Worker                     gradients[face][0] * cScale + cBias, gradients[face][1] * cScale + cBias);
938*35238bceSAndroid Build Coastguard Worker             }
939*35238bceSAndroid Build Coastguard Worker         }
940*35238bceSAndroid Build Coastguard Worker 
941*35238bceSAndroid Build Coastguard Worker         // Fill second with grid texture.
942*35238bceSAndroid Build Coastguard Worker         for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
943*35238bceSAndroid Build Coastguard Worker         {
944*35238bceSAndroid Build Coastguard Worker             for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
945*35238bceSAndroid Build Coastguard Worker             {
946*35238bceSAndroid Build Coastguard Worker                 const uint32_t step   = 0x00ffffff / (numLevels * tcu::CUBEFACE_LAST);
947*35238bceSAndroid Build Coastguard Worker                 const uint32_t rgb    = step * levelNdx * face;
948*35238bceSAndroid Build Coastguard Worker                 const uint32_t colorA = 0xff000000 | rgb;
949*35238bceSAndroid Build Coastguard Worker                 const uint32_t colorB = 0xff000000 | ~rgb;
950*35238bceSAndroid Build Coastguard Worker 
951*35238bceSAndroid Build Coastguard Worker                 m_textures[1]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
952*35238bceSAndroid Build Coastguard Worker                 tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), 4,
953*35238bceSAndroid Build Coastguard Worker                                   tcu::RGBA(colorA).toVec() * cScale + cBias,
954*35238bceSAndroid Build Coastguard Worker                                   tcu::RGBA(colorB).toVec() * cScale + cBias);
955*35238bceSAndroid Build Coastguard Worker             }
956*35238bceSAndroid Build Coastguard Worker         }
957*35238bceSAndroid Build Coastguard Worker 
958*35238bceSAndroid Build Coastguard Worker         // Upload.
959*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < 2; i++)
960*35238bceSAndroid Build Coastguard Worker             m_textures[i]->upload();
961*35238bceSAndroid Build Coastguard Worker     }
962*35238bceSAndroid Build Coastguard Worker     catch (const std::exception &)
963*35238bceSAndroid Build Coastguard Worker     {
964*35238bceSAndroid Build Coastguard Worker         // Clean up to save memory.
965*35238bceSAndroid Build Coastguard Worker         VertexCubeTextureCase::deinit();
966*35238bceSAndroid Build Coastguard Worker         throw;
967*35238bceSAndroid Build Coastguard Worker     }
968*35238bceSAndroid Build Coastguard Worker }
969*35238bceSAndroid Build Coastguard Worker 
deinit(void)970*35238bceSAndroid Build Coastguard Worker void VertexCubeTextureCase::deinit(void)
971*35238bceSAndroid Build Coastguard Worker {
972*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < 2; i++)
973*35238bceSAndroid Build Coastguard Worker     {
974*35238bceSAndroid Build Coastguard Worker         delete m_textures[i];
975*35238bceSAndroid Build Coastguard Worker         m_textures[i] = DE_NULL;
976*35238bceSAndroid Build Coastguard Worker     }
977*35238bceSAndroid Build Coastguard Worker 
978*35238bceSAndroid Build Coastguard Worker     delete m_program;
979*35238bceSAndroid Build Coastguard Worker     m_program = DE_NULL;
980*35238bceSAndroid Build Coastguard Worker }
981*35238bceSAndroid Build Coastguard Worker 
calculateLod(const Vec2 & texScale,const Vec2 & dstSize,int textureNdx) const982*35238bceSAndroid Build Coastguard Worker float VertexCubeTextureCase::calculateLod(const Vec2 &texScale, const Vec2 &dstSize, int textureNdx) const
983*35238bceSAndroid Build Coastguard Worker {
984*35238bceSAndroid Build Coastguard Worker     const tcu::TextureCube &refTexture = m_textures[textureNdx]->getRefTexture();
985*35238bceSAndroid Build Coastguard Worker     const Vec2 srcSize                 = Vec2((float)refTexture.getSize(), (float)refTexture.getSize());
986*35238bceSAndroid Build Coastguard Worker     const Vec2 sizeRatio               = texScale * srcSize / dstSize;
987*35238bceSAndroid Build Coastguard Worker 
988*35238bceSAndroid Build Coastguard Worker     // \note In this particular case, dv/dx and du/dy are zero, simplifying the expression.
989*35238bceSAndroid Build Coastguard Worker     return deFloatLog2(de::max(sizeRatio.x(), sizeRatio.y()));
990*35238bceSAndroid Build Coastguard Worker }
991*35238bceSAndroid Build Coastguard Worker 
iterate(void)992*35238bceSAndroid Build Coastguard Worker VertexCubeTextureCase::IterateResult VertexCubeTextureCase::iterate(void)
993*35238bceSAndroid Build Coastguard Worker {
994*35238bceSAndroid Build Coastguard Worker     const int viewportWidth  = deMin32(m_context.getRenderTarget().getWidth(), MAX_CUBE_RENDER_WIDTH);
995*35238bceSAndroid Build Coastguard Worker     const int viewportHeight = deMin32(m_context.getRenderTarget().getHeight(), MAX_CUBE_RENDER_HEIGHT);
996*35238bceSAndroid Build Coastguard Worker 
997*35238bceSAndroid Build Coastguard Worker     const int viewportXOffsetMax = m_context.getRenderTarget().getWidth() - viewportWidth;
998*35238bceSAndroid Build Coastguard Worker     const int viewportYOffsetMax = m_context.getRenderTarget().getHeight() - viewportHeight;
999*35238bceSAndroid Build Coastguard Worker 
1000*35238bceSAndroid Build Coastguard Worker     de::Random rnd(deStringHash(getName()));
1001*35238bceSAndroid Build Coastguard Worker 
1002*35238bceSAndroid Build Coastguard Worker     const int viewportXOffset = rnd.getInt(0, viewportXOffsetMax);
1003*35238bceSAndroid Build Coastguard Worker     const int viewportYOffset = rnd.getInt(0, viewportYOffsetMax);
1004*35238bceSAndroid Build Coastguard Worker 
1005*35238bceSAndroid Build Coastguard Worker     glUseProgram(m_program->getProgram());
1006*35238bceSAndroid Build Coastguard Worker 
1007*35238bceSAndroid Build Coastguard Worker     // Divide viewport into 4 areas.
1008*35238bceSAndroid Build Coastguard Worker     const int leftWidth    = viewportWidth / 2;
1009*35238bceSAndroid Build Coastguard Worker     const int rightWidth   = viewportWidth - leftWidth;
1010*35238bceSAndroid Build Coastguard Worker     const int bottomHeight = viewportHeight / 2;
1011*35238bceSAndroid Build Coastguard Worker     const int topHeight    = viewportHeight - bottomHeight;
1012*35238bceSAndroid Build Coastguard Worker 
1013*35238bceSAndroid Build Coastguard Worker     // Clear.
1014*35238bceSAndroid Build Coastguard Worker     glClearColor(0.125f, 0.25f, 0.5f, 1.0f);
1015*35238bceSAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
1016*35238bceSAndroid Build Coastguard Worker 
1017*35238bceSAndroid Build Coastguard Worker     // Texture scaling and offsetting vectors.
1018*35238bceSAndroid Build Coastguard Worker     const Vec2 texMinScale(1.0f, 1.0f);
1019*35238bceSAndroid Build Coastguard Worker     const Vec2 texMinOffset(0.0f, 0.0f);
1020*35238bceSAndroid Build Coastguard Worker     const Vec2 texMagScale(0.3f, 0.3f);
1021*35238bceSAndroid Build Coastguard Worker     const Vec2 texMagOffset(0.5f, 0.3f);
1022*35238bceSAndroid Build Coastguard Worker 
1023*35238bceSAndroid Build Coastguard Worker     // Surface for the reference image.
1024*35238bceSAndroid Build Coastguard Worker     tcu::Surface refImage(viewportWidth, viewportHeight);
1025*35238bceSAndroid Build Coastguard Worker 
1026*35238bceSAndroid Build Coastguard Worker     // Each of the four areas is divided into 6 cells.
1027*35238bceSAndroid Build Coastguard Worker     const int defCellWidth  = viewportWidth / 2 / 3;
1028*35238bceSAndroid Build Coastguard Worker     const int defCellHeight = viewportHeight / 2 / 2;
1029*35238bceSAndroid Build Coastguard Worker 
1030*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < tcu::CUBEFACE_LAST; i++)
1031*35238bceSAndroid Build Coastguard Worker     {
1032*35238bceSAndroid Build Coastguard Worker         const int cellOffsetX      = defCellWidth * (i % 3);
1033*35238bceSAndroid Build Coastguard Worker         const int cellOffsetY      = defCellHeight * (i / 3);
1034*35238bceSAndroid Build Coastguard Worker         const bool isRightmostCell = i == 2 || i == 5;
1035*35238bceSAndroid Build Coastguard Worker         const bool isTopCell       = i >= 3;
1036*35238bceSAndroid Build Coastguard Worker         const int leftCellWidth    = isRightmostCell ? leftWidth - cellOffsetX : defCellWidth;
1037*35238bceSAndroid Build Coastguard Worker         const int rightCellWidth   = isRightmostCell ? rightWidth - cellOffsetX : defCellWidth;
1038*35238bceSAndroid Build Coastguard Worker         const int bottomCellHeight = isTopCell ? bottomHeight - cellOffsetY : defCellHeight;
1039*35238bceSAndroid Build Coastguard Worker         const int topCellHeight    = isTopCell ? topHeight - cellOffsetY : defCellHeight;
1040*35238bceSAndroid Build Coastguard Worker 
1041*35238bceSAndroid Build Coastguard Worker         const struct Render
1042*35238bceSAndroid Build Coastguard Worker         {
1043*35238bceSAndroid Build Coastguard Worker             const Rect region;
1044*35238bceSAndroid Build Coastguard Worker             int textureNdx;
1045*35238bceSAndroid Build Coastguard Worker             const Vec2 texCoordScale;
1046*35238bceSAndroid Build Coastguard Worker             const Vec2 texCoordOffset;
1047*35238bceSAndroid Build Coastguard Worker             Render(const Rect &r, int tN, const Vec2 &tS, const Vec2 &tO)
1048*35238bceSAndroid Build Coastguard Worker                 : region(r)
1049*35238bceSAndroid Build Coastguard Worker                 , textureNdx(tN)
1050*35238bceSAndroid Build Coastguard Worker                 , texCoordScale(tS)
1051*35238bceSAndroid Build Coastguard Worker                 , texCoordOffset(tO)
1052*35238bceSAndroid Build Coastguard Worker             {
1053*35238bceSAndroid Build Coastguard Worker             }
1054*35238bceSAndroid Build Coastguard Worker         } renders[] = {Render(Rect(cellOffsetX + 0, cellOffsetY + 0, leftCellWidth, bottomCellHeight), 0, texMinScale,
1055*35238bceSAndroid Build Coastguard Worker                               texMinOffset),
1056*35238bceSAndroid Build Coastguard Worker                        Render(Rect(cellOffsetX + leftWidth, cellOffsetY + 0, rightCellWidth, bottomCellHeight), 0,
1057*35238bceSAndroid Build Coastguard Worker                               texMagScale, texMagOffset),
1058*35238bceSAndroid Build Coastguard Worker                        Render(Rect(cellOffsetX + 0, cellOffsetY + bottomHeight, leftCellWidth, topCellHeight), 1,
1059*35238bceSAndroid Build Coastguard Worker                               texMinScale, texMinOffset),
1060*35238bceSAndroid Build Coastguard Worker                        Render(Rect(cellOffsetX + leftWidth, cellOffsetY + bottomHeight, rightCellWidth, topCellHeight),
1061*35238bceSAndroid Build Coastguard Worker                               1, texMagScale, texMagOffset)};
1062*35238bceSAndroid Build Coastguard Worker 
1063*35238bceSAndroid Build Coastguard Worker         for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renders); renderNdx++)
1064*35238bceSAndroid Build Coastguard Worker         {
1065*35238bceSAndroid Build Coastguard Worker             const Render &rend = renders[renderNdx];
1066*35238bceSAndroid Build Coastguard Worker             const float lod    = calculateLod(rend.texCoordScale, rend.region.size().asFloat(), rend.textureNdx);
1067*35238bceSAndroid Build Coastguard Worker             const bool useSafeTexCoords = isLevelNearest(lod > 0.0f ? m_minFilter : m_magFilter);
1068*35238bceSAndroid Build Coastguard Worker             const Grid grid(
1069*35238bceSAndroid Build Coastguard Worker                 GRID_SIZE_CUBE, rend.region.size(), getTextureSize(*m_textures[rend.textureNdx]),
1070*35238bceSAndroid Build Coastguard Worker                 TexTypeCoordParams<TEXTURETYPE_CUBE>(rend.texCoordScale, rend.texCoordOffset, (tcu::CubeFace)i),
1071*35238bceSAndroid Build Coastguard Worker                 useSafeTexCoords);
1072*35238bceSAndroid Build Coastguard Worker 
1073*35238bceSAndroid Build Coastguard Worker             glViewport(viewportXOffset + rend.region.x, viewportYOffset + rend.region.y, rend.region.w, rend.region.h);
1074*35238bceSAndroid Build Coastguard Worker             renderCell(rend.textureNdx, lod, grid);
1075*35238bceSAndroid Build Coastguard Worker             computeReferenceCell(rend.textureNdx, lod, grid, refImage, rend.region);
1076*35238bceSAndroid Build Coastguard Worker         }
1077*35238bceSAndroid Build Coastguard Worker     }
1078*35238bceSAndroid Build Coastguard Worker 
1079*35238bceSAndroid Build Coastguard Worker     // Read back rendered results.
1080*35238bceSAndroid Build Coastguard Worker     tcu::Surface resImage(viewportWidth, viewportHeight);
1081*35238bceSAndroid Build Coastguard Worker     glu::readPixels(m_context.getRenderContext(), viewportXOffset, viewportYOffset, resImage.getAccess());
1082*35238bceSAndroid Build Coastguard Worker 
1083*35238bceSAndroid Build Coastguard Worker     glUseProgram(0);
1084*35238bceSAndroid Build Coastguard Worker 
1085*35238bceSAndroid Build Coastguard Worker     // Compare and log.
1086*35238bceSAndroid Build Coastguard Worker     {
1087*35238bceSAndroid Build Coastguard Worker         const bool isOk = compareImages(m_context.getRenderContext(), m_testCtx.getLog(), refImage, resImage);
1088*35238bceSAndroid Build Coastguard Worker 
1089*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
1090*35238bceSAndroid Build Coastguard Worker                                 isOk ? "Pass" : "Image comparison failed");
1091*35238bceSAndroid Build Coastguard Worker     }
1092*35238bceSAndroid Build Coastguard Worker 
1093*35238bceSAndroid Build Coastguard Worker     return STOP;
1094*35238bceSAndroid Build Coastguard Worker }
1095*35238bceSAndroid Build Coastguard Worker 
setupShaderInputs(int textureNdx,float lod,const Grid & grid) const1096*35238bceSAndroid Build Coastguard Worker void VertexCubeTextureCase::setupShaderInputs(int textureNdx, float lod, const Grid &grid) const
1097*35238bceSAndroid Build Coastguard Worker {
1098*35238bceSAndroid Build Coastguard Worker     const uint32_t programID = m_program->getProgram();
1099*35238bceSAndroid Build Coastguard Worker 
1100*35238bceSAndroid Build Coastguard Worker     // SETUP ATTRIBUTES.
1101*35238bceSAndroid Build Coastguard Worker 
1102*35238bceSAndroid Build Coastguard Worker     {
1103*35238bceSAndroid Build Coastguard Worker         const int positionLoc = glGetAttribLocation(programID, "a_position");
1104*35238bceSAndroid Build Coastguard Worker         if (positionLoc != -1)
1105*35238bceSAndroid Build Coastguard Worker         {
1106*35238bceSAndroid Build Coastguard Worker             glEnableVertexAttribArray(positionLoc);
1107*35238bceSAndroid Build Coastguard Worker             glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getPositionPtr());
1108*35238bceSAndroid Build Coastguard Worker         }
1109*35238bceSAndroid Build Coastguard Worker     }
1110*35238bceSAndroid Build Coastguard Worker 
1111*35238bceSAndroid Build Coastguard Worker     {
1112*35238bceSAndroid Build Coastguard Worker         const int texCoordLoc = glGetAttribLocation(programID, "a_texCoord");
1113*35238bceSAndroid Build Coastguard Worker         if (texCoordLoc != -1)
1114*35238bceSAndroid Build Coastguard Worker         {
1115*35238bceSAndroid Build Coastguard Worker             glEnableVertexAttribArray(texCoordLoc);
1116*35238bceSAndroid Build Coastguard Worker             glVertexAttribPointer(texCoordLoc, 3, GL_FLOAT, GL_FALSE, 0, grid.getTexCoordPtr());
1117*35238bceSAndroid Build Coastguard Worker         }
1118*35238bceSAndroid Build Coastguard Worker     }
1119*35238bceSAndroid Build Coastguard Worker 
1120*35238bceSAndroid Build Coastguard Worker     // SETUP UNIFORMS.
1121*35238bceSAndroid Build Coastguard Worker 
1122*35238bceSAndroid Build Coastguard Worker     {
1123*35238bceSAndroid Build Coastguard Worker         const int lodLoc = glGetUniformLocation(programID, "u_lod");
1124*35238bceSAndroid Build Coastguard Worker         if (lodLoc != -1)
1125*35238bceSAndroid Build Coastguard Worker             glUniform1f(lodLoc, lod);
1126*35238bceSAndroid Build Coastguard Worker     }
1127*35238bceSAndroid Build Coastguard Worker 
1128*35238bceSAndroid Build Coastguard Worker     glActiveTexture(GL_TEXTURE0);
1129*35238bceSAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_CUBE_MAP, m_textures[textureNdx]->getGLTexture());
1130*35238bceSAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, m_wrapS);
1131*35238bceSAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, m_wrapT);
1132*35238bceSAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, m_minFilter);
1133*35238bceSAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, m_magFilter);
1134*35238bceSAndroid Build Coastguard Worker 
1135*35238bceSAndroid Build Coastguard Worker     {
1136*35238bceSAndroid Build Coastguard Worker         const int texLoc = glGetUniformLocation(programID, "u_texture");
1137*35238bceSAndroid Build Coastguard Worker         if (texLoc != -1)
1138*35238bceSAndroid Build Coastguard Worker             glUniform1i(texLoc, 0);
1139*35238bceSAndroid Build Coastguard Worker     }
1140*35238bceSAndroid Build Coastguard Worker }
1141*35238bceSAndroid Build Coastguard Worker 
1142*35238bceSAndroid Build Coastguard Worker // Renders one cube face with given parameters.
renderCell(int textureNdx,float lod,const Grid & grid) const1143*35238bceSAndroid Build Coastguard Worker void VertexCubeTextureCase::renderCell(int textureNdx, float lod, const Grid &grid) const
1144*35238bceSAndroid Build Coastguard Worker {
1145*35238bceSAndroid Build Coastguard Worker     setupShaderInputs(textureNdx, lod, grid);
1146*35238bceSAndroid Build Coastguard Worker     glDrawElements(GL_TRIANGLES, grid.getNumIndices(), GL_UNSIGNED_SHORT, grid.getIndexPtr());
1147*35238bceSAndroid Build Coastguard Worker }
1148*35238bceSAndroid Build Coastguard Worker 
1149*35238bceSAndroid Build Coastguard Worker // Computes reference for one cube face with given parameters.
computeReferenceCell(int textureNdx,float lod,const Grid & grid,tcu::Surface & dst,const Rect & dstRegion) const1150*35238bceSAndroid Build Coastguard Worker void VertexCubeTextureCase::computeReferenceCell(int textureNdx, float lod, const Grid &grid, tcu::Surface &dst,
1151*35238bceSAndroid Build Coastguard Worker                                                  const Rect &dstRegion) const
1152*35238bceSAndroid Build Coastguard Worker {
1153*35238bceSAndroid Build Coastguard Worker     tcu::Sampler sampler    = glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
1154*35238bceSAndroid Build Coastguard Worker     sampler.seamlessCubeMap = m_isES3Capable;
1155*35238bceSAndroid Build Coastguard Worker     computeReference(m_textures[textureNdx]->getRefTexture(), lod, sampler, grid, dst, dstRegion);
1156*35238bceSAndroid Build Coastguard Worker }
1157*35238bceSAndroid Build Coastguard Worker 
VertexTextureTests(Context & context)1158*35238bceSAndroid Build Coastguard Worker VertexTextureTests::VertexTextureTests(Context &context) : TestCaseGroup(context, "vertex", "Vertex Texture Tests")
1159*35238bceSAndroid Build Coastguard Worker {
1160*35238bceSAndroid Build Coastguard Worker }
1161*35238bceSAndroid Build Coastguard Worker 
~VertexTextureTests(void)1162*35238bceSAndroid Build Coastguard Worker VertexTextureTests::~VertexTextureTests(void)
1163*35238bceSAndroid Build Coastguard Worker {
1164*35238bceSAndroid Build Coastguard Worker }
1165*35238bceSAndroid Build Coastguard Worker 
init(void)1166*35238bceSAndroid Build Coastguard Worker void VertexTextureTests::init(void)
1167*35238bceSAndroid Build Coastguard Worker {
1168*35238bceSAndroid Build Coastguard Worker     // 2D and cube map groups, and their filtering and wrap sub-groups.
1169*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *const group2D   = new TestCaseGroup(m_context, "2d", "2D Vertex Texture Tests");
1170*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *const groupCube = new TestCaseGroup(m_context, "cube", "Cube Map Vertex Texture Tests");
1171*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *const filteringGroup2D =
1172*35238bceSAndroid Build Coastguard Worker         new TestCaseGroup(m_context, "filtering", "2D Vertex Texture Filtering Tests");
1173*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *const wrapGroup2D = new TestCaseGroup(m_context, "wrap", "2D Vertex Texture Wrap Tests");
1174*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *const filteringGroupCube =
1175*35238bceSAndroid Build Coastguard Worker         new TestCaseGroup(m_context, "filtering", "Cube Map Vertex Texture Filtering Tests");
1176*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *const wrapGroupCube = new TestCaseGroup(m_context, "wrap", "Cube Map Vertex Texture Wrap Tests");
1177*35238bceSAndroid Build Coastguard Worker 
1178*35238bceSAndroid Build Coastguard Worker     group2D->addChild(filteringGroup2D);
1179*35238bceSAndroid Build Coastguard Worker     group2D->addChild(wrapGroup2D);
1180*35238bceSAndroid Build Coastguard Worker     groupCube->addChild(filteringGroupCube);
1181*35238bceSAndroid Build Coastguard Worker     groupCube->addChild(wrapGroupCube);
1182*35238bceSAndroid Build Coastguard Worker 
1183*35238bceSAndroid Build Coastguard Worker     addChild(group2D);
1184*35238bceSAndroid Build Coastguard Worker     addChild(groupCube);
1185*35238bceSAndroid Build Coastguard Worker 
1186*35238bceSAndroid Build Coastguard Worker     static const struct
1187*35238bceSAndroid Build Coastguard Worker     {
1188*35238bceSAndroid Build Coastguard Worker         const char *name;
1189*35238bceSAndroid Build Coastguard Worker         GLenum mode;
1190*35238bceSAndroid Build Coastguard Worker     } wrapModes[] = {{"clamp", GL_CLAMP_TO_EDGE}, {"repeat", GL_REPEAT}, {"mirror", GL_MIRRORED_REPEAT}};
1191*35238bceSAndroid Build Coastguard Worker 
1192*35238bceSAndroid Build Coastguard Worker     static const struct
1193*35238bceSAndroid Build Coastguard Worker     {
1194*35238bceSAndroid Build Coastguard Worker         const char *name;
1195*35238bceSAndroid Build Coastguard Worker         GLenum mode;
1196*35238bceSAndroid Build Coastguard Worker     } minFilterModes[] = {{"nearest", GL_NEAREST},
1197*35238bceSAndroid Build Coastguard Worker                           {"linear", GL_LINEAR},
1198*35238bceSAndroid Build Coastguard Worker                           {"nearest_mipmap_nearest", GL_NEAREST_MIPMAP_NEAREST},
1199*35238bceSAndroid Build Coastguard Worker                           {"linear_mipmap_nearest", GL_LINEAR_MIPMAP_NEAREST},
1200*35238bceSAndroid Build Coastguard Worker                           {"nearest_mipmap_linear", GL_NEAREST_MIPMAP_LINEAR},
1201*35238bceSAndroid Build Coastguard Worker                           {"linear_mipmap_linear", GL_LINEAR_MIPMAP_LINEAR}};
1202*35238bceSAndroid Build Coastguard Worker 
1203*35238bceSAndroid Build Coastguard Worker     static const struct
1204*35238bceSAndroid Build Coastguard Worker     {
1205*35238bceSAndroid Build Coastguard Worker         const char *name;
1206*35238bceSAndroid Build Coastguard Worker         GLenum mode;
1207*35238bceSAndroid Build Coastguard Worker     } magFilterModes[] = {{"nearest", GL_NEAREST}, {"linear", GL_LINEAR}};
1208*35238bceSAndroid Build Coastguard Worker 
1209*35238bceSAndroid Build Coastguard Worker #define FOR_EACH(ITERATOR, ARRAY, BODY)                                      \
1210*35238bceSAndroid Build Coastguard Worker     for (int ITERATOR = 0; ITERATOR < DE_LENGTH_OF_ARRAY(ARRAY); ITERATOR++) \
1211*35238bceSAndroid Build Coastguard Worker     BODY
1212*35238bceSAndroid Build Coastguard Worker 
1213*35238bceSAndroid Build Coastguard Worker     // 2D cases.
1214*35238bceSAndroid Build Coastguard Worker 
1215*35238bceSAndroid Build Coastguard Worker     FOR_EACH(minFilter, minFilterModes,
1216*35238bceSAndroid Build Coastguard Worker              FOR_EACH(magFilter, magFilterModes, FOR_EACH(wrapMode, wrapModes, {
1217*35238bceSAndroid Build Coastguard Worker                           const string name = string("") + minFilterModes[minFilter].name + "_" +
1218*35238bceSAndroid Build Coastguard Worker                                               magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name;
1219*35238bceSAndroid Build Coastguard Worker 
1220*35238bceSAndroid Build Coastguard Worker                           filteringGroup2D->addChild(new Vertex2DTextureCase(
1221*35238bceSAndroid Build Coastguard Worker                               m_context, name.c_str(), "", minFilterModes[minFilter].mode,
1222*35238bceSAndroid Build Coastguard Worker                               magFilterModes[magFilter].mode, wrapModes[wrapMode].mode, wrapModes[wrapMode].mode));
1223*35238bceSAndroid Build Coastguard Worker                       })))
1224*35238bceSAndroid Build Coastguard Worker 
1225*35238bceSAndroid Build Coastguard Worker     FOR_EACH(wrapSMode, wrapModes, FOR_EACH(wrapTMode, wrapModes, {
1226*35238bceSAndroid Build Coastguard Worker                  const string name = string("") + wrapModes[wrapSMode].name + "_" + wrapModes[wrapTMode].name;
1227*35238bceSAndroid Build Coastguard Worker 
1228*35238bceSAndroid Build Coastguard Worker                  wrapGroup2D->addChild(new Vertex2DTextureCase(m_context, name.c_str(), "", GL_LINEAR_MIPMAP_LINEAR,
1229*35238bceSAndroid Build Coastguard Worker                                                                GL_LINEAR, wrapModes[wrapSMode].mode,
1230*35238bceSAndroid Build Coastguard Worker                                                                wrapModes[wrapTMode].mode));
1231*35238bceSAndroid Build Coastguard Worker              }))
1232*35238bceSAndroid Build Coastguard Worker 
1233*35238bceSAndroid Build Coastguard Worker     // Cube map cases.
1234*35238bceSAndroid Build Coastguard Worker 
1235*35238bceSAndroid Build Coastguard Worker     FOR_EACH(minFilter, minFilterModes,
1236*35238bceSAndroid Build Coastguard Worker              FOR_EACH(magFilter, magFilterModes, FOR_EACH(wrapMode, wrapModes, {
1237*35238bceSAndroid Build Coastguard Worker                           const string name = string("") + minFilterModes[minFilter].name + "_" +
1238*35238bceSAndroid Build Coastguard Worker                                               magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name;
1239*35238bceSAndroid Build Coastguard Worker 
1240*35238bceSAndroid Build Coastguard Worker                           filteringGroupCube->addChild(new VertexCubeTextureCase(
1241*35238bceSAndroid Build Coastguard Worker                               m_context, name.c_str(), "", minFilterModes[minFilter].mode,
1242*35238bceSAndroid Build Coastguard Worker                               magFilterModes[magFilter].mode, wrapModes[wrapMode].mode, wrapModes[wrapMode].mode));
1243*35238bceSAndroid Build Coastguard Worker                       })))
1244*35238bceSAndroid Build Coastguard Worker 
1245*35238bceSAndroid Build Coastguard Worker     FOR_EACH(wrapSMode, wrapModes, FOR_EACH(wrapTMode, wrapModes, {
1246*35238bceSAndroid Build Coastguard Worker                  const string name = string("") + wrapModes[wrapSMode].name + "_" + wrapModes[wrapTMode].name;
1247*35238bceSAndroid Build Coastguard Worker 
1248*35238bceSAndroid Build Coastguard Worker                  wrapGroupCube->addChild(new VertexCubeTextureCase(m_context, name.c_str(), "", GL_LINEAR_MIPMAP_LINEAR,
1249*35238bceSAndroid Build Coastguard Worker                                                                    GL_LINEAR, wrapModes[wrapSMode].mode,
1250*35238bceSAndroid Build Coastguard Worker                                                                    wrapModes[wrapTMode].mode));
1251*35238bceSAndroid Build Coastguard Worker              }))
1252*35238bceSAndroid Build Coastguard Worker }
1253*35238bceSAndroid Build Coastguard Worker 
1254*35238bceSAndroid Build Coastguard Worker } // namespace Functional
1255*35238bceSAndroid Build Coastguard Worker } // namespace gles2
1256*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1257