xref: /aosp_15_r20/external/deqp/modules/gles31/functional/es31fTextureGatherTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 3.1 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 GLSL textureGather[Offset[s]] tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es31fTextureGatherTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "glsTextureTestUtil.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "gluTexture.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "gluDrawUtil.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "gluPixelTransfer.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "gluTextureUtil.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "gluStrUtil.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "gluObjectWrapper.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "tcuTextureUtil.hpp"
34*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
35*35238bceSAndroid Build Coastguard Worker #include "tcuSurface.hpp"
36*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
37*35238bceSAndroid Build Coastguard Worker #include "tcuVectorUtil.hpp"
38*35238bceSAndroid Build Coastguard Worker #include "tcuTexLookupVerifier.hpp"
39*35238bceSAndroid Build Coastguard Worker #include "tcuTexCompareVerifier.hpp"
40*35238bceSAndroid Build Coastguard Worker #include "tcuCommandLine.hpp"
41*35238bceSAndroid Build Coastguard Worker #include "deUniquePtr.hpp"
42*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
43*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
44*35238bceSAndroid Build Coastguard Worker #include "deString.h"
45*35238bceSAndroid Build Coastguard Worker 
46*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
47*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
48*35238bceSAndroid Build Coastguard Worker 
49*35238bceSAndroid Build Coastguard Worker using de::MovePtr;
50*35238bceSAndroid Build Coastguard Worker using glu::ShaderProgram;
51*35238bceSAndroid Build Coastguard Worker using tcu::ConstPixelBufferAccess;
52*35238bceSAndroid Build Coastguard Worker using tcu::IVec2;
53*35238bceSAndroid Build Coastguard Worker using tcu::IVec3;
54*35238bceSAndroid Build Coastguard Worker using tcu::IVec4;
55*35238bceSAndroid Build Coastguard Worker using tcu::PixelBufferAccess;
56*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
57*35238bceSAndroid Build Coastguard Worker using tcu::UVec4;
58*35238bceSAndroid Build Coastguard Worker using tcu::Vec2;
59*35238bceSAndroid Build Coastguard Worker using tcu::Vec3;
60*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
61*35238bceSAndroid Build Coastguard Worker 
62*35238bceSAndroid Build Coastguard Worker using std::string;
63*35238bceSAndroid Build Coastguard Worker using std::vector;
64*35238bceSAndroid Build Coastguard Worker 
65*35238bceSAndroid Build Coastguard Worker namespace deqp
66*35238bceSAndroid Build Coastguard Worker {
67*35238bceSAndroid Build Coastguard Worker 
68*35238bceSAndroid Build Coastguard Worker using glu::TextureTestUtil::TextureType;
69*35238bceSAndroid Build Coastguard Worker using glu::TextureTestUtil::TEXTURETYPE_2D;
70*35238bceSAndroid Build Coastguard Worker using glu::TextureTestUtil::TEXTURETYPE_2D_ARRAY;
71*35238bceSAndroid Build Coastguard Worker using glu::TextureTestUtil::TEXTURETYPE_CUBE;
72*35238bceSAndroid Build Coastguard Worker 
73*35238bceSAndroid Build Coastguard Worker namespace gles31
74*35238bceSAndroid Build Coastguard Worker {
75*35238bceSAndroid Build Coastguard Worker namespace Functional
76*35238bceSAndroid Build Coastguard Worker {
77*35238bceSAndroid Build Coastguard Worker 
78*35238bceSAndroid Build Coastguard Worker namespace
79*35238bceSAndroid Build Coastguard Worker {
80*35238bceSAndroid Build Coastguard Worker 
specializeShader(Context & context,const char * code)81*35238bceSAndroid Build Coastguard Worker static std::string specializeShader(Context &context, const char *code)
82*35238bceSAndroid Build Coastguard Worker {
83*35238bceSAndroid Build Coastguard Worker     const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(context.getRenderContext().getType());
84*35238bceSAndroid Build Coastguard Worker     std::map<std::string, std::string> specializationMap;
85*35238bceSAndroid Build Coastguard Worker 
86*35238bceSAndroid Build Coastguard Worker     specializationMap["GLSL_VERSION_DECL"] = glu::getGLSLVersionDeclaration(glslVersion);
87*35238bceSAndroid Build Coastguard Worker 
88*35238bceSAndroid Build Coastguard Worker     if (glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
89*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::core(4, 5)))
90*35238bceSAndroid Build Coastguard Worker         specializationMap["GPU_SHADER5_REQUIRE"] = "";
91*35238bceSAndroid Build Coastguard Worker     else
92*35238bceSAndroid Build Coastguard Worker         specializationMap["GPU_SHADER5_REQUIRE"] = "#extension GL_EXT_gpu_shader5 : require";
93*35238bceSAndroid Build Coastguard Worker 
94*35238bceSAndroid Build Coastguard Worker     return tcu::StringTemplate(code).specialize(specializationMap);
95*35238bceSAndroid Build Coastguard Worker }
96*35238bceSAndroid Build Coastguard Worker 
97*35238bceSAndroid Build Coastguard Worker // Round-to-zero int division, because pre-c++11 it's somewhat implementation-defined for negative values.
divRoundToZero(int a,int b)98*35238bceSAndroid Build Coastguard Worker static inline int divRoundToZero(int a, int b)
99*35238bceSAndroid Build Coastguard Worker {
100*35238bceSAndroid Build Coastguard Worker     return de::abs(a) / de::abs(b) * deSign32(a) * deSign32(b);
101*35238bceSAndroid Build Coastguard Worker }
102*35238bceSAndroid Build Coastguard Worker 
fillWithRandomColorTiles(const PixelBufferAccess & dst,const Vec4 & minVal,const Vec4 & maxVal,uint32_t seed)103*35238bceSAndroid Build Coastguard Worker static void fillWithRandomColorTiles(const PixelBufferAccess &dst, const Vec4 &minVal, const Vec4 &maxVal,
104*35238bceSAndroid Build Coastguard Worker                                      uint32_t seed)
105*35238bceSAndroid Build Coastguard Worker {
106*35238bceSAndroid Build Coastguard Worker     const int numCols = dst.getWidth() >= 7 ? 7 : dst.getWidth();
107*35238bceSAndroid Build Coastguard Worker     const int numRows = dst.getHeight() >= 5 ? 5 : dst.getHeight();
108*35238bceSAndroid Build Coastguard Worker     de::Random rnd(seed);
109*35238bceSAndroid Build Coastguard Worker 
110*35238bceSAndroid Build Coastguard Worker     for (int slice = 0; slice < dst.getDepth(); slice++)
111*35238bceSAndroid Build Coastguard Worker         for (int row = 0; row < numRows; row++)
112*35238bceSAndroid Build Coastguard Worker             for (int col = 0; col < numCols; col++)
113*35238bceSAndroid Build Coastguard Worker             {
114*35238bceSAndroid Build Coastguard Worker                 const int yBegin = (row + 0) * dst.getHeight() / numRows;
115*35238bceSAndroid Build Coastguard Worker                 const int yEnd   = (row + 1) * dst.getHeight() / numRows;
116*35238bceSAndroid Build Coastguard Worker                 const int xBegin = (col + 0) * dst.getWidth() / numCols;
117*35238bceSAndroid Build Coastguard Worker                 const int xEnd   = (col + 1) * dst.getWidth() / numCols;
118*35238bceSAndroid Build Coastguard Worker                 Vec4 color;
119*35238bceSAndroid Build Coastguard Worker                 for (int i = 0; i < 4; i++)
120*35238bceSAndroid Build Coastguard Worker                     color[i] = rnd.getFloat(minVal[i], maxVal[i]);
121*35238bceSAndroid Build Coastguard Worker                 tcu::clear(tcu::getSubregion(dst, xBegin, yBegin, slice, xEnd - xBegin, yEnd - yBegin, 1), color);
122*35238bceSAndroid Build Coastguard Worker             }
123*35238bceSAndroid Build Coastguard Worker }
124*35238bceSAndroid Build Coastguard Worker 
isDepthFormat(const tcu::TextureFormat & fmt)125*35238bceSAndroid Build Coastguard Worker static inline bool isDepthFormat(const tcu::TextureFormat &fmt)
126*35238bceSAndroid Build Coastguard Worker {
127*35238bceSAndroid Build Coastguard Worker     return fmt.order == tcu::TextureFormat::D || fmt.order == tcu::TextureFormat::DS;
128*35238bceSAndroid Build Coastguard Worker }
129*35238bceSAndroid Build Coastguard Worker 
isUnormFormatType(tcu::TextureFormat::ChannelType type)130*35238bceSAndroid Build Coastguard Worker static inline bool isUnormFormatType(tcu::TextureFormat::ChannelType type)
131*35238bceSAndroid Build Coastguard Worker {
132*35238bceSAndroid Build Coastguard Worker     return type == tcu::TextureFormat::UNORM_INT8 || type == tcu::TextureFormat::UNORM_INT16 ||
133*35238bceSAndroid Build Coastguard Worker            type == tcu::TextureFormat::UNORM_INT32;
134*35238bceSAndroid Build Coastguard Worker }
135*35238bceSAndroid Build Coastguard Worker 
isSIntFormatType(tcu::TextureFormat::ChannelType type)136*35238bceSAndroid Build Coastguard Worker static inline bool isSIntFormatType(tcu::TextureFormat::ChannelType type)
137*35238bceSAndroid Build Coastguard Worker {
138*35238bceSAndroid Build Coastguard Worker     return type == tcu::TextureFormat::SIGNED_INT8 || type == tcu::TextureFormat::SIGNED_INT16 ||
139*35238bceSAndroid Build Coastguard Worker            type == tcu::TextureFormat::SIGNED_INT32;
140*35238bceSAndroid Build Coastguard Worker }
141*35238bceSAndroid Build Coastguard Worker 
isUIntFormatType(tcu::TextureFormat::ChannelType type)142*35238bceSAndroid Build Coastguard Worker static inline bool isUIntFormatType(tcu::TextureFormat::ChannelType type)
143*35238bceSAndroid Build Coastguard Worker {
144*35238bceSAndroid Build Coastguard Worker     return type == tcu::TextureFormat::UNSIGNED_INT8 || type == tcu::TextureFormat::UNSIGNED_INT16 ||
145*35238bceSAndroid Build Coastguard Worker            type == tcu::TextureFormat::UNSIGNED_INT32;
146*35238bceSAndroid Build Coastguard Worker }
147*35238bceSAndroid Build Coastguard Worker 
getPixels(const glu::RenderContext & renderCtx,const IVec2 & size,const tcu::TextureFormat & colorBufferFormat)148*35238bceSAndroid Build Coastguard Worker static tcu::TextureLevel getPixels(const glu::RenderContext &renderCtx, const IVec2 &size,
149*35238bceSAndroid Build Coastguard Worker                                    const tcu::TextureFormat &colorBufferFormat)
150*35238bceSAndroid Build Coastguard Worker {
151*35238bceSAndroid Build Coastguard Worker     tcu::TextureLevel result(colorBufferFormat, size.x(), size.y());
152*35238bceSAndroid Build Coastguard Worker 
153*35238bceSAndroid Build Coastguard Worker     // only a few pixel formats are guaranteed to be valid targets for readPixels, convert the rest
154*35238bceSAndroid Build Coastguard Worker     if (colorBufferFormat.order == tcu::TextureFormat::RGBA &&
155*35238bceSAndroid Build Coastguard Worker         (colorBufferFormat.type == tcu::TextureFormat::UNORM_INT8 ||
156*35238bceSAndroid Build Coastguard Worker          colorBufferFormat.type == tcu::TextureFormat::SIGNED_INT32 ||
157*35238bceSAndroid Build Coastguard Worker          colorBufferFormat.type == tcu::TextureFormat::UNSIGNED_INT32))
158*35238bceSAndroid Build Coastguard Worker     {
159*35238bceSAndroid Build Coastguard Worker         // valid as is
160*35238bceSAndroid Build Coastguard Worker         glu::readPixels(renderCtx, 0, 0, result.getAccess());
161*35238bceSAndroid Build Coastguard Worker     }
162*35238bceSAndroid Build Coastguard Worker     else if (colorBufferFormat.order == tcu::TextureFormat::RGBA &&
163*35238bceSAndroid Build Coastguard Worker              (isSIntFormatType(colorBufferFormat.type) || isUIntFormatType(colorBufferFormat.type)))
164*35238bceSAndroid Build Coastguard Worker     {
165*35238bceSAndroid Build Coastguard Worker         // signed and unsigned integers must be read using 32-bit values
166*35238bceSAndroid Build Coastguard Worker         const bool isSigned = isSIntFormatType(colorBufferFormat.type);
167*35238bceSAndroid Build Coastguard Worker         tcu::TextureLevel readResult(
168*35238bceSAndroid Build Coastguard Worker             tcu::TextureFormat(tcu::TextureFormat::RGBA,
169*35238bceSAndroid Build Coastguard Worker                                (isSigned) ? (tcu::TextureFormat::SIGNED_INT32) : (tcu::TextureFormat::UNSIGNED_INT32)),
170*35238bceSAndroid Build Coastguard Worker             size.x(), size.y());
171*35238bceSAndroid Build Coastguard Worker 
172*35238bceSAndroid Build Coastguard Worker         glu::readPixels(renderCtx, 0, 0, readResult.getAccess());
173*35238bceSAndroid Build Coastguard Worker         tcu::copy(result.getAccess(), readResult.getAccess());
174*35238bceSAndroid Build Coastguard Worker     }
175*35238bceSAndroid Build Coastguard Worker     else
176*35238bceSAndroid Build Coastguard Worker     {
177*35238bceSAndroid Build Coastguard Worker         // unreadable format
178*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
179*35238bceSAndroid Build Coastguard Worker     }
180*35238bceSAndroid Build Coastguard Worker 
181*35238bceSAndroid Build Coastguard Worker     return result;
182*35238bceSAndroid Build Coastguard Worker }
183*35238bceSAndroid Build Coastguard Worker 
184*35238bceSAndroid Build Coastguard Worker enum TextureSwizzleComponent
185*35238bceSAndroid Build Coastguard Worker {
186*35238bceSAndroid Build Coastguard Worker     TEXTURESWIZZLECOMPONENT_R = 0,
187*35238bceSAndroid Build Coastguard Worker     TEXTURESWIZZLECOMPONENT_G,
188*35238bceSAndroid Build Coastguard Worker     TEXTURESWIZZLECOMPONENT_B,
189*35238bceSAndroid Build Coastguard Worker     TEXTURESWIZZLECOMPONENT_A,
190*35238bceSAndroid Build Coastguard Worker     TEXTURESWIZZLECOMPONENT_ZERO,
191*35238bceSAndroid Build Coastguard Worker     TEXTURESWIZZLECOMPONENT_ONE,
192*35238bceSAndroid Build Coastguard Worker 
193*35238bceSAndroid Build Coastguard Worker     TEXTURESWIZZLECOMPONENT_LAST
194*35238bceSAndroid Build Coastguard Worker };
195*35238bceSAndroid Build Coastguard Worker 
operator <<(std::ostream & stream,TextureSwizzleComponent comp)196*35238bceSAndroid Build Coastguard Worker static std::ostream &operator<<(std::ostream &stream, TextureSwizzleComponent comp)
197*35238bceSAndroid Build Coastguard Worker {
198*35238bceSAndroid Build Coastguard Worker     switch (comp)
199*35238bceSAndroid Build Coastguard Worker     {
200*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_R:
201*35238bceSAndroid Build Coastguard Worker         return stream << "RED";
202*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_G:
203*35238bceSAndroid Build Coastguard Worker         return stream << "GREEN";
204*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_B:
205*35238bceSAndroid Build Coastguard Worker         return stream << "BLUE";
206*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_A:
207*35238bceSAndroid Build Coastguard Worker         return stream << "ALPHA";
208*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_ZERO:
209*35238bceSAndroid Build Coastguard Worker         return stream << "ZERO";
210*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_ONE:
211*35238bceSAndroid Build Coastguard Worker         return stream << "ONE";
212*35238bceSAndroid Build Coastguard Worker     default:
213*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
214*35238bceSAndroid Build Coastguard Worker         return stream;
215*35238bceSAndroid Build Coastguard Worker     }
216*35238bceSAndroid Build Coastguard Worker }
217*35238bceSAndroid Build Coastguard Worker 
218*35238bceSAndroid Build Coastguard Worker struct MaybeTextureSwizzle
219*35238bceSAndroid Build Coastguard Worker {
220*35238bceSAndroid Build Coastguard Worker public:
221*35238bceSAndroid Build Coastguard Worker     static MaybeTextureSwizzle createNoneTextureSwizzle(void);
222*35238bceSAndroid Build Coastguard Worker     static MaybeTextureSwizzle createSomeTextureSwizzle(void);
223*35238bceSAndroid Build Coastguard Worker 
224*35238bceSAndroid Build Coastguard Worker     bool isSome(void) const;
225*35238bceSAndroid Build Coastguard Worker     bool isNone(void) const;
226*35238bceSAndroid Build Coastguard Worker     bool isIdentitySwizzle(void) const;
227*35238bceSAndroid Build Coastguard Worker 
228*35238bceSAndroid Build Coastguard Worker     tcu::Vector<TextureSwizzleComponent, 4> &getSwizzle(void);
229*35238bceSAndroid Build Coastguard Worker     const tcu::Vector<TextureSwizzleComponent, 4> &getSwizzle(void) const;
230*35238bceSAndroid Build Coastguard Worker 
231*35238bceSAndroid Build Coastguard Worker private:
232*35238bceSAndroid Build Coastguard Worker     MaybeTextureSwizzle(void);
233*35238bceSAndroid Build Coastguard Worker 
234*35238bceSAndroid Build Coastguard Worker     tcu::Vector<TextureSwizzleComponent, 4> m_swizzle;
235*35238bceSAndroid Build Coastguard Worker     bool m_isSome;
236*35238bceSAndroid Build Coastguard Worker };
237*35238bceSAndroid Build Coastguard Worker 
operator <<(std::ostream & stream,const MaybeTextureSwizzle & comp)238*35238bceSAndroid Build Coastguard Worker static std::ostream &operator<<(std::ostream &stream, const MaybeTextureSwizzle &comp)
239*35238bceSAndroid Build Coastguard Worker {
240*35238bceSAndroid Build Coastguard Worker     if (comp.isNone())
241*35238bceSAndroid Build Coastguard Worker         stream << "[default swizzle state]";
242*35238bceSAndroid Build Coastguard Worker     else
243*35238bceSAndroid Build Coastguard Worker         stream << "(" << comp.getSwizzle()[0] << ", " << comp.getSwizzle()[1] << ", " << comp.getSwizzle()[2] << ", "
244*35238bceSAndroid Build Coastguard Worker                << comp.getSwizzle()[3] << ")";
245*35238bceSAndroid Build Coastguard Worker 
246*35238bceSAndroid Build Coastguard Worker     return stream;
247*35238bceSAndroid Build Coastguard Worker }
248*35238bceSAndroid Build Coastguard Worker 
createNoneTextureSwizzle(void)249*35238bceSAndroid Build Coastguard Worker MaybeTextureSwizzle MaybeTextureSwizzle::createNoneTextureSwizzle(void)
250*35238bceSAndroid Build Coastguard Worker {
251*35238bceSAndroid Build Coastguard Worker     MaybeTextureSwizzle swizzle;
252*35238bceSAndroid Build Coastguard Worker 
253*35238bceSAndroid Build Coastguard Worker     swizzle.m_swizzle[0] = TEXTURESWIZZLECOMPONENT_LAST;
254*35238bceSAndroid Build Coastguard Worker     swizzle.m_swizzle[1] = TEXTURESWIZZLECOMPONENT_LAST;
255*35238bceSAndroid Build Coastguard Worker     swizzle.m_swizzle[2] = TEXTURESWIZZLECOMPONENT_LAST;
256*35238bceSAndroid Build Coastguard Worker     swizzle.m_swizzle[3] = TEXTURESWIZZLECOMPONENT_LAST;
257*35238bceSAndroid Build Coastguard Worker     swizzle.m_isSome     = false;
258*35238bceSAndroid Build Coastguard Worker 
259*35238bceSAndroid Build Coastguard Worker     return swizzle;
260*35238bceSAndroid Build Coastguard Worker }
261*35238bceSAndroid Build Coastguard Worker 
createSomeTextureSwizzle(void)262*35238bceSAndroid Build Coastguard Worker MaybeTextureSwizzle MaybeTextureSwizzle::createSomeTextureSwizzle(void)
263*35238bceSAndroid Build Coastguard Worker {
264*35238bceSAndroid Build Coastguard Worker     MaybeTextureSwizzle swizzle;
265*35238bceSAndroid Build Coastguard Worker 
266*35238bceSAndroid Build Coastguard Worker     swizzle.m_swizzle[0] = TEXTURESWIZZLECOMPONENT_R;
267*35238bceSAndroid Build Coastguard Worker     swizzle.m_swizzle[1] = TEXTURESWIZZLECOMPONENT_G;
268*35238bceSAndroid Build Coastguard Worker     swizzle.m_swizzle[2] = TEXTURESWIZZLECOMPONENT_B;
269*35238bceSAndroid Build Coastguard Worker     swizzle.m_swizzle[3] = TEXTURESWIZZLECOMPONENT_A;
270*35238bceSAndroid Build Coastguard Worker     swizzle.m_isSome     = true;
271*35238bceSAndroid Build Coastguard Worker 
272*35238bceSAndroid Build Coastguard Worker     return swizzle;
273*35238bceSAndroid Build Coastguard Worker }
274*35238bceSAndroid Build Coastguard Worker 
isSome(void) const275*35238bceSAndroid Build Coastguard Worker bool MaybeTextureSwizzle::isSome(void) const
276*35238bceSAndroid Build Coastguard Worker {
277*35238bceSAndroid Build Coastguard Worker     return m_isSome;
278*35238bceSAndroid Build Coastguard Worker }
279*35238bceSAndroid Build Coastguard Worker 
isNone(void) const280*35238bceSAndroid Build Coastguard Worker bool MaybeTextureSwizzle::isNone(void) const
281*35238bceSAndroid Build Coastguard Worker {
282*35238bceSAndroid Build Coastguard Worker     return !m_isSome;
283*35238bceSAndroid Build Coastguard Worker }
284*35238bceSAndroid Build Coastguard Worker 
isIdentitySwizzle(void) const285*35238bceSAndroid Build Coastguard Worker bool MaybeTextureSwizzle::isIdentitySwizzle(void) const
286*35238bceSAndroid Build Coastguard Worker {
287*35238bceSAndroid Build Coastguard Worker     return m_isSome && m_swizzle[0] == TEXTURESWIZZLECOMPONENT_R && m_swizzle[1] == TEXTURESWIZZLECOMPONENT_G &&
288*35238bceSAndroid Build Coastguard Worker            m_swizzle[2] == TEXTURESWIZZLECOMPONENT_B && m_swizzle[3] == TEXTURESWIZZLECOMPONENT_A;
289*35238bceSAndroid Build Coastguard Worker }
290*35238bceSAndroid Build Coastguard Worker 
getSwizzle(void)291*35238bceSAndroid Build Coastguard Worker tcu::Vector<TextureSwizzleComponent, 4> &MaybeTextureSwizzle::getSwizzle(void)
292*35238bceSAndroid Build Coastguard Worker {
293*35238bceSAndroid Build Coastguard Worker     return m_swizzle;
294*35238bceSAndroid Build Coastguard Worker }
295*35238bceSAndroid Build Coastguard Worker 
getSwizzle(void) const296*35238bceSAndroid Build Coastguard Worker const tcu::Vector<TextureSwizzleComponent, 4> &MaybeTextureSwizzle::getSwizzle(void) const
297*35238bceSAndroid Build Coastguard Worker {
298*35238bceSAndroid Build Coastguard Worker     return m_swizzle;
299*35238bceSAndroid Build Coastguard Worker }
300*35238bceSAndroid Build Coastguard Worker 
MaybeTextureSwizzle(void)301*35238bceSAndroid Build Coastguard Worker MaybeTextureSwizzle::MaybeTextureSwizzle(void)
302*35238bceSAndroid Build Coastguard Worker     : m_swizzle(TEXTURESWIZZLECOMPONENT_LAST, TEXTURESWIZZLECOMPONENT_LAST, TEXTURESWIZZLECOMPONENT_LAST,
303*35238bceSAndroid Build Coastguard Worker                 TEXTURESWIZZLECOMPONENT_LAST)
304*35238bceSAndroid Build Coastguard Worker     , m_isSome(false)
305*35238bceSAndroid Build Coastguard Worker {
306*35238bceSAndroid Build Coastguard Worker }
307*35238bceSAndroid Build Coastguard Worker 
getGLTextureSwizzleComponent(TextureSwizzleComponent c)308*35238bceSAndroid Build Coastguard Worker static uint32_t getGLTextureSwizzleComponent(TextureSwizzleComponent c)
309*35238bceSAndroid Build Coastguard Worker {
310*35238bceSAndroid Build Coastguard Worker     switch (c)
311*35238bceSAndroid Build Coastguard Worker     {
312*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_R:
313*35238bceSAndroid Build Coastguard Worker         return GL_RED;
314*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_G:
315*35238bceSAndroid Build Coastguard Worker         return GL_GREEN;
316*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_B:
317*35238bceSAndroid Build Coastguard Worker         return GL_BLUE;
318*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_A:
319*35238bceSAndroid Build Coastguard Worker         return GL_ALPHA;
320*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_ZERO:
321*35238bceSAndroid Build Coastguard Worker         return GL_ZERO;
322*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_ONE:
323*35238bceSAndroid Build Coastguard Worker         return GL_ONE;
324*35238bceSAndroid Build Coastguard Worker     default:
325*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
326*35238bceSAndroid Build Coastguard Worker         return (uint32_t)-1;
327*35238bceSAndroid Build Coastguard Worker     }
328*35238bceSAndroid Build Coastguard Worker }
329*35238bceSAndroid Build Coastguard Worker 
330*35238bceSAndroid Build Coastguard Worker template <typename T>
swizzleColorChannel(const tcu::Vector<T,4> & src,TextureSwizzleComponent swizzle)331*35238bceSAndroid Build Coastguard Worker static inline T swizzleColorChannel(const tcu::Vector<T, 4> &src, TextureSwizzleComponent swizzle)
332*35238bceSAndroid Build Coastguard Worker {
333*35238bceSAndroid Build Coastguard Worker     switch (swizzle)
334*35238bceSAndroid Build Coastguard Worker     {
335*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_R:
336*35238bceSAndroid Build Coastguard Worker         return src[0];
337*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_G:
338*35238bceSAndroid Build Coastguard Worker         return src[1];
339*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_B:
340*35238bceSAndroid Build Coastguard Worker         return src[2];
341*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_A:
342*35238bceSAndroid Build Coastguard Worker         return src[3];
343*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_ZERO:
344*35238bceSAndroid Build Coastguard Worker         return (T)0;
345*35238bceSAndroid Build Coastguard Worker     case TEXTURESWIZZLECOMPONENT_ONE:
346*35238bceSAndroid Build Coastguard Worker         return (T)1;
347*35238bceSAndroid Build Coastguard Worker     default:
348*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
349*35238bceSAndroid Build Coastguard Worker         return (T)-1;
350*35238bceSAndroid Build Coastguard Worker     }
351*35238bceSAndroid Build Coastguard Worker }
352*35238bceSAndroid Build Coastguard Worker 
353*35238bceSAndroid Build Coastguard Worker template <typename T>
swizzleColor(const tcu::Vector<T,4> & src,const MaybeTextureSwizzle & swizzle)354*35238bceSAndroid Build Coastguard Worker static inline tcu::Vector<T, 4> swizzleColor(const tcu::Vector<T, 4> &src, const MaybeTextureSwizzle &swizzle)
355*35238bceSAndroid Build Coastguard Worker {
356*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(swizzle.isSome());
357*35238bceSAndroid Build Coastguard Worker 
358*35238bceSAndroid Build Coastguard Worker     tcu::Vector<T, 4> result;
359*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < 4; i++)
360*35238bceSAndroid Build Coastguard Worker         result[i] = swizzleColorChannel(src, swizzle.getSwizzle()[i]);
361*35238bceSAndroid Build Coastguard Worker     return result;
362*35238bceSAndroid Build Coastguard Worker }
363*35238bceSAndroid Build Coastguard Worker 
364*35238bceSAndroid Build Coastguard Worker template <typename T>
swizzlePixels(const PixelBufferAccess & dst,const ConstPixelBufferAccess & src,const MaybeTextureSwizzle & swizzle)365*35238bceSAndroid Build Coastguard Worker static void swizzlePixels(const PixelBufferAccess &dst, const ConstPixelBufferAccess &src,
366*35238bceSAndroid Build Coastguard Worker                           const MaybeTextureSwizzle &swizzle)
367*35238bceSAndroid Build Coastguard Worker {
368*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(dst.getWidth() == src.getWidth() && dst.getHeight() == src.getHeight() &&
369*35238bceSAndroid Build Coastguard Worker               dst.getDepth() == src.getDepth());
370*35238bceSAndroid Build Coastguard Worker     for (int z = 0; z < src.getDepth(); z++)
371*35238bceSAndroid Build Coastguard Worker         for (int y = 0; y < src.getHeight(); y++)
372*35238bceSAndroid Build Coastguard Worker             for (int x = 0; x < src.getWidth(); x++)
373*35238bceSAndroid Build Coastguard Worker                 dst.setPixel(swizzleColor(src.getPixelT<T>(x, y, z), swizzle), x, y, z);
374*35238bceSAndroid Build Coastguard Worker }
375*35238bceSAndroid Build Coastguard Worker 
swizzlePixels(const PixelBufferAccess & dst,const ConstPixelBufferAccess & src,const MaybeTextureSwizzle & swizzle)376*35238bceSAndroid Build Coastguard Worker static void swizzlePixels(const PixelBufferAccess &dst, const ConstPixelBufferAccess &src,
377*35238bceSAndroid Build Coastguard Worker                           const MaybeTextureSwizzle &swizzle)
378*35238bceSAndroid Build Coastguard Worker {
379*35238bceSAndroid Build Coastguard Worker     if (isDepthFormat(dst.getFormat()))
380*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(swizzle.isNone() || swizzle.isIdentitySwizzle());
381*35238bceSAndroid Build Coastguard Worker 
382*35238bceSAndroid Build Coastguard Worker     if (swizzle.isNone() || swizzle.isIdentitySwizzle())
383*35238bceSAndroid Build Coastguard Worker         tcu::copy(dst, src);
384*35238bceSAndroid Build Coastguard Worker     else if (isUnormFormatType(dst.getFormat().type))
385*35238bceSAndroid Build Coastguard Worker         swizzlePixels<float>(dst, src, swizzle);
386*35238bceSAndroid Build Coastguard Worker     else if (isUIntFormatType(dst.getFormat().type))
387*35238bceSAndroid Build Coastguard Worker         swizzlePixels<uint32_t>(dst, src, swizzle);
388*35238bceSAndroid Build Coastguard Worker     else if (isSIntFormatType(dst.getFormat().type))
389*35238bceSAndroid Build Coastguard Worker         swizzlePixels<int32_t>(dst, src, swizzle);
390*35238bceSAndroid Build Coastguard Worker     else
391*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
392*35238bceSAndroid Build Coastguard Worker }
393*35238bceSAndroid Build Coastguard Worker 
swizzleTexture(tcu::Texture2D & dst,const tcu::Texture2D & src,const MaybeTextureSwizzle & swizzle)394*35238bceSAndroid Build Coastguard Worker static void swizzleTexture(tcu::Texture2D &dst, const tcu::Texture2D &src, const MaybeTextureSwizzle &swizzle)
395*35238bceSAndroid Build Coastguard Worker {
396*35238bceSAndroid Build Coastguard Worker     dst = tcu::Texture2D(src.getFormat(), src.getWidth(), src.getHeight());
397*35238bceSAndroid Build Coastguard Worker     for (int levelNdx = 0; levelNdx < src.getNumLevels(); levelNdx++)
398*35238bceSAndroid Build Coastguard Worker     {
399*35238bceSAndroid Build Coastguard Worker         if (src.isLevelEmpty(levelNdx))
400*35238bceSAndroid Build Coastguard Worker             continue;
401*35238bceSAndroid Build Coastguard Worker         dst.allocLevel(levelNdx);
402*35238bceSAndroid Build Coastguard Worker         swizzlePixels(dst.getLevel(levelNdx), src.getLevel(levelNdx), swizzle);
403*35238bceSAndroid Build Coastguard Worker     }
404*35238bceSAndroid Build Coastguard Worker }
405*35238bceSAndroid Build Coastguard Worker 
swizzleTexture(tcu::Texture2DArray & dst,const tcu::Texture2DArray & src,const MaybeTextureSwizzle & swizzle)406*35238bceSAndroid Build Coastguard Worker static void swizzleTexture(tcu::Texture2DArray &dst, const tcu::Texture2DArray &src, const MaybeTextureSwizzle &swizzle)
407*35238bceSAndroid Build Coastguard Worker {
408*35238bceSAndroid Build Coastguard Worker     dst = tcu::Texture2DArray(src.getFormat(), src.getWidth(), src.getHeight(), src.getNumLayers());
409*35238bceSAndroid Build Coastguard Worker     for (int levelNdx = 0; levelNdx < src.getNumLevels(); levelNdx++)
410*35238bceSAndroid Build Coastguard Worker     {
411*35238bceSAndroid Build Coastguard Worker         if (src.isLevelEmpty(levelNdx))
412*35238bceSAndroid Build Coastguard Worker             continue;
413*35238bceSAndroid Build Coastguard Worker         dst.allocLevel(levelNdx);
414*35238bceSAndroid Build Coastguard Worker         swizzlePixels(dst.getLevel(levelNdx), src.getLevel(levelNdx), swizzle);
415*35238bceSAndroid Build Coastguard Worker     }
416*35238bceSAndroid Build Coastguard Worker }
417*35238bceSAndroid Build Coastguard Worker 
swizzleTexture(tcu::TextureCube & dst,const tcu::TextureCube & src,const MaybeTextureSwizzle & swizzle)418*35238bceSAndroid Build Coastguard Worker static void swizzleTexture(tcu::TextureCube &dst, const tcu::TextureCube &src, const MaybeTextureSwizzle &swizzle)
419*35238bceSAndroid Build Coastguard Worker {
420*35238bceSAndroid Build Coastguard Worker     dst = tcu::TextureCube(src.getFormat(), src.getSize());
421*35238bceSAndroid Build Coastguard Worker     for (int faceI = 0; faceI < tcu::CUBEFACE_LAST; faceI++)
422*35238bceSAndroid Build Coastguard Worker     {
423*35238bceSAndroid Build Coastguard Worker         const tcu::CubeFace face = (tcu::CubeFace)faceI;
424*35238bceSAndroid Build Coastguard Worker         for (int levelNdx = 0; levelNdx < src.getNumLevels(); levelNdx++)
425*35238bceSAndroid Build Coastguard Worker         {
426*35238bceSAndroid Build Coastguard Worker             if (src.isLevelEmpty(face, levelNdx))
427*35238bceSAndroid Build Coastguard Worker                 continue;
428*35238bceSAndroid Build Coastguard Worker             dst.allocLevel(face, levelNdx);
429*35238bceSAndroid Build Coastguard Worker             swizzlePixels(dst.getLevelFace(levelNdx, face), src.getLevelFace(levelNdx, face), swizzle);
430*35238bceSAndroid Build Coastguard Worker         }
431*35238bceSAndroid Build Coastguard Worker     }
432*35238bceSAndroid Build Coastguard Worker }
433*35238bceSAndroid Build Coastguard Worker 
getOneLevelSubView(const tcu::Texture2DView & view,int level)434*35238bceSAndroid Build Coastguard Worker static tcu::Texture2DView getOneLevelSubView(const tcu::Texture2DView &view, int level)
435*35238bceSAndroid Build Coastguard Worker {
436*35238bceSAndroid Build Coastguard Worker     return tcu::Texture2DView(1, view.getLevels() + level);
437*35238bceSAndroid Build Coastguard Worker }
438*35238bceSAndroid Build Coastguard Worker 
getOneLevelSubView(const tcu::Texture2DArrayView & view,int level)439*35238bceSAndroid Build Coastguard Worker static tcu::Texture2DArrayView getOneLevelSubView(const tcu::Texture2DArrayView &view, int level)
440*35238bceSAndroid Build Coastguard Worker {
441*35238bceSAndroid Build Coastguard Worker     return tcu::Texture2DArrayView(1, view.getLevels() + level);
442*35238bceSAndroid Build Coastguard Worker }
443*35238bceSAndroid Build Coastguard Worker 
getOneLevelSubView(const tcu::TextureCubeView & view,int level)444*35238bceSAndroid Build Coastguard Worker static tcu::TextureCubeView getOneLevelSubView(const tcu::TextureCubeView &view, int level)
445*35238bceSAndroid Build Coastguard Worker {
446*35238bceSAndroid Build Coastguard Worker     const tcu::ConstPixelBufferAccess *levels[tcu::CUBEFACE_LAST];
447*35238bceSAndroid Build Coastguard Worker 
448*35238bceSAndroid Build Coastguard Worker     for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
449*35238bceSAndroid Build Coastguard Worker         levels[face] = view.getFaceLevels((tcu::CubeFace)face) + level;
450*35238bceSAndroid Build Coastguard Worker 
451*35238bceSAndroid Build Coastguard Worker     return tcu::TextureCubeView(1, levels);
452*35238bceSAndroid Build Coastguard Worker }
453*35238bceSAndroid Build Coastguard Worker 
454*35238bceSAndroid Build Coastguard Worker class PixelOffsets
455*35238bceSAndroid Build Coastguard Worker {
456*35238bceSAndroid Build Coastguard Worker public:
457*35238bceSAndroid Build Coastguard Worker     virtual void operator()(const IVec2 &pixCoord, IVec2 (&dst)[4]) const = 0;
~PixelOffsets(void)458*35238bceSAndroid Build Coastguard Worker     virtual ~PixelOffsets(void)
459*35238bceSAndroid Build Coastguard Worker     {
460*35238bceSAndroid Build Coastguard Worker     }
461*35238bceSAndroid Build Coastguard Worker };
462*35238bceSAndroid Build Coastguard Worker 
463*35238bceSAndroid Build Coastguard Worker class MultiplePixelOffsets : public PixelOffsets
464*35238bceSAndroid Build Coastguard Worker {
465*35238bceSAndroid Build Coastguard Worker public:
MultiplePixelOffsets(const IVec2 & a,const IVec2 & b,const IVec2 & c,const IVec2 & d)466*35238bceSAndroid Build Coastguard Worker     MultiplePixelOffsets(const IVec2 &a, const IVec2 &b, const IVec2 &c, const IVec2 &d)
467*35238bceSAndroid Build Coastguard Worker     {
468*35238bceSAndroid Build Coastguard Worker         m_offsets[0] = a;
469*35238bceSAndroid Build Coastguard Worker         m_offsets[1] = b;
470*35238bceSAndroid Build Coastguard Worker         m_offsets[2] = c;
471*35238bceSAndroid Build Coastguard Worker         m_offsets[3] = d;
472*35238bceSAndroid Build Coastguard Worker     }
473*35238bceSAndroid Build Coastguard Worker 
operator ()(const IVec2 &,IVec2 (& dst)[4]) const474*35238bceSAndroid Build Coastguard Worker     void operator()(const IVec2 & /* pixCoord */, IVec2 (&dst)[4]) const
475*35238bceSAndroid Build Coastguard Worker     {
476*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < DE_LENGTH_OF_ARRAY(dst); i++)
477*35238bceSAndroid Build Coastguard Worker             dst[i] = m_offsets[i];
478*35238bceSAndroid Build Coastguard Worker     }
479*35238bceSAndroid Build Coastguard Worker 
480*35238bceSAndroid Build Coastguard Worker private:
481*35238bceSAndroid Build Coastguard Worker     IVec2 m_offsets[4];
482*35238bceSAndroid Build Coastguard Worker };
483*35238bceSAndroid Build Coastguard Worker 
484*35238bceSAndroid Build Coastguard Worker class SinglePixelOffsets : public MultiplePixelOffsets
485*35238bceSAndroid Build Coastguard Worker {
486*35238bceSAndroid Build Coastguard Worker public:
SinglePixelOffsets(const IVec2 & offset)487*35238bceSAndroid Build Coastguard Worker     SinglePixelOffsets(const IVec2 &offset)
488*35238bceSAndroid Build Coastguard Worker         : MultiplePixelOffsets(offset + IVec2(0, 1), offset + IVec2(1, 1), offset + IVec2(1, 0), offset + IVec2(0, 0))
489*35238bceSAndroid Build Coastguard Worker     {
490*35238bceSAndroid Build Coastguard Worker     }
491*35238bceSAndroid Build Coastguard Worker };
492*35238bceSAndroid Build Coastguard Worker 
493*35238bceSAndroid Build Coastguard Worker class DynamicSinglePixelOffsets : public PixelOffsets
494*35238bceSAndroid Build Coastguard Worker {
495*35238bceSAndroid Build Coastguard Worker public:
DynamicSinglePixelOffsets(const IVec2 & offsetRange)496*35238bceSAndroid Build Coastguard Worker     DynamicSinglePixelOffsets(const IVec2 &offsetRange) : m_offsetRange(offsetRange)
497*35238bceSAndroid Build Coastguard Worker     {
498*35238bceSAndroid Build Coastguard Worker     }
499*35238bceSAndroid Build Coastguard Worker 
operator ()(const IVec2 & pixCoord,IVec2 (& dst)[4]) const500*35238bceSAndroid Build Coastguard Worker     void operator()(const IVec2 &pixCoord, IVec2 (&dst)[4]) const
501*35238bceSAndroid Build Coastguard Worker     {
502*35238bceSAndroid Build Coastguard Worker         const int offsetRangeSize = m_offsetRange.y() - m_offsetRange.x() + 1;
503*35238bceSAndroid Build Coastguard Worker         SinglePixelOffsets(tcu::mod(pixCoord.swizzle(1, 0), IVec2(offsetRangeSize)) + m_offsetRange.x())(IVec2(), dst);
504*35238bceSAndroid Build Coastguard Worker     }
505*35238bceSAndroid Build Coastguard Worker 
506*35238bceSAndroid Build Coastguard Worker private:
507*35238bceSAndroid Build Coastguard Worker     IVec2 m_offsetRange;
508*35238bceSAndroid Build Coastguard Worker };
509*35238bceSAndroid Build Coastguard Worker 
510*35238bceSAndroid Build Coastguard Worker template <typename T>
triQuadInterpolate(const T (& values)[4],float xFactor,float yFactor)511*35238bceSAndroid Build Coastguard Worker static inline T triQuadInterpolate(const T (&values)[4], float xFactor, float yFactor)
512*35238bceSAndroid Build Coastguard Worker {
513*35238bceSAndroid Build Coastguard Worker     if (xFactor + yFactor < 1.0f)
514*35238bceSAndroid Build Coastguard Worker         return values[0] + (values[2] - values[0]) * xFactor + (values[1] - values[0]) * yFactor;
515*35238bceSAndroid Build Coastguard Worker     else
516*35238bceSAndroid Build Coastguard Worker         return values[3] + (values[1] - values[3]) * (1.0f - xFactor) + (values[2] - values[3]) * (1.0f - yFactor);
517*35238bceSAndroid Build Coastguard Worker }
518*35238bceSAndroid Build Coastguard Worker 
519*35238bceSAndroid Build Coastguard Worker template <int N>
computeTexCoordVecs(const vector<float> & texCoords,tcu::Vector<float,N> (& dst)[4])520*35238bceSAndroid Build Coastguard Worker static inline void computeTexCoordVecs(const vector<float> &texCoords, tcu::Vector<float, N> (&dst)[4])
521*35238bceSAndroid Build Coastguard Worker {
522*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((int)texCoords.size() == 4 * N);
523*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < 4; i++)
524*35238bceSAndroid Build Coastguard Worker         for (int j = 0; j < N; j++)
525*35238bceSAndroid Build Coastguard Worker             dst[i][j] = texCoords[i * N + j];
526*35238bceSAndroid Build Coastguard Worker }
527*35238bceSAndroid Build Coastguard Worker 
528*35238bceSAndroid Build Coastguard Worker #if defined(DE_DEBUG)
529*35238bceSAndroid Build Coastguard Worker // Whether offsets correspond to the sample offsets used with plain textureGather().
isZeroOffsetOffsets(const IVec2 (& offsets)[4])530*35238bceSAndroid Build Coastguard Worker static inline bool isZeroOffsetOffsets(const IVec2 (&offsets)[4])
531*35238bceSAndroid Build Coastguard Worker {
532*35238bceSAndroid Build Coastguard Worker     IVec2 ref[4];
533*35238bceSAndroid Build Coastguard Worker     SinglePixelOffsets(IVec2(0))(IVec2(), ref);
534*35238bceSAndroid Build Coastguard Worker     return std::equal(DE_ARRAY_BEGIN(offsets), DE_ARRAY_END(offsets), DE_ARRAY_BEGIN(ref));
535*35238bceSAndroid Build Coastguard Worker }
536*35238bceSAndroid Build Coastguard Worker #endif
537*35238bceSAndroid Build Coastguard Worker 
538*35238bceSAndroid Build Coastguard Worker template <typename ColorScalarType>
gatherOffsets(const tcu::Texture2DView & texture,const tcu::Sampler & sampler,const Vec2 & coord,int componentNdx,const IVec2 (& offsets)[4])539*35238bceSAndroid Build Coastguard Worker static tcu::Vector<ColorScalarType, 4> gatherOffsets(const tcu::Texture2DView &texture, const tcu::Sampler &sampler,
540*35238bceSAndroid Build Coastguard Worker                                                      const Vec2 &coord, int componentNdx, const IVec2 (&offsets)[4])
541*35238bceSAndroid Build Coastguard Worker {
542*35238bceSAndroid Build Coastguard Worker     return texture.gatherOffsets(sampler, coord.x(), coord.y(), componentNdx, offsets).cast<ColorScalarType>();
543*35238bceSAndroid Build Coastguard Worker }
544*35238bceSAndroid Build Coastguard Worker 
545*35238bceSAndroid Build Coastguard Worker template <typename ColorScalarType>
gatherOffsets(const tcu::Texture2DArrayView & texture,const tcu::Sampler & sampler,const Vec3 & coord,int componentNdx,const IVec2 (& offsets)[4])546*35238bceSAndroid Build Coastguard Worker static tcu::Vector<ColorScalarType, 4> gatherOffsets(const tcu::Texture2DArrayView &texture,
547*35238bceSAndroid Build Coastguard Worker                                                      const tcu::Sampler &sampler, const Vec3 &coord, int componentNdx,
548*35238bceSAndroid Build Coastguard Worker                                                      const IVec2 (&offsets)[4])
549*35238bceSAndroid Build Coastguard Worker {
550*35238bceSAndroid Build Coastguard Worker     return texture.gatherOffsets(sampler, coord.x(), coord.y(), coord.z(), componentNdx, offsets)
551*35238bceSAndroid Build Coastguard Worker         .cast<ColorScalarType>();
552*35238bceSAndroid Build Coastguard Worker }
553*35238bceSAndroid Build Coastguard Worker 
554*35238bceSAndroid Build Coastguard Worker template <typename ColorScalarType>
gatherOffsets(const tcu::TextureCubeView & texture,const tcu::Sampler & sampler,const Vec3 & coord,int componentNdx,const IVec2 (& offsets)[4])555*35238bceSAndroid Build Coastguard Worker static tcu::Vector<ColorScalarType, 4> gatherOffsets(const tcu::TextureCubeView &texture, const tcu::Sampler &sampler,
556*35238bceSAndroid Build Coastguard Worker                                                      const Vec3 &coord, int componentNdx, const IVec2 (&offsets)[4])
557*35238bceSAndroid Build Coastguard Worker {
558*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(isZeroOffsetOffsets(offsets));
559*35238bceSAndroid Build Coastguard Worker     DE_UNREF(offsets);
560*35238bceSAndroid Build Coastguard Worker     return texture.gather(sampler, coord.x(), coord.y(), coord.z(), componentNdx).cast<ColorScalarType>();
561*35238bceSAndroid Build Coastguard Worker }
562*35238bceSAndroid Build Coastguard Worker 
gatherOffsetsCompare(const tcu::Texture2DView & texture,const tcu::Sampler & sampler,float refZ,const Vec2 & coord,const IVec2 (& offsets)[4])563*35238bceSAndroid Build Coastguard Worker static Vec4 gatherOffsetsCompare(const tcu::Texture2DView &texture, const tcu::Sampler &sampler, float refZ,
564*35238bceSAndroid Build Coastguard Worker                                  const Vec2 &coord, const IVec2 (&offsets)[4])
565*35238bceSAndroid Build Coastguard Worker {
566*35238bceSAndroid Build Coastguard Worker     return texture.gatherOffsetsCompare(sampler, refZ, coord.x(), coord.y(), offsets);
567*35238bceSAndroid Build Coastguard Worker }
568*35238bceSAndroid Build Coastguard Worker 
gatherOffsetsCompare(const tcu::Texture2DArrayView & texture,const tcu::Sampler & sampler,float refZ,const Vec3 & coord,const IVec2 (& offsets)[4])569*35238bceSAndroid Build Coastguard Worker static Vec4 gatherOffsetsCompare(const tcu::Texture2DArrayView &texture, const tcu::Sampler &sampler, float refZ,
570*35238bceSAndroid Build Coastguard Worker                                  const Vec3 &coord, const IVec2 (&offsets)[4])
571*35238bceSAndroid Build Coastguard Worker {
572*35238bceSAndroid Build Coastguard Worker     return texture.gatherOffsetsCompare(sampler, refZ, coord.x(), coord.y(), coord.z(), offsets);
573*35238bceSAndroid Build Coastguard Worker }
574*35238bceSAndroid Build Coastguard Worker 
gatherOffsetsCompare(const tcu::TextureCubeView & texture,const tcu::Sampler & sampler,float refZ,const Vec3 & coord,const IVec2 (& offsets)[4])575*35238bceSAndroid Build Coastguard Worker static Vec4 gatherOffsetsCompare(const tcu::TextureCubeView &texture, const tcu::Sampler &sampler, float refZ,
576*35238bceSAndroid Build Coastguard Worker                                  const Vec3 &coord, const IVec2 (&offsets)[4])
577*35238bceSAndroid Build Coastguard Worker {
578*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(isZeroOffsetOffsets(offsets));
579*35238bceSAndroid Build Coastguard Worker     DE_UNREF(offsets);
580*35238bceSAndroid Build Coastguard Worker     return texture.gatherCompare(sampler, refZ, coord.x(), coord.y(), coord.z());
581*35238bceSAndroid Build Coastguard Worker }
582*35238bceSAndroid Build Coastguard Worker 
583*35238bceSAndroid Build Coastguard Worker template <typename PrecType, typename ColorScalarT>
isGatherOffsetsResultValid(const tcu::TextureCubeView & texture,const tcu::Sampler & sampler,const PrecType & prec,const Vec3 & coord,int componentNdx,const IVec2 (& offsets)[4],const tcu::Vector<ColorScalarT,4> & result)584*35238bceSAndroid Build Coastguard Worker static bool isGatherOffsetsResultValid(const tcu::TextureCubeView &texture, const tcu::Sampler &sampler,
585*35238bceSAndroid Build Coastguard Worker                                        const PrecType &prec, const Vec3 &coord, int componentNdx,
586*35238bceSAndroid Build Coastguard Worker                                        const IVec2 (&offsets)[4], const tcu::Vector<ColorScalarT, 4> &result)
587*35238bceSAndroid Build Coastguard Worker {
588*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(isZeroOffsetOffsets(offsets));
589*35238bceSAndroid Build Coastguard Worker     DE_UNREF(offsets);
590*35238bceSAndroid Build Coastguard Worker     return tcu::isGatherResultValid(texture, sampler, prec, coord, componentNdx, result);
591*35238bceSAndroid Build Coastguard Worker }
592*35238bceSAndroid Build Coastguard Worker 
isGatherOffsetsCompareResultValid(const tcu::TextureCubeView & texture,const tcu::Sampler & sampler,const tcu::TexComparePrecision & prec,const Vec3 & coord,const IVec2 (& offsets)[4],float cmpReference,const Vec4 & result)593*35238bceSAndroid Build Coastguard Worker static bool isGatherOffsetsCompareResultValid(const tcu::TextureCubeView &texture, const tcu::Sampler &sampler,
594*35238bceSAndroid Build Coastguard Worker                                               const tcu::TexComparePrecision &prec, const Vec3 &coord,
595*35238bceSAndroid Build Coastguard Worker                                               const IVec2 (&offsets)[4], float cmpReference, const Vec4 &result)
596*35238bceSAndroid Build Coastguard Worker {
597*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(isZeroOffsetOffsets(offsets));
598*35238bceSAndroid Build Coastguard Worker     DE_UNREF(offsets);
599*35238bceSAndroid Build Coastguard Worker     return tcu::isGatherCompareResultValid(texture, sampler, prec, coord, cmpReference, result);
600*35238bceSAndroid Build Coastguard Worker }
601*35238bceSAndroid Build Coastguard Worker 
602*35238bceSAndroid Build Coastguard Worker template <typename ColorScalarType, typename PrecType, typename TexViewT, typename TexCoordT>
verifyGatherOffsets(TestLog & log,const ConstPixelBufferAccess & result,const TexViewT & texture,const TexCoordT (& texCoords)[4],const tcu::Sampler & sampler,const PrecType & lookupPrec,int componentNdx,const PixelOffsets & getPixelOffsets)603*35238bceSAndroid Build Coastguard Worker static bool verifyGatherOffsets(TestLog &log, const ConstPixelBufferAccess &result, const TexViewT &texture,
604*35238bceSAndroid Build Coastguard Worker                                 const TexCoordT (&texCoords)[4], const tcu::Sampler &sampler,
605*35238bceSAndroid Build Coastguard Worker                                 const PrecType &lookupPrec, int componentNdx, const PixelOffsets &getPixelOffsets)
606*35238bceSAndroid Build Coastguard Worker {
607*35238bceSAndroid Build Coastguard Worker     typedef tcu::Vector<ColorScalarType, 4> ColorVec;
608*35238bceSAndroid Build Coastguard Worker 
609*35238bceSAndroid Build Coastguard Worker     const int width  = result.getWidth();
610*35238bceSAndroid Build Coastguard Worker     const int height = result.getWidth();
611*35238bceSAndroid Build Coastguard Worker     tcu::TextureLevel ideal(result.getFormat(), width, height);
612*35238bceSAndroid Build Coastguard Worker     const PixelBufferAccess idealAccess = ideal.getAccess();
613*35238bceSAndroid Build Coastguard Worker     tcu::Surface errorMask(width, height);
614*35238bceSAndroid Build Coastguard Worker     bool success = true;
615*35238bceSAndroid Build Coastguard Worker 
616*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toVec());
617*35238bceSAndroid Build Coastguard Worker 
618*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < height; py++)
619*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < width; px++)
620*35238bceSAndroid Build Coastguard Worker         {
621*35238bceSAndroid Build Coastguard Worker             IVec2 offsets[4];
622*35238bceSAndroid Build Coastguard Worker             getPixelOffsets(IVec2(px, py), offsets);
623*35238bceSAndroid Build Coastguard Worker 
624*35238bceSAndroid Build Coastguard Worker             const Vec2 viewportCoord = (Vec2((float)px, (float)py) + 0.5f) / Vec2((float)width, (float)height);
625*35238bceSAndroid Build Coastguard Worker             const TexCoordT texCoord = triQuadInterpolate(texCoords, viewportCoord.x(), viewportCoord.y());
626*35238bceSAndroid Build Coastguard Worker             const ColorVec resultPix = result.getPixelT<ColorScalarType>(px, py);
627*35238bceSAndroid Build Coastguard Worker             const ColorVec idealPix = gatherOffsets<ColorScalarType>(texture, sampler, texCoord, componentNdx, offsets);
628*35238bceSAndroid Build Coastguard Worker 
629*35238bceSAndroid Build Coastguard Worker             idealAccess.setPixel(idealPix, px, py);
630*35238bceSAndroid Build Coastguard Worker 
631*35238bceSAndroid Build Coastguard Worker             if (tcu::boolAny(
632*35238bceSAndroid Build Coastguard Worker                     tcu::logicalAnd(lookupPrec.colorMask,
633*35238bceSAndroid Build Coastguard Worker                                     tcu::greaterThan(tcu::absDiff(resultPix, idealPix),
634*35238bceSAndroid Build Coastguard Worker                                                      lookupPrec.colorThreshold.template cast<ColorScalarType>()))))
635*35238bceSAndroid Build Coastguard Worker             {
636*35238bceSAndroid Build Coastguard Worker                 if (!isGatherOffsetsResultValid(texture, sampler, lookupPrec, texCoord, componentNdx, offsets,
637*35238bceSAndroid Build Coastguard Worker                                                 resultPix))
638*35238bceSAndroid Build Coastguard Worker                 {
639*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(px, py, tcu::RGBA::red());
640*35238bceSAndroid Build Coastguard Worker                     success = false;
641*35238bceSAndroid Build Coastguard Worker                 }
642*35238bceSAndroid Build Coastguard Worker             }
643*35238bceSAndroid Build Coastguard Worker         }
644*35238bceSAndroid Build Coastguard Worker 
645*35238bceSAndroid Build Coastguard Worker     log << TestLog::ImageSet("VerifyResult", "Verification result")
646*35238bceSAndroid Build Coastguard Worker         << TestLog::Image("Rendered", "Rendered image", result);
647*35238bceSAndroid Build Coastguard Worker 
648*35238bceSAndroid Build Coastguard Worker     if (!success)
649*35238bceSAndroid Build Coastguard Worker     {
650*35238bceSAndroid Build Coastguard Worker         log << TestLog::Image("Reference", "Ideal reference image", ideal)
651*35238bceSAndroid Build Coastguard Worker             << TestLog::Image("ErrorMask", "Error mask", errorMask);
652*35238bceSAndroid Build Coastguard Worker     }
653*35238bceSAndroid Build Coastguard Worker 
654*35238bceSAndroid Build Coastguard Worker     log << TestLog::EndImageSet;
655*35238bceSAndroid Build Coastguard Worker 
656*35238bceSAndroid Build Coastguard Worker     return success;
657*35238bceSAndroid Build Coastguard Worker }
658*35238bceSAndroid Build Coastguard Worker 
659*35238bceSAndroid Build Coastguard Worker class PixelCompareRefZ
660*35238bceSAndroid Build Coastguard Worker {
661*35238bceSAndroid Build Coastguard Worker public:
662*35238bceSAndroid Build Coastguard Worker     virtual float operator()(const IVec2 &pixCoord) const = 0;
663*35238bceSAndroid Build Coastguard Worker };
664*35238bceSAndroid Build Coastguard Worker 
665*35238bceSAndroid Build Coastguard Worker class PixelCompareRefZDefault : public PixelCompareRefZ
666*35238bceSAndroid Build Coastguard Worker {
667*35238bceSAndroid Build Coastguard Worker public:
PixelCompareRefZDefault(const IVec2 & renderSize)668*35238bceSAndroid Build Coastguard Worker     PixelCompareRefZDefault(const IVec2 &renderSize) : m_renderSize(renderSize)
669*35238bceSAndroid Build Coastguard Worker     {
670*35238bceSAndroid Build Coastguard Worker     }
671*35238bceSAndroid Build Coastguard Worker 
operator ()(const IVec2 & pixCoord) const672*35238bceSAndroid Build Coastguard Worker     float operator()(const IVec2 &pixCoord) const
673*35238bceSAndroid Build Coastguard Worker     {
674*35238bceSAndroid Build Coastguard Worker         return ((float)pixCoord.x() + 0.5f) / (float)m_renderSize.x();
675*35238bceSAndroid Build Coastguard Worker     }
676*35238bceSAndroid Build Coastguard Worker 
677*35238bceSAndroid Build Coastguard Worker private:
678*35238bceSAndroid Build Coastguard Worker     IVec2 m_renderSize;
679*35238bceSAndroid Build Coastguard Worker };
680*35238bceSAndroid Build Coastguard Worker 
681*35238bceSAndroid Build Coastguard Worker template <typename TexViewT, typename TexCoordT>
verifyGatherOffsetsCompare(TestLog & log,const ConstPixelBufferAccess & result,const TexViewT & texture,const TexCoordT (& texCoords)[4],const tcu::Sampler & sampler,const tcu::TexComparePrecision & compPrec,const PixelCompareRefZ & getPixelRefZ,const PixelOffsets & getPixelOffsets)682*35238bceSAndroid Build Coastguard Worker static bool verifyGatherOffsetsCompare(TestLog &log, const ConstPixelBufferAccess &result, const TexViewT &texture,
683*35238bceSAndroid Build Coastguard Worker                                        const TexCoordT (&texCoords)[4], const tcu::Sampler &sampler,
684*35238bceSAndroid Build Coastguard Worker                                        const tcu::TexComparePrecision &compPrec, const PixelCompareRefZ &getPixelRefZ,
685*35238bceSAndroid Build Coastguard Worker                                        const PixelOffsets &getPixelOffsets)
686*35238bceSAndroid Build Coastguard Worker {
687*35238bceSAndroid Build Coastguard Worker     const int width  = result.getWidth();
688*35238bceSAndroid Build Coastguard Worker     const int height = result.getWidth();
689*35238bceSAndroid Build Coastguard Worker     tcu::Surface ideal(width, height);
690*35238bceSAndroid Build Coastguard Worker     const PixelBufferAccess idealAccess = ideal.getAccess();
691*35238bceSAndroid Build Coastguard Worker     tcu::Surface errorMask(width, height);
692*35238bceSAndroid Build Coastguard Worker     bool success = true;
693*35238bceSAndroid Build Coastguard Worker 
694*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toVec());
695*35238bceSAndroid Build Coastguard Worker 
696*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < height; py++)
697*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < width; px++)
698*35238bceSAndroid Build Coastguard Worker         {
699*35238bceSAndroid Build Coastguard Worker             IVec2 offsets[4];
700*35238bceSAndroid Build Coastguard Worker             getPixelOffsets(IVec2(px, py), offsets);
701*35238bceSAndroid Build Coastguard Worker 
702*35238bceSAndroid Build Coastguard Worker             const Vec2 viewportCoord = (Vec2((float)px, (float)py) + 0.5f) / Vec2((float)width, (float)height);
703*35238bceSAndroid Build Coastguard Worker             const TexCoordT texCoord = triQuadInterpolate(texCoords, viewportCoord.x(), viewportCoord.y());
704*35238bceSAndroid Build Coastguard Worker             const float refZ         = getPixelRefZ(IVec2(px, py));
705*35238bceSAndroid Build Coastguard Worker             const Vec4 resultPix     = result.getPixel(px, py);
706*35238bceSAndroid Build Coastguard Worker             const Vec4 idealPix      = gatherOffsetsCompare(texture, sampler, refZ, texCoord, offsets);
707*35238bceSAndroid Build Coastguard Worker 
708*35238bceSAndroid Build Coastguard Worker             idealAccess.setPixel(idealPix, px, py);
709*35238bceSAndroid Build Coastguard Worker 
710*35238bceSAndroid Build Coastguard Worker             if (!tcu::boolAll(tcu::equal(resultPix, idealPix)))
711*35238bceSAndroid Build Coastguard Worker             {
712*35238bceSAndroid Build Coastguard Worker                 if (!isGatherOffsetsCompareResultValid(texture, sampler, compPrec, texCoord, offsets, refZ, resultPix))
713*35238bceSAndroid Build Coastguard Worker                 {
714*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(px, py, tcu::RGBA::red());
715*35238bceSAndroid Build Coastguard Worker                     success = false;
716*35238bceSAndroid Build Coastguard Worker                 }
717*35238bceSAndroid Build Coastguard Worker             }
718*35238bceSAndroid Build Coastguard Worker         }
719*35238bceSAndroid Build Coastguard Worker 
720*35238bceSAndroid Build Coastguard Worker     log << TestLog::ImageSet("VerifyResult", "Verification result")
721*35238bceSAndroid Build Coastguard Worker         << TestLog::Image("Rendered", "Rendered image", result);
722*35238bceSAndroid Build Coastguard Worker 
723*35238bceSAndroid Build Coastguard Worker     if (!success)
724*35238bceSAndroid Build Coastguard Worker     {
725*35238bceSAndroid Build Coastguard Worker         log << TestLog::Image("Reference", "Ideal reference image", ideal)
726*35238bceSAndroid Build Coastguard Worker             << TestLog::Image("ErrorMask", "Error mask", errorMask);
727*35238bceSAndroid Build Coastguard Worker     }
728*35238bceSAndroid Build Coastguard Worker 
729*35238bceSAndroid Build Coastguard Worker     log << TestLog::EndImageSet;
730*35238bceSAndroid Build Coastguard Worker 
731*35238bceSAndroid Build Coastguard Worker     return success;
732*35238bceSAndroid Build Coastguard Worker }
733*35238bceSAndroid Build Coastguard Worker 
verifySingleColored(TestLog & log,const ConstPixelBufferAccess & result,const Vec4 & refColor)734*35238bceSAndroid Build Coastguard Worker static bool verifySingleColored(TestLog &log, const ConstPixelBufferAccess &result, const Vec4 &refColor)
735*35238bceSAndroid Build Coastguard Worker {
736*35238bceSAndroid Build Coastguard Worker     const int width  = result.getWidth();
737*35238bceSAndroid Build Coastguard Worker     const int height = result.getWidth();
738*35238bceSAndroid Build Coastguard Worker     tcu::Surface ideal(width, height);
739*35238bceSAndroid Build Coastguard Worker     const PixelBufferAccess idealAccess = ideal.getAccess();
740*35238bceSAndroid Build Coastguard Worker     tcu::Surface errorMask(width, height);
741*35238bceSAndroid Build Coastguard Worker     bool success = true;
742*35238bceSAndroid Build Coastguard Worker 
743*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask.getAccess(), tcu::RGBA::green().toVec());
744*35238bceSAndroid Build Coastguard Worker     tcu::clear(idealAccess, refColor);
745*35238bceSAndroid Build Coastguard Worker 
746*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < height; py++)
747*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < width; px++)
748*35238bceSAndroid Build Coastguard Worker         {
749*35238bceSAndroid Build Coastguard Worker             if (result.getPixel(px, py) != refColor)
750*35238bceSAndroid Build Coastguard Worker             {
751*35238bceSAndroid Build Coastguard Worker                 errorMask.setPixel(px, py, tcu::RGBA::red());
752*35238bceSAndroid Build Coastguard Worker                 success = false;
753*35238bceSAndroid Build Coastguard Worker             }
754*35238bceSAndroid Build Coastguard Worker         }
755*35238bceSAndroid Build Coastguard Worker 
756*35238bceSAndroid Build Coastguard Worker     log << TestLog::ImageSet("VerifyResult", "Verification result")
757*35238bceSAndroid Build Coastguard Worker         << TestLog::Image("Rendered", "Rendered image", result);
758*35238bceSAndroid Build Coastguard Worker 
759*35238bceSAndroid Build Coastguard Worker     if (!success)
760*35238bceSAndroid Build Coastguard Worker     {
761*35238bceSAndroid Build Coastguard Worker         log << TestLog::Image("Reference", "Ideal reference image", ideal)
762*35238bceSAndroid Build Coastguard Worker             << TestLog::Image("ErrorMask", "Error mask", errorMask);
763*35238bceSAndroid Build Coastguard Worker     }
764*35238bceSAndroid Build Coastguard Worker 
765*35238bceSAndroid Build Coastguard Worker     log << TestLog::EndImageSet;
766*35238bceSAndroid Build Coastguard Worker 
767*35238bceSAndroid Build Coastguard Worker     return success;
768*35238bceSAndroid Build Coastguard Worker }
769*35238bceSAndroid Build Coastguard Worker 
770*35238bceSAndroid Build Coastguard Worker enum GatherType
771*35238bceSAndroid Build Coastguard Worker {
772*35238bceSAndroid Build Coastguard Worker     GATHERTYPE_BASIC = 0,
773*35238bceSAndroid Build Coastguard Worker     GATHERTYPE_OFFSET,
774*35238bceSAndroid Build Coastguard Worker     GATHERTYPE_OFFSET_DYNAMIC,
775*35238bceSAndroid Build Coastguard Worker     GATHERTYPE_OFFSETS,
776*35238bceSAndroid Build Coastguard Worker 
777*35238bceSAndroid Build Coastguard Worker     GATHERTYPE_LAST
778*35238bceSAndroid Build Coastguard Worker };
779*35238bceSAndroid Build Coastguard Worker 
780*35238bceSAndroid Build Coastguard Worker enum GatherCaseFlags
781*35238bceSAndroid Build Coastguard Worker {
782*35238bceSAndroid Build Coastguard Worker     GATHERCASE_MIPMAP_INCOMPLETE        = (1 << 0), //!< Excercise special case of sampling mipmap-incomplete texture
783*35238bceSAndroid Build Coastguard Worker     GATHERCASE_DONT_SAMPLE_CUBE_CORNERS = (1 << 1)  //!< For cube map cases: do not sample cube corners
784*35238bceSAndroid Build Coastguard Worker };
785*35238bceSAndroid Build Coastguard Worker 
gatherTypeName(GatherType type)786*35238bceSAndroid Build Coastguard Worker static inline const char *gatherTypeName(GatherType type)
787*35238bceSAndroid Build Coastguard Worker {
788*35238bceSAndroid Build Coastguard Worker     switch (type)
789*35238bceSAndroid Build Coastguard Worker     {
790*35238bceSAndroid Build Coastguard Worker     case GATHERTYPE_BASIC:
791*35238bceSAndroid Build Coastguard Worker         return "basic";
792*35238bceSAndroid Build Coastguard Worker     case GATHERTYPE_OFFSET:
793*35238bceSAndroid Build Coastguard Worker         return "offset";
794*35238bceSAndroid Build Coastguard Worker     case GATHERTYPE_OFFSET_DYNAMIC:
795*35238bceSAndroid Build Coastguard Worker         return "offset_dynamic";
796*35238bceSAndroid Build Coastguard Worker     case GATHERTYPE_OFFSETS:
797*35238bceSAndroid Build Coastguard Worker         return "offsets";
798*35238bceSAndroid Build Coastguard Worker     default:
799*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
800*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
801*35238bceSAndroid Build Coastguard Worker     }
802*35238bceSAndroid Build Coastguard Worker }
803*35238bceSAndroid Build Coastguard Worker 
gatherTypeDescription(GatherType type)804*35238bceSAndroid Build Coastguard Worker static inline const char *gatherTypeDescription(GatherType type)
805*35238bceSAndroid Build Coastguard Worker {
806*35238bceSAndroid Build Coastguard Worker     switch (type)
807*35238bceSAndroid Build Coastguard Worker     {
808*35238bceSAndroid Build Coastguard Worker     case GATHERTYPE_BASIC:
809*35238bceSAndroid Build Coastguard Worker         return "textureGather";
810*35238bceSAndroid Build Coastguard Worker     case GATHERTYPE_OFFSET:
811*35238bceSAndroid Build Coastguard Worker         return "textureGatherOffset";
812*35238bceSAndroid Build Coastguard Worker     case GATHERTYPE_OFFSET_DYNAMIC:
813*35238bceSAndroid Build Coastguard Worker         return "textureGatherOffset with dynamic offsets";
814*35238bceSAndroid Build Coastguard Worker     case GATHERTYPE_OFFSETS:
815*35238bceSAndroid Build Coastguard Worker         return "textureGatherOffsets";
816*35238bceSAndroid Build Coastguard Worker     default:
817*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
818*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
819*35238bceSAndroid Build Coastguard Worker     }
820*35238bceSAndroid Build Coastguard Worker }
821*35238bceSAndroid Build Coastguard Worker 
requireGpuShader5(GatherType gatherType)822*35238bceSAndroid Build Coastguard Worker static inline bool requireGpuShader5(GatherType gatherType)
823*35238bceSAndroid Build Coastguard Worker {
824*35238bceSAndroid Build Coastguard Worker     return gatherType == GATHERTYPE_OFFSET_DYNAMIC || gatherType == GATHERTYPE_OFFSETS;
825*35238bceSAndroid Build Coastguard Worker }
826*35238bceSAndroid Build Coastguard Worker 
827*35238bceSAndroid Build Coastguard Worker struct GatherArgs
828*35238bceSAndroid Build Coastguard Worker {
829*35238bceSAndroid Build Coastguard Worker     int componentNdx; // If negative, implicit component index 0 is used (i.e. the parameter is not given).
830*35238bceSAndroid Build Coastguard Worker     IVec2 offsets
831*35238bceSAndroid Build Coastguard Worker         [4]; // \note Unless GATHERTYPE_OFFSETS is used, only offsets[0] is relevant; also, for GATHERTYPE_OFFSET_DYNAMIC, none are relevant.
832*35238bceSAndroid Build Coastguard Worker 
GatherArgsdeqp::gles31::Functional::__anon1bb6c87a0111::GatherArgs833*35238bceSAndroid Build Coastguard Worker     GatherArgs(void) : componentNdx(-1)
834*35238bceSAndroid Build Coastguard Worker     {
835*35238bceSAndroid Build Coastguard Worker         std::fill(DE_ARRAY_BEGIN(offsets), DE_ARRAY_END(offsets), IVec2());
836*35238bceSAndroid Build Coastguard Worker     }
837*35238bceSAndroid Build Coastguard Worker 
GatherArgsdeqp::gles31::Functional::__anon1bb6c87a0111::GatherArgs838*35238bceSAndroid Build Coastguard Worker     GatherArgs(int comp, const IVec2 &off0 = IVec2(), const IVec2 &off1 = IVec2(), const IVec2 &off2 = IVec2(),
839*35238bceSAndroid Build Coastguard Worker                const IVec2 &off3 = IVec2())
840*35238bceSAndroid Build Coastguard Worker         : componentNdx(comp)
841*35238bceSAndroid Build Coastguard Worker     {
842*35238bceSAndroid Build Coastguard Worker         offsets[0] = off0;
843*35238bceSAndroid Build Coastguard Worker         offsets[1] = off1;
844*35238bceSAndroid Build Coastguard Worker         offsets[2] = off2;
845*35238bceSAndroid Build Coastguard Worker         offsets[3] = off3;
846*35238bceSAndroid Build Coastguard Worker     }
847*35238bceSAndroid Build Coastguard Worker };
848*35238bceSAndroid Build Coastguard Worker 
makePixelOffsetsFunctor(GatherType gatherType,const GatherArgs & gatherArgs,const IVec2 & offsetRange)849*35238bceSAndroid Build Coastguard Worker static MovePtr<PixelOffsets> makePixelOffsetsFunctor(GatherType gatherType, const GatherArgs &gatherArgs,
850*35238bceSAndroid Build Coastguard Worker                                                      const IVec2 &offsetRange)
851*35238bceSAndroid Build Coastguard Worker {
852*35238bceSAndroid Build Coastguard Worker     if (gatherType == GATHERTYPE_BASIC || gatherType == GATHERTYPE_OFFSET)
853*35238bceSAndroid Build Coastguard Worker     {
854*35238bceSAndroid Build Coastguard Worker         const IVec2 offset = gatherType == GATHERTYPE_BASIC ? IVec2(0) : gatherArgs.offsets[0];
855*35238bceSAndroid Build Coastguard Worker         return MovePtr<PixelOffsets>(new SinglePixelOffsets(offset));
856*35238bceSAndroid Build Coastguard Worker     }
857*35238bceSAndroid Build Coastguard Worker     else if (gatherType == GATHERTYPE_OFFSET_DYNAMIC)
858*35238bceSAndroid Build Coastguard Worker     {
859*35238bceSAndroid Build Coastguard Worker         return MovePtr<PixelOffsets>(new DynamicSinglePixelOffsets(offsetRange));
860*35238bceSAndroid Build Coastguard Worker     }
861*35238bceSAndroid Build Coastguard Worker     else if (gatherType == GATHERTYPE_OFFSETS)
862*35238bceSAndroid Build Coastguard Worker         return MovePtr<PixelOffsets>(new MultiplePixelOffsets(gatherArgs.offsets[0], gatherArgs.offsets[1],
863*35238bceSAndroid Build Coastguard Worker                                                               gatherArgs.offsets[2], gatherArgs.offsets[3]));
864*35238bceSAndroid Build Coastguard Worker     else
865*35238bceSAndroid Build Coastguard Worker     {
866*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
867*35238bceSAndroid Build Coastguard Worker         return MovePtr<PixelOffsets>(DE_NULL);
868*35238bceSAndroid Build Coastguard Worker     }
869*35238bceSAndroid Build Coastguard Worker }
870*35238bceSAndroid Build Coastguard Worker 
getSamplerType(TextureType textureType,const tcu::TextureFormat & format)871*35238bceSAndroid Build Coastguard Worker static inline glu::DataType getSamplerType(TextureType textureType, const tcu::TextureFormat &format)
872*35238bceSAndroid Build Coastguard Worker {
873*35238bceSAndroid Build Coastguard Worker     if (isDepthFormat(format))
874*35238bceSAndroid Build Coastguard Worker     {
875*35238bceSAndroid Build Coastguard Worker         switch (textureType)
876*35238bceSAndroid Build Coastguard Worker         {
877*35238bceSAndroid Build Coastguard Worker         case TEXTURETYPE_2D:
878*35238bceSAndroid Build Coastguard Worker             return glu::TYPE_SAMPLER_2D_SHADOW;
879*35238bceSAndroid Build Coastguard Worker         case TEXTURETYPE_2D_ARRAY:
880*35238bceSAndroid Build Coastguard Worker             return glu::TYPE_SAMPLER_2D_ARRAY_SHADOW;
881*35238bceSAndroid Build Coastguard Worker         case TEXTURETYPE_CUBE:
882*35238bceSAndroid Build Coastguard Worker             return glu::TYPE_SAMPLER_CUBE_SHADOW;
883*35238bceSAndroid Build Coastguard Worker         default:
884*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
885*35238bceSAndroid Build Coastguard Worker             return glu::TYPE_LAST;
886*35238bceSAndroid Build Coastguard Worker         }
887*35238bceSAndroid Build Coastguard Worker     }
888*35238bceSAndroid Build Coastguard Worker     else
889*35238bceSAndroid Build Coastguard Worker     {
890*35238bceSAndroid Build Coastguard Worker         switch (textureType)
891*35238bceSAndroid Build Coastguard Worker         {
892*35238bceSAndroid Build Coastguard Worker         case TEXTURETYPE_2D:
893*35238bceSAndroid Build Coastguard Worker             return glu::getSampler2DType(format);
894*35238bceSAndroid Build Coastguard Worker         case TEXTURETYPE_2D_ARRAY:
895*35238bceSAndroid Build Coastguard Worker             return glu::getSampler2DArrayType(format);
896*35238bceSAndroid Build Coastguard Worker         case TEXTURETYPE_CUBE:
897*35238bceSAndroid Build Coastguard Worker             return glu::getSamplerCubeType(format);
898*35238bceSAndroid Build Coastguard Worker         default:
899*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
900*35238bceSAndroid Build Coastguard Worker             return glu::TYPE_LAST;
901*35238bceSAndroid Build Coastguard Worker         }
902*35238bceSAndroid Build Coastguard Worker     }
903*35238bceSAndroid Build Coastguard Worker }
904*35238bceSAndroid Build Coastguard Worker 
getSamplerGatherResultType(glu::DataType samplerType)905*35238bceSAndroid Build Coastguard Worker static inline glu::DataType getSamplerGatherResultType(glu::DataType samplerType)
906*35238bceSAndroid Build Coastguard Worker {
907*35238bceSAndroid Build Coastguard Worker     switch (samplerType)
908*35238bceSAndroid Build Coastguard Worker     {
909*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_2D_SHADOW:
910*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW:
911*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_CUBE_SHADOW:
912*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_2D:
913*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_2D_ARRAY:
914*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_SAMPLER_CUBE:
915*35238bceSAndroid Build Coastguard Worker         return glu::TYPE_FLOAT_VEC4;
916*35238bceSAndroid Build Coastguard Worker 
917*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_INT_SAMPLER_2D:
918*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_INT_SAMPLER_2D_ARRAY:
919*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_INT_SAMPLER_CUBE:
920*35238bceSAndroid Build Coastguard Worker         return glu::TYPE_INT_VEC4;
921*35238bceSAndroid Build Coastguard Worker 
922*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_UINT_SAMPLER_2D:
923*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
924*35238bceSAndroid Build Coastguard Worker     case glu::TYPE_UINT_SAMPLER_CUBE:
925*35238bceSAndroid Build Coastguard Worker         return glu::TYPE_UINT_VEC4;
926*35238bceSAndroid Build Coastguard Worker 
927*35238bceSAndroid Build Coastguard Worker     default:
928*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
929*35238bceSAndroid Build Coastguard Worker         return glu::TYPE_LAST;
930*35238bceSAndroid Build Coastguard Worker     }
931*35238bceSAndroid Build Coastguard Worker }
932*35238bceSAndroid Build Coastguard Worker 
getNumTextureSamplingDimensions(TextureType type)933*35238bceSAndroid Build Coastguard Worker static inline int getNumTextureSamplingDimensions(TextureType type)
934*35238bceSAndroid Build Coastguard Worker {
935*35238bceSAndroid Build Coastguard Worker     switch (type)
936*35238bceSAndroid Build Coastguard Worker     {
937*35238bceSAndroid Build Coastguard Worker     case TEXTURETYPE_2D:
938*35238bceSAndroid Build Coastguard Worker         return 2;
939*35238bceSAndroid Build Coastguard Worker     case TEXTURETYPE_2D_ARRAY:
940*35238bceSAndroid Build Coastguard Worker         return 3;
941*35238bceSAndroid Build Coastguard Worker     case TEXTURETYPE_CUBE:
942*35238bceSAndroid Build Coastguard Worker         return 3;
943*35238bceSAndroid Build Coastguard Worker     default:
944*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
945*35238bceSAndroid Build Coastguard Worker         return -1;
946*35238bceSAndroid Build Coastguard Worker     }
947*35238bceSAndroid Build Coastguard Worker }
948*35238bceSAndroid Build Coastguard Worker 
getGLTextureType(TextureType type)949*35238bceSAndroid Build Coastguard Worker static uint32_t getGLTextureType(TextureType type)
950*35238bceSAndroid Build Coastguard Worker {
951*35238bceSAndroid Build Coastguard Worker     switch (type)
952*35238bceSAndroid Build Coastguard Worker     {
953*35238bceSAndroid Build Coastguard Worker     case TEXTURETYPE_2D:
954*35238bceSAndroid Build Coastguard Worker         return GL_TEXTURE_2D;
955*35238bceSAndroid Build Coastguard Worker     case TEXTURETYPE_2D_ARRAY:
956*35238bceSAndroid Build Coastguard Worker         return GL_TEXTURE_2D_ARRAY;
957*35238bceSAndroid Build Coastguard Worker     case TEXTURETYPE_CUBE:
958*35238bceSAndroid Build Coastguard Worker         return GL_TEXTURE_CUBE_MAP;
959*35238bceSAndroid Build Coastguard Worker     default:
960*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
961*35238bceSAndroid Build Coastguard Worker         return (uint32_t)-1;
962*35238bceSAndroid Build Coastguard Worker     }
963*35238bceSAndroid Build Coastguard Worker }
964*35238bceSAndroid Build Coastguard Worker 
965*35238bceSAndroid Build Coastguard Worker enum OffsetSize
966*35238bceSAndroid Build Coastguard Worker {
967*35238bceSAndroid Build Coastguard Worker     OFFSETSIZE_NONE = 0,
968*35238bceSAndroid Build Coastguard Worker     OFFSETSIZE_MINIMUM_REQUIRED,
969*35238bceSAndroid Build Coastguard Worker     OFFSETSIZE_IMPLEMENTATION_MAXIMUM,
970*35238bceSAndroid Build Coastguard Worker 
971*35238bceSAndroid Build Coastguard Worker     OFFSETSIZE_LAST
972*35238bceSAndroid Build Coastguard Worker };
973*35238bceSAndroid Build Coastguard Worker 
isMipmapFilter(tcu::Sampler::FilterMode filter)974*35238bceSAndroid Build Coastguard Worker static inline bool isMipmapFilter(tcu::Sampler::FilterMode filter)
975*35238bceSAndroid Build Coastguard Worker {
976*35238bceSAndroid Build Coastguard Worker     switch (filter)
977*35238bceSAndroid Build Coastguard Worker     {
978*35238bceSAndroid Build Coastguard Worker     case tcu::Sampler::NEAREST:
979*35238bceSAndroid Build Coastguard Worker     case tcu::Sampler::LINEAR:
980*35238bceSAndroid Build Coastguard Worker         return false;
981*35238bceSAndroid Build Coastguard Worker 
982*35238bceSAndroid Build Coastguard Worker     case tcu::Sampler::NEAREST_MIPMAP_NEAREST:
983*35238bceSAndroid Build Coastguard Worker     case tcu::Sampler::NEAREST_MIPMAP_LINEAR:
984*35238bceSAndroid Build Coastguard Worker     case tcu::Sampler::LINEAR_MIPMAP_NEAREST:
985*35238bceSAndroid Build Coastguard Worker     case tcu::Sampler::LINEAR_MIPMAP_LINEAR:
986*35238bceSAndroid Build Coastguard Worker         return true;
987*35238bceSAndroid Build Coastguard Worker 
988*35238bceSAndroid Build Coastguard Worker     default:
989*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
990*35238bceSAndroid Build Coastguard Worker         return false;
991*35238bceSAndroid Build Coastguard Worker     }
992*35238bceSAndroid Build Coastguard Worker }
993*35238bceSAndroid Build Coastguard Worker 
994*35238bceSAndroid Build Coastguard Worker class TextureGatherCase : public TestCase
995*35238bceSAndroid Build Coastguard Worker {
996*35238bceSAndroid Build Coastguard Worker public:
997*35238bceSAndroid Build Coastguard Worker     TextureGatherCase(Context &context, const char *name, const char *description, TextureType textureType,
998*35238bceSAndroid Build Coastguard Worker                       GatherType gatherType, OffsetSize offsetSize, tcu::TextureFormat textureFormat,
999*35238bceSAndroid Build Coastguard Worker                       tcu::Sampler::CompareMode
1000*35238bceSAndroid Build Coastguard Worker                           shadowCompareMode, //!< Should be COMPAREMODE_NONE iff textureFormat is a depth format.
1001*35238bceSAndroid Build Coastguard Worker                       tcu::Sampler::WrapMode wrapS, tcu::Sampler::WrapMode wrapT, const MaybeTextureSwizzle &texSwizzle,
1002*35238bceSAndroid Build Coastguard Worker                       // \note Filter modes have no effect on gather (except when it comes to
1003*35238bceSAndroid Build Coastguard Worker                       //          texture completeness); these are supposed to test just that.
1004*35238bceSAndroid Build Coastguard Worker                       tcu::Sampler::FilterMode minFilter, tcu::Sampler::FilterMode magFilter, int baseLevel,
1005*35238bceSAndroid Build Coastguard Worker                       uint32_t flags);
1006*35238bceSAndroid Build Coastguard Worker 
1007*35238bceSAndroid Build Coastguard Worker     void init(void);
1008*35238bceSAndroid Build Coastguard Worker     void deinit(void);
1009*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
1010*35238bceSAndroid Build Coastguard Worker 
1011*35238bceSAndroid Build Coastguard Worker protected:
1012*35238bceSAndroid Build Coastguard Worker     IVec2 getOffsetRange(void) const;
1013*35238bceSAndroid Build Coastguard Worker 
1014*35238bceSAndroid Build Coastguard Worker     template <typename TexViewT, typename TexCoordT>
1015*35238bceSAndroid Build Coastguard Worker     bool verify(const ConstPixelBufferAccess &rendered, const TexViewT &texture, const TexCoordT (&bottomLeft)[4],
1016*35238bceSAndroid Build Coastguard Worker                 const GatherArgs &gatherArgs) const;
1017*35238bceSAndroid Build Coastguard Worker 
1018*35238bceSAndroid Build Coastguard Worker     virtual void generateIterations(void)                                               = 0;
1019*35238bceSAndroid Build Coastguard Worker     virtual void createAndUploadTexture(void)                                           = 0;
1020*35238bceSAndroid Build Coastguard Worker     virtual int getNumIterations(void) const                                            = 0;
1021*35238bceSAndroid Build Coastguard Worker     virtual GatherArgs getGatherArgs(int iterationNdx) const                            = 0;
1022*35238bceSAndroid Build Coastguard Worker     virtual vector<float> computeQuadTexCoord(int iterationNdx) const                   = 0;
1023*35238bceSAndroid Build Coastguard Worker     virtual bool verify(int iterationNdx, const ConstPixelBufferAccess &rendered) const = 0;
1024*35238bceSAndroid Build Coastguard Worker 
1025*35238bceSAndroid Build Coastguard Worker     const GatherType m_gatherType;
1026*35238bceSAndroid Build Coastguard Worker     const OffsetSize m_offsetSize;
1027*35238bceSAndroid Build Coastguard Worker     const tcu::TextureFormat m_textureFormat;
1028*35238bceSAndroid Build Coastguard Worker     const tcu::Sampler::CompareMode m_shadowCompareMode;
1029*35238bceSAndroid Build Coastguard Worker     const tcu::Sampler::WrapMode m_wrapS;
1030*35238bceSAndroid Build Coastguard Worker     const tcu::Sampler::WrapMode m_wrapT;
1031*35238bceSAndroid Build Coastguard Worker     const MaybeTextureSwizzle m_textureSwizzle;
1032*35238bceSAndroid Build Coastguard Worker     const tcu::Sampler::FilterMode m_minFilter;
1033*35238bceSAndroid Build Coastguard Worker     const tcu::Sampler::FilterMode m_magFilter;
1034*35238bceSAndroid Build Coastguard Worker     const int m_baseLevel;
1035*35238bceSAndroid Build Coastguard Worker     const uint32_t m_flags;
1036*35238bceSAndroid Build Coastguard Worker 
1037*35238bceSAndroid Build Coastguard Worker private:
1038*35238bceSAndroid Build Coastguard Worker     enum
1039*35238bceSAndroid Build Coastguard Worker     {
1040*35238bceSAndroid Build Coastguard Worker         SPEC_MAX_MIN_OFFSET = -8,
1041*35238bceSAndroid Build Coastguard Worker         SPEC_MIN_MAX_OFFSET = 7
1042*35238bceSAndroid Build Coastguard Worker     };
1043*35238bceSAndroid Build Coastguard Worker 
1044*35238bceSAndroid Build Coastguard Worker     static const IVec2 RENDER_SIZE;
1045*35238bceSAndroid Build Coastguard Worker 
1046*35238bceSAndroid Build Coastguard Worker     glu::VertexSource genVertexShaderSource(bool requireGpuShader5, int numTexCoordComponents,
1047*35238bceSAndroid Build Coastguard Worker                                             bool useNormalizedCoordInput);
1048*35238bceSAndroid Build Coastguard Worker     glu::FragmentSource genFragmentShaderSource(bool requireGpuShader5, int numTexCoordComponents,
1049*35238bceSAndroid Build Coastguard Worker                                                 glu::DataType samplerType, const string &funcCall,
1050*35238bceSAndroid Build Coastguard Worker                                                 bool useNormalizedCoordInput, bool usePixCoord);
1051*35238bceSAndroid Build Coastguard Worker     string genGatherFuncCall(GatherType, const tcu::TextureFormat &, const GatherArgs &, const string &refZExpr,
1052*35238bceSAndroid Build Coastguard Worker                              const IVec2 &offsetRange, int indentationDepth);
1053*35238bceSAndroid Build Coastguard Worker     glu::ProgramSources genProgramSources(GatherType, TextureType, const tcu::TextureFormat &, const GatherArgs &,
1054*35238bceSAndroid Build Coastguard Worker                                           const string &refZExpr, const IVec2 &offsetRange);
1055*35238bceSAndroid Build Coastguard Worker 
1056*35238bceSAndroid Build Coastguard Worker     const TextureType m_textureType;
1057*35238bceSAndroid Build Coastguard Worker 
1058*35238bceSAndroid Build Coastguard Worker     const tcu::TextureFormat m_colorBufferFormat;
1059*35238bceSAndroid Build Coastguard Worker     MovePtr<glu::Renderbuffer> m_colorBuffer;
1060*35238bceSAndroid Build Coastguard Worker     MovePtr<glu::Framebuffer> m_fbo;
1061*35238bceSAndroid Build Coastguard Worker 
1062*35238bceSAndroid Build Coastguard Worker     int m_currentIteration;
1063*35238bceSAndroid Build Coastguard Worker     MovePtr<ShaderProgram> m_program;
1064*35238bceSAndroid Build Coastguard Worker };
1065*35238bceSAndroid Build Coastguard Worker 
1066*35238bceSAndroid Build Coastguard Worker const IVec2 TextureGatherCase::RENDER_SIZE = IVec2(64, 64);
1067*35238bceSAndroid Build Coastguard Worker 
TextureGatherCase(Context & context,const char * name,const char * description,TextureType textureType,GatherType gatherType,OffsetSize offsetSize,tcu::TextureFormat textureFormat,tcu::Sampler::CompareMode shadowCompareMode,tcu::Sampler::WrapMode wrapS,tcu::Sampler::WrapMode wrapT,const MaybeTextureSwizzle & textureSwizzle,tcu::Sampler::FilterMode minFilter,tcu::Sampler::FilterMode magFilter,int baseLevel,uint32_t flags)1068*35238bceSAndroid Build Coastguard Worker TextureGatherCase::TextureGatherCase(
1069*35238bceSAndroid Build Coastguard Worker     Context &context, const char *name, const char *description, TextureType textureType, GatherType gatherType,
1070*35238bceSAndroid Build Coastguard Worker     OffsetSize offsetSize, tcu::TextureFormat textureFormat,
1071*35238bceSAndroid Build Coastguard Worker     tcu::Sampler::CompareMode shadowCompareMode, //!< Should be COMPAREMODE_NONE iff textureType == TEXTURETYPE_NORMAL.
1072*35238bceSAndroid Build Coastguard Worker     tcu::Sampler::WrapMode wrapS, tcu::Sampler::WrapMode wrapT, const MaybeTextureSwizzle &textureSwizzle,
1073*35238bceSAndroid Build Coastguard Worker     tcu::Sampler::FilterMode minFilter, tcu::Sampler::FilterMode magFilter, int baseLevel, uint32_t flags)
1074*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
1075*35238bceSAndroid Build Coastguard Worker     , m_gatherType(gatherType)
1076*35238bceSAndroid Build Coastguard Worker     , m_offsetSize(offsetSize)
1077*35238bceSAndroid Build Coastguard Worker     , m_textureFormat(textureFormat)
1078*35238bceSAndroid Build Coastguard Worker     , m_shadowCompareMode(shadowCompareMode)
1079*35238bceSAndroid Build Coastguard Worker     , m_wrapS(wrapS)
1080*35238bceSAndroid Build Coastguard Worker     , m_wrapT(wrapT)
1081*35238bceSAndroid Build Coastguard Worker     , m_textureSwizzle(textureSwizzle)
1082*35238bceSAndroid Build Coastguard Worker     , m_minFilter(minFilter)
1083*35238bceSAndroid Build Coastguard Worker     , m_magFilter(magFilter)
1084*35238bceSAndroid Build Coastguard Worker     , m_baseLevel(baseLevel)
1085*35238bceSAndroid Build Coastguard Worker     , m_flags(flags)
1086*35238bceSAndroid Build Coastguard Worker     , m_textureType(textureType)
1087*35238bceSAndroid Build Coastguard Worker     , m_colorBufferFormat(tcu::TextureFormat(
1088*35238bceSAndroid Build Coastguard Worker           tcu::TextureFormat::RGBA, isDepthFormat(textureFormat) ? tcu::TextureFormat::UNORM_INT8 : textureFormat.type))
1089*35238bceSAndroid Build Coastguard Worker     , m_currentIteration(0)
1090*35238bceSAndroid Build Coastguard Worker {
1091*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((m_gatherType == GATHERTYPE_BASIC) == (m_offsetSize == OFFSETSIZE_NONE));
1092*35238bceSAndroid Build Coastguard Worker     DE_ASSERT((m_shadowCompareMode != tcu::Sampler::COMPAREMODE_NONE) == isDepthFormat(m_textureFormat));
1093*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(isUnormFormatType(m_colorBufferFormat.type) ||
1094*35238bceSAndroid Build Coastguard Worker               m_colorBufferFormat.type == tcu::TextureFormat::UNSIGNED_INT8 ||
1095*35238bceSAndroid Build Coastguard Worker               m_colorBufferFormat.type == tcu::TextureFormat::UNSIGNED_INT16 ||
1096*35238bceSAndroid Build Coastguard Worker               m_colorBufferFormat.type == tcu::TextureFormat::SIGNED_INT8 ||
1097*35238bceSAndroid Build Coastguard Worker               m_colorBufferFormat.type == tcu::TextureFormat::SIGNED_INT16);
1098*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(glu::isGLInternalColorFormatFilterable(glu::getInternalFormat(m_colorBufferFormat)) ||
1099*35238bceSAndroid Build Coastguard Worker               (m_magFilter == tcu::Sampler::NEAREST &&
1100*35238bceSAndroid Build Coastguard Worker                (m_minFilter == tcu::Sampler::NEAREST || m_minFilter == tcu::Sampler::NEAREST_MIPMAP_NEAREST)));
1101*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(isMipmapFilter(m_minFilter) || !(m_flags & GATHERCASE_MIPMAP_INCOMPLETE));
1102*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_textureType == TEXTURETYPE_CUBE || !(m_flags & GATHERCASE_DONT_SAMPLE_CUBE_CORNERS));
1103*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!((m_flags & GATHERCASE_MIPMAP_INCOMPLETE) &&
1104*35238bceSAndroid Build Coastguard Worker                 isDepthFormat(m_textureFormat))); // It's not clear what shadow textures should return when incomplete.
1105*35238bceSAndroid Build Coastguard Worker }
1106*35238bceSAndroid Build Coastguard Worker 
getOffsetRange(void) const1107*35238bceSAndroid Build Coastguard Worker IVec2 TextureGatherCase::getOffsetRange(void) const
1108*35238bceSAndroid Build Coastguard Worker {
1109*35238bceSAndroid Build Coastguard Worker     switch (m_offsetSize)
1110*35238bceSAndroid Build Coastguard Worker     {
1111*35238bceSAndroid Build Coastguard Worker     case OFFSETSIZE_NONE:
1112*35238bceSAndroid Build Coastguard Worker         return IVec2(0);
1113*35238bceSAndroid Build Coastguard Worker 
1114*35238bceSAndroid Build Coastguard Worker     case OFFSETSIZE_MINIMUM_REQUIRED:
1115*35238bceSAndroid Build Coastguard Worker         // \note Defined by spec.
1116*35238bceSAndroid Build Coastguard Worker         return IVec2(SPEC_MAX_MIN_OFFSET, SPEC_MIN_MAX_OFFSET);
1117*35238bceSAndroid Build Coastguard Worker 
1118*35238bceSAndroid Build Coastguard Worker     case OFFSETSIZE_IMPLEMENTATION_MAXIMUM:
1119*35238bceSAndroid Build Coastguard Worker         return IVec2(m_context.getContextInfo().getInt(GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET),
1120*35238bceSAndroid Build Coastguard Worker                      m_context.getContextInfo().getInt(GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET));
1121*35238bceSAndroid Build Coastguard Worker 
1122*35238bceSAndroid Build Coastguard Worker     default:
1123*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1124*35238bceSAndroid Build Coastguard Worker         return IVec2(-1);
1125*35238bceSAndroid Build Coastguard Worker     }
1126*35238bceSAndroid Build Coastguard Worker }
1127*35238bceSAndroid Build Coastguard Worker 
genVertexShaderSource(bool requireGpuShader5,int numTexCoordComponents,bool useNormalizedCoordInput)1128*35238bceSAndroid Build Coastguard Worker glu::VertexSource TextureGatherCase::genVertexShaderSource(bool requireGpuShader5, int numTexCoordComponents,
1129*35238bceSAndroid Build Coastguard Worker                                                            bool useNormalizedCoordInput)
1130*35238bceSAndroid Build Coastguard Worker {
1131*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numTexCoordComponents == 2 || numTexCoordComponents == 3);
1132*35238bceSAndroid Build Coastguard Worker     const string texCoordType = "vec" + de::toString(numTexCoordComponents);
1133*35238bceSAndroid Build Coastguard Worker     std::string vertexSource  = "${GLSL_VERSION_DECL}\n" + string(requireGpuShader5 ? "${GPU_SHADER5_REQUIRE}\n" : "") +
1134*35238bceSAndroid Build Coastguard Worker                                "\n"
1135*35238bceSAndroid Build Coastguard Worker                                "in highp vec2 a_position;\n"
1136*35238bceSAndroid Build Coastguard Worker                                "in highp " +
1137*35238bceSAndroid Build Coastguard Worker                                texCoordType + " a_texCoord;\n" +
1138*35238bceSAndroid Build Coastguard Worker                                (useNormalizedCoordInput ? "in highp vec2 a_normalizedCoord; // (0,0) to (1,1)\n" : "") +
1139*35238bceSAndroid Build Coastguard Worker                                "\n"
1140*35238bceSAndroid Build Coastguard Worker                                "out highp " +
1141*35238bceSAndroid Build Coastguard Worker                                texCoordType + " v_texCoord;\n" +
1142*35238bceSAndroid Build Coastguard Worker                                (useNormalizedCoordInput ? "out highp vec2 v_normalizedCoord;\n" : "") +
1143*35238bceSAndroid Build Coastguard Worker                                "\n"
1144*35238bceSAndroid Build Coastguard Worker                                "void main (void)\n"
1145*35238bceSAndroid Build Coastguard Worker                                "{\n"
1146*35238bceSAndroid Build Coastguard Worker                                "    gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0);\n"
1147*35238bceSAndroid Build Coastguard Worker                                "    v_texCoord = a_texCoord;\n" +
1148*35238bceSAndroid Build Coastguard Worker                                (useNormalizedCoordInput ? "\tv_normalizedCoord = a_normalizedCoord;\n" : "") + "}\n";
1149*35238bceSAndroid Build Coastguard Worker     return glu::VertexSource(specializeShader(m_context, vertexSource.c_str()));
1150*35238bceSAndroid Build Coastguard Worker }
1151*35238bceSAndroid Build Coastguard Worker 
genFragmentShaderSource(bool requireGpuShader5,int numTexCoordComponents,glu::DataType samplerType,const string & funcCall,bool useNormalizedCoordInput,bool usePixCoord)1152*35238bceSAndroid Build Coastguard Worker glu::FragmentSource TextureGatherCase::genFragmentShaderSource(bool requireGpuShader5, int numTexCoordComponents,
1153*35238bceSAndroid Build Coastguard Worker                                                                glu::DataType samplerType, const string &funcCall,
1154*35238bceSAndroid Build Coastguard Worker                                                                bool useNormalizedCoordInput, bool usePixCoord)
1155*35238bceSAndroid Build Coastguard Worker {
1156*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(glu::isDataTypeSampler(samplerType));
1157*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(de::inRange(numTexCoordComponents, 2, 3));
1158*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!usePixCoord || useNormalizedCoordInput);
1159*35238bceSAndroid Build Coastguard Worker 
1160*35238bceSAndroid Build Coastguard Worker     const string texCoordType = "vec" + de::toString(numTexCoordComponents);
1161*35238bceSAndroid Build Coastguard Worker 
1162*35238bceSAndroid Build Coastguard Worker     std::string fragmentSource =
1163*35238bceSAndroid Build Coastguard Worker         "${GLSL_VERSION_DECL}\n" + string(requireGpuShader5 ? "${GPU_SHADER5_REQUIRE}\n" : "") +
1164*35238bceSAndroid Build Coastguard Worker         "\n"
1165*35238bceSAndroid Build Coastguard Worker         "layout (location = 0) out mediump " +
1166*35238bceSAndroid Build Coastguard Worker         glu::getDataTypeName(getSamplerGatherResultType(samplerType)) +
1167*35238bceSAndroid Build Coastguard Worker         " o_color;\n"
1168*35238bceSAndroid Build Coastguard Worker         "\n"
1169*35238bceSAndroid Build Coastguard Worker         "in highp " +
1170*35238bceSAndroid Build Coastguard Worker         texCoordType + " v_texCoord;\n" + (useNormalizedCoordInput ? "in highp vec2 v_normalizedCoord;\n" : "") +
1171*35238bceSAndroid Build Coastguard Worker         "\n"
1172*35238bceSAndroid Build Coastguard Worker         "uniform highp " +
1173*35238bceSAndroid Build Coastguard Worker         string(glu::getDataTypeName(samplerType)) + " u_sampler;\n" +
1174*35238bceSAndroid Build Coastguard Worker         (useNormalizedCoordInput ? "uniform highp vec2 u_viewportSize;\n" : "") +
1175*35238bceSAndroid Build Coastguard Worker         "\n"
1176*35238bceSAndroid Build Coastguard Worker         "void main(void)\n"
1177*35238bceSAndroid Build Coastguard Worker         "{\n" +
1178*35238bceSAndroid Build Coastguard Worker         (usePixCoord ? "\tivec2 pixCoord = ivec2(v_normalizedCoord*u_viewportSize);\n" : "") +
1179*35238bceSAndroid Build Coastguard Worker         "    o_color = " + funcCall +
1180*35238bceSAndroid Build Coastguard Worker         ";\n"
1181*35238bceSAndroid Build Coastguard Worker         "}\n";
1182*35238bceSAndroid Build Coastguard Worker 
1183*35238bceSAndroid Build Coastguard Worker     return glu::FragmentSource(specializeShader(m_context, fragmentSource.c_str()));
1184*35238bceSAndroid Build Coastguard Worker }
1185*35238bceSAndroid Build Coastguard Worker 
genGatherFuncCall(GatherType gatherType,const tcu::TextureFormat & textureFormat,const GatherArgs & gatherArgs,const string & refZExpr,const IVec2 & offsetRange,int indentationDepth)1186*35238bceSAndroid Build Coastguard Worker string TextureGatherCase::genGatherFuncCall(GatherType gatherType, const tcu::TextureFormat &textureFormat,
1187*35238bceSAndroid Build Coastguard Worker                                             const GatherArgs &gatherArgs, const string &refZExpr,
1188*35238bceSAndroid Build Coastguard Worker                                             const IVec2 &offsetRange, int indentationDepth)
1189*35238bceSAndroid Build Coastguard Worker {
1190*35238bceSAndroid Build Coastguard Worker     string result;
1191*35238bceSAndroid Build Coastguard Worker 
1192*35238bceSAndroid Build Coastguard Worker     switch (gatherType)
1193*35238bceSAndroid Build Coastguard Worker     {
1194*35238bceSAndroid Build Coastguard Worker     case GATHERTYPE_BASIC:
1195*35238bceSAndroid Build Coastguard Worker         result += "textureGather";
1196*35238bceSAndroid Build Coastguard Worker         break;
1197*35238bceSAndroid Build Coastguard Worker     case GATHERTYPE_OFFSET: // \note Fallthrough.
1198*35238bceSAndroid Build Coastguard Worker     case GATHERTYPE_OFFSET_DYNAMIC:
1199*35238bceSAndroid Build Coastguard Worker         result += "textureGatherOffset";
1200*35238bceSAndroid Build Coastguard Worker         break;
1201*35238bceSAndroid Build Coastguard Worker     case GATHERTYPE_OFFSETS:
1202*35238bceSAndroid Build Coastguard Worker         result += "textureGatherOffsets";
1203*35238bceSAndroid Build Coastguard Worker         break;
1204*35238bceSAndroid Build Coastguard Worker     default:
1205*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1206*35238bceSAndroid Build Coastguard Worker     }
1207*35238bceSAndroid Build Coastguard Worker 
1208*35238bceSAndroid Build Coastguard Worker     result += "(u_sampler, v_texCoord";
1209*35238bceSAndroid Build Coastguard Worker 
1210*35238bceSAndroid Build Coastguard Worker     if (isDepthFormat(textureFormat))
1211*35238bceSAndroid Build Coastguard Worker     {
1212*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(gatherArgs.componentNdx < 0);
1213*35238bceSAndroid Build Coastguard Worker         result += ", " + refZExpr;
1214*35238bceSAndroid Build Coastguard Worker     }
1215*35238bceSAndroid Build Coastguard Worker 
1216*35238bceSAndroid Build Coastguard Worker     if (gatherType == GATHERTYPE_OFFSET || gatherType == GATHERTYPE_OFFSET_DYNAMIC || gatherType == GATHERTYPE_OFFSETS)
1217*35238bceSAndroid Build Coastguard Worker     {
1218*35238bceSAndroid Build Coastguard Worker         result += ", ";
1219*35238bceSAndroid Build Coastguard Worker         switch (gatherType)
1220*35238bceSAndroid Build Coastguard Worker         {
1221*35238bceSAndroid Build Coastguard Worker         case GATHERTYPE_OFFSET:
1222*35238bceSAndroid Build Coastguard Worker             result += "ivec2" + de::toString(gatherArgs.offsets[0]);
1223*35238bceSAndroid Build Coastguard Worker             break;
1224*35238bceSAndroid Build Coastguard Worker 
1225*35238bceSAndroid Build Coastguard Worker         case GATHERTYPE_OFFSET_DYNAMIC:
1226*35238bceSAndroid Build Coastguard Worker             result += "pixCoord.yx % ivec2(" + de::toString(offsetRange.y() - offsetRange.x() + 1) + ") + " +
1227*35238bceSAndroid Build Coastguard Worker                       de::toString(offsetRange.x());
1228*35238bceSAndroid Build Coastguard Worker             break;
1229*35238bceSAndroid Build Coastguard Worker 
1230*35238bceSAndroid Build Coastguard Worker         case GATHERTYPE_OFFSETS:
1231*35238bceSAndroid Build Coastguard Worker             result += "ivec2[4](\n" + string(indentationDepth, '\t') + "\tivec2" + de::toString(gatherArgs.offsets[0]) +
1232*35238bceSAndroid Build Coastguard Worker                       ",\n" + string(indentationDepth, '\t') + "\tivec2" + de::toString(gatherArgs.offsets[1]) + ",\n" +
1233*35238bceSAndroid Build Coastguard Worker                       string(indentationDepth, '\t') + "\tivec2" + de::toString(gatherArgs.offsets[2]) + ",\n" +
1234*35238bceSAndroid Build Coastguard Worker                       string(indentationDepth, '\t') + "\tivec2" + de::toString(gatherArgs.offsets[3]) + ")\n" +
1235*35238bceSAndroid Build Coastguard Worker                       string(indentationDepth, '\t') + "\t";
1236*35238bceSAndroid Build Coastguard Worker             break;
1237*35238bceSAndroid Build Coastguard Worker 
1238*35238bceSAndroid Build Coastguard Worker         default:
1239*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
1240*35238bceSAndroid Build Coastguard Worker         }
1241*35238bceSAndroid Build Coastguard Worker     }
1242*35238bceSAndroid Build Coastguard Worker 
1243*35238bceSAndroid Build Coastguard Worker     if (gatherArgs.componentNdx >= 0)
1244*35238bceSAndroid Build Coastguard Worker     {
1245*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(gatherArgs.componentNdx < 4);
1246*35238bceSAndroid Build Coastguard Worker         result += ", " + de::toString(gatherArgs.componentNdx);
1247*35238bceSAndroid Build Coastguard Worker     }
1248*35238bceSAndroid Build Coastguard Worker 
1249*35238bceSAndroid Build Coastguard Worker     result += ")";
1250*35238bceSAndroid Build Coastguard Worker 
1251*35238bceSAndroid Build Coastguard Worker     return result;
1252*35238bceSAndroid Build Coastguard Worker }
1253*35238bceSAndroid Build Coastguard Worker 
1254*35238bceSAndroid Build Coastguard Worker // \note If componentNdx for genProgramSources() is -1, component index is not specified.
genProgramSources(GatherType gatherType,TextureType textureType,const tcu::TextureFormat & textureFormat,const GatherArgs & gatherArgs,const string & refZExpr,const IVec2 & offsetRange)1255*35238bceSAndroid Build Coastguard Worker glu::ProgramSources TextureGatherCase::genProgramSources(GatherType gatherType, TextureType textureType,
1256*35238bceSAndroid Build Coastguard Worker                                                          const tcu::TextureFormat &textureFormat,
1257*35238bceSAndroid Build Coastguard Worker                                                          const GatherArgs &gatherArgs, const string &refZExpr,
1258*35238bceSAndroid Build Coastguard Worker                                                          const IVec2 &offsetRange)
1259*35238bceSAndroid Build Coastguard Worker {
1260*35238bceSAndroid Build Coastguard Worker     const bool usePixCoord          = gatherType == GATHERTYPE_OFFSET_DYNAMIC;
1261*35238bceSAndroid Build Coastguard Worker     const bool useNormalizedCoord   = usePixCoord || isDepthFormat(textureFormat);
1262*35238bceSAndroid Build Coastguard Worker     const bool isDynamicOffset      = gatherType == GATHERTYPE_OFFSET_DYNAMIC;
1263*35238bceSAndroid Build Coastguard Worker     const bool isShadow             = isDepthFormat(textureFormat);
1264*35238bceSAndroid Build Coastguard Worker     const glu::DataType samplerType = getSamplerType(textureType, textureFormat);
1265*35238bceSAndroid Build Coastguard Worker     const int numDims               = getNumTextureSamplingDimensions(textureType);
1266*35238bceSAndroid Build Coastguard Worker     const string funcCall = genGatherFuncCall(gatherType, textureFormat, gatherArgs, refZExpr, offsetRange, 1);
1267*35238bceSAndroid Build Coastguard Worker 
1268*35238bceSAndroid Build Coastguard Worker     return glu::ProgramSources() << genVertexShaderSource(requireGpuShader5(gatherType), numDims,
1269*35238bceSAndroid Build Coastguard Worker                                                           isDynamicOffset || isShadow)
1270*35238bceSAndroid Build Coastguard Worker                                  << genFragmentShaderSource(requireGpuShader5(gatherType), numDims, samplerType,
1271*35238bceSAndroid Build Coastguard Worker                                                             funcCall, useNormalizedCoord, usePixCoord);
1272*35238bceSAndroid Build Coastguard Worker }
1273*35238bceSAndroid Build Coastguard Worker 
init(void)1274*35238bceSAndroid Build Coastguard Worker void TextureGatherCase::init(void)
1275*35238bceSAndroid Build Coastguard Worker {
1276*35238bceSAndroid Build Coastguard Worker     TestLog &log                        = m_testCtx.getLog();
1277*35238bceSAndroid Build Coastguard Worker     const glu::RenderContext &renderCtx = m_context.getRenderContext();
1278*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl            = renderCtx.getFunctions();
1279*35238bceSAndroid Build Coastguard Worker     const uint32_t texTypeGL            = getGLTextureType(m_textureType);
1280*35238bceSAndroid Build Coastguard Worker     const bool supportsES32orGL45 =
1281*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
1282*35238bceSAndroid Build Coastguard Worker         glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
1283*35238bceSAndroid Build Coastguard Worker 
1284*35238bceSAndroid Build Coastguard Worker     // Check prerequisites.
1285*35238bceSAndroid Build Coastguard Worker     if (requireGpuShader5(m_gatherType) && !supportsES32orGL45 &&
1286*35238bceSAndroid Build Coastguard Worker         !m_context.getContextInfo().isExtensionSupported("GL_EXT_gpu_shader5"))
1287*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError("GL_EXT_gpu_shader5 required");
1288*35238bceSAndroid Build Coastguard Worker 
1289*35238bceSAndroid Build Coastguard Worker     // Log and check implementation offset limits, if appropriate.
1290*35238bceSAndroid Build Coastguard Worker     if (m_offsetSize == OFFSETSIZE_IMPLEMENTATION_MAXIMUM)
1291*35238bceSAndroid Build Coastguard Worker     {
1292*35238bceSAndroid Build Coastguard Worker         const IVec2 offsetRange = getOffsetRange();
1293*35238bceSAndroid Build Coastguard Worker         log << TestLog::Integer("ImplementationMinTextureGatherOffset",
1294*35238bceSAndroid Build Coastguard Worker                                 "Implementation's value for GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET", "", QP_KEY_TAG_NONE,
1295*35238bceSAndroid Build Coastguard Worker                                 offsetRange[0])
1296*35238bceSAndroid Build Coastguard Worker             << TestLog::Integer("ImplementationMaxTextureGatherOffset",
1297*35238bceSAndroid Build Coastguard Worker                                 "Implementation's value for GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET", "", QP_KEY_TAG_NONE,
1298*35238bceSAndroid Build Coastguard Worker                                 offsetRange[1]);
1299*35238bceSAndroid Build Coastguard Worker         TCU_CHECK_MSG(
1300*35238bceSAndroid Build Coastguard Worker             offsetRange[0] <= SPEC_MAX_MIN_OFFSET,
1301*35238bceSAndroid Build Coastguard Worker             ("GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET must be at most " + de::toString((int)SPEC_MAX_MIN_OFFSET)).c_str());
1302*35238bceSAndroid Build Coastguard Worker         TCU_CHECK_MSG(offsetRange[1] >= SPEC_MIN_MAX_OFFSET, ("GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET must be at least " +
1303*35238bceSAndroid Build Coastguard Worker                                                               de::toString((int)SPEC_MIN_MAX_OFFSET))
1304*35238bceSAndroid Build Coastguard Worker                                                                  .c_str());
1305*35238bceSAndroid Build Coastguard Worker     }
1306*35238bceSAndroid Build Coastguard Worker 
1307*35238bceSAndroid Build Coastguard Worker     if (!isContextTypeES(m_context.getRenderContext().getType()))
1308*35238bceSAndroid Build Coastguard Worker         gl.enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
1309*35238bceSAndroid Build Coastguard Worker 
1310*35238bceSAndroid Build Coastguard Worker     // Create rbo and fbo.
1311*35238bceSAndroid Build Coastguard Worker 
1312*35238bceSAndroid Build Coastguard Worker     m_colorBuffer = MovePtr<glu::Renderbuffer>(new glu::Renderbuffer(renderCtx));
1313*35238bceSAndroid Build Coastguard Worker     gl.bindRenderbuffer(GL_RENDERBUFFER, **m_colorBuffer);
1314*35238bceSAndroid Build Coastguard Worker     gl.renderbufferStorage(GL_RENDERBUFFER, glu::getInternalFormat(m_colorBufferFormat), RENDER_SIZE.x(),
1315*35238bceSAndroid Build Coastguard Worker                            RENDER_SIZE.y());
1316*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "Create and setup renderbuffer object");
1317*35238bceSAndroid Build Coastguard Worker 
1318*35238bceSAndroid Build Coastguard Worker     m_fbo = MovePtr<glu::Framebuffer>(new glu::Framebuffer(renderCtx));
1319*35238bceSAndroid Build Coastguard Worker     gl.bindFramebuffer(GL_FRAMEBUFFER, **m_fbo);
1320*35238bceSAndroid Build Coastguard Worker     gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, **m_colorBuffer);
1321*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "Create and setup framebuffer object");
1322*35238bceSAndroid Build Coastguard Worker 
1323*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Using a framebuffer object with renderbuffer with format "
1324*35238bceSAndroid Build Coastguard Worker         << glu::getTextureFormatName(glu::getInternalFormat(m_colorBufferFormat)) << " and size " << RENDER_SIZE
1325*35238bceSAndroid Build Coastguard Worker         << TestLog::EndMessage;
1326*35238bceSAndroid Build Coastguard Worker 
1327*35238bceSAndroid Build Coastguard Worker     // Generate subclass-specific iterations.
1328*35238bceSAndroid Build Coastguard Worker 
1329*35238bceSAndroid Build Coastguard Worker     generateIterations();
1330*35238bceSAndroid Build Coastguard Worker     m_currentIteration = 0;
1331*35238bceSAndroid Build Coastguard Worker 
1332*35238bceSAndroid Build Coastguard Worker     // Initialize texture.
1333*35238bceSAndroid Build Coastguard Worker 
1334*35238bceSAndroid Build Coastguard Worker     createAndUploadTexture();
1335*35238bceSAndroid Build Coastguard Worker     gl.texParameteri(texTypeGL, GL_TEXTURE_WRAP_S, glu::getGLWrapMode(m_wrapS));
1336*35238bceSAndroid Build Coastguard Worker     gl.texParameteri(texTypeGL, GL_TEXTURE_WRAP_T, glu::getGLWrapMode(m_wrapT));
1337*35238bceSAndroid Build Coastguard Worker     gl.texParameteri(texTypeGL, GL_TEXTURE_MIN_FILTER, glu::getGLFilterMode(m_minFilter));
1338*35238bceSAndroid Build Coastguard Worker     gl.texParameteri(texTypeGL, GL_TEXTURE_MAG_FILTER, glu::getGLFilterMode(m_magFilter));
1339*35238bceSAndroid Build Coastguard Worker 
1340*35238bceSAndroid Build Coastguard Worker     if (m_baseLevel != 0)
1341*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(texTypeGL, GL_TEXTURE_BASE_LEVEL, m_baseLevel);
1342*35238bceSAndroid Build Coastguard Worker 
1343*35238bceSAndroid Build Coastguard Worker     if (isDepthFormat(m_textureFormat))
1344*35238bceSAndroid Build Coastguard Worker     {
1345*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(texTypeGL, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
1346*35238bceSAndroid Build Coastguard Worker         gl.texParameteri(texTypeGL, GL_TEXTURE_COMPARE_FUNC, glu::getGLCompareFunc(m_shadowCompareMode));
1347*35238bceSAndroid Build Coastguard Worker     }
1348*35238bceSAndroid Build Coastguard Worker 
1349*35238bceSAndroid Build Coastguard Worker     if (m_textureSwizzle.isSome())
1350*35238bceSAndroid Build Coastguard Worker     {
1351*35238bceSAndroid Build Coastguard Worker         const uint32_t swizzleNamesGL[4] = {GL_TEXTURE_SWIZZLE_R, GL_TEXTURE_SWIZZLE_G, GL_TEXTURE_SWIZZLE_B,
1352*35238bceSAndroid Build Coastguard Worker                                             GL_TEXTURE_SWIZZLE_A};
1353*35238bceSAndroid Build Coastguard Worker 
1354*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < 4; i++)
1355*35238bceSAndroid Build Coastguard Worker         {
1356*35238bceSAndroid Build Coastguard Worker             const uint32_t curGLSwizzle = getGLTextureSwizzleComponent(m_textureSwizzle.getSwizzle()[i]);
1357*35238bceSAndroid Build Coastguard Worker             gl.texParameteri(texTypeGL, swizzleNamesGL[i], curGLSwizzle);
1358*35238bceSAndroid Build Coastguard Worker         }
1359*35238bceSAndroid Build Coastguard Worker     }
1360*35238bceSAndroid Build Coastguard Worker 
1361*35238bceSAndroid Build Coastguard Worker     GLU_EXPECT_NO_ERROR(gl.getError(), "Set texture parameters");
1362*35238bceSAndroid Build Coastguard Worker 
1363*35238bceSAndroid Build Coastguard Worker     log << TestLog::Message << "Texture base level is " << m_baseLevel << TestLog::EndMessage << TestLog::Message
1364*35238bceSAndroid Build Coastguard Worker         << "s and t wrap modes are " << glu::getTextureWrapModeName(glu::getGLWrapMode(m_wrapS)) << " and "
1365*35238bceSAndroid Build Coastguard Worker         << glu::getTextureWrapModeName(glu::getGLWrapMode(m_wrapT)) << ", respectively" << TestLog::EndMessage
1366*35238bceSAndroid Build Coastguard Worker         << TestLog::Message << "Minification and magnification filter modes are "
1367*35238bceSAndroid Build Coastguard Worker         << glu::getTextureFilterName(glu::getGLFilterMode(m_minFilter)) << " and "
1368*35238bceSAndroid Build Coastguard Worker         << glu::getTextureFilterName(glu::getGLFilterMode(m_magFilter)) << ", respectively "
1369*35238bceSAndroid Build Coastguard Worker         << ((m_flags & GATHERCASE_MIPMAP_INCOMPLETE) ? "(note that they cause the texture to be incomplete)" :
1370*35238bceSAndroid Build Coastguard Worker                                                        "(note that they should have no effect on gather result)")
1371*35238bceSAndroid Build Coastguard Worker         << TestLog::EndMessage << TestLog::Message << "Using texture swizzle " << m_textureSwizzle
1372*35238bceSAndroid Build Coastguard Worker         << TestLog::EndMessage;
1373*35238bceSAndroid Build Coastguard Worker 
1374*35238bceSAndroid Build Coastguard Worker     if (m_shadowCompareMode != tcu::Sampler::COMPAREMODE_NONE)
1375*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Using texture compare func "
1376*35238bceSAndroid Build Coastguard Worker             << glu::getCompareFuncName(glu::getGLCompareFunc(m_shadowCompareMode)) << TestLog::EndMessage;
1377*35238bceSAndroid Build Coastguard Worker }
1378*35238bceSAndroid Build Coastguard Worker 
deinit(void)1379*35238bceSAndroid Build Coastguard Worker void TextureGatherCase::deinit(void)
1380*35238bceSAndroid Build Coastguard Worker {
1381*35238bceSAndroid Build Coastguard Worker     if (!isContextTypeES(m_context.getRenderContext().getType()))
1382*35238bceSAndroid Build Coastguard Worker         m_context.getRenderContext().getFunctions().disable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
1383*35238bceSAndroid Build Coastguard Worker 
1384*35238bceSAndroid Build Coastguard Worker     m_program     = MovePtr<ShaderProgram>(DE_NULL);
1385*35238bceSAndroid Build Coastguard Worker     m_fbo         = MovePtr<glu::Framebuffer>(DE_NULL);
1386*35238bceSAndroid Build Coastguard Worker     m_colorBuffer = MovePtr<glu::Renderbuffer>(DE_NULL);
1387*35238bceSAndroid Build Coastguard Worker }
1388*35238bceSAndroid Build Coastguard Worker 
iterate(void)1389*35238bceSAndroid Build Coastguard Worker TextureGatherCase::IterateResult TextureGatherCase::iterate(void)
1390*35238bceSAndroid Build Coastguard Worker {
1391*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
1392*35238bceSAndroid Build Coastguard Worker     const tcu::ScopedLogSection iterationSection(log, "Iteration" + de::toString(m_currentIteration),
1393*35238bceSAndroid Build Coastguard Worker                                                  "Iteration " + de::toString(m_currentIteration));
1394*35238bceSAndroid Build Coastguard Worker     const glu::RenderContext &renderCtx    = m_context.getRenderContext();
1395*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl               = renderCtx.getFunctions();
1396*35238bceSAndroid Build Coastguard Worker     const GatherArgs &gatherArgs           = getGatherArgs(m_currentIteration);
1397*35238bceSAndroid Build Coastguard Worker     const string refZExpr                  = "v_normalizedCoord.x";
1398*35238bceSAndroid Build Coastguard Worker     const bool needPixelCoordInShader      = m_gatherType == GATHERTYPE_OFFSET_DYNAMIC;
1399*35238bceSAndroid Build Coastguard Worker     const bool needNormalizedCoordInShader = needPixelCoordInShader || isDepthFormat(m_textureFormat);
1400*35238bceSAndroid Build Coastguard Worker 
1401*35238bceSAndroid Build Coastguard Worker     // Generate a program appropriate for this iteration.
1402*35238bceSAndroid Build Coastguard Worker 
1403*35238bceSAndroid Build Coastguard Worker     m_program = MovePtr<ShaderProgram>(
1404*35238bceSAndroid Build Coastguard Worker         new ShaderProgram(renderCtx, genProgramSources(m_gatherType, m_textureType, m_textureFormat, gatherArgs,
1405*35238bceSAndroid Build Coastguard Worker                                                        refZExpr, getOffsetRange())));
1406*35238bceSAndroid Build Coastguard Worker     if (m_currentIteration == 0)
1407*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << *m_program;
1408*35238bceSAndroid Build Coastguard Worker     else
1409*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog()
1410*35238bceSAndroid Build Coastguard Worker             << TestLog::Message
1411*35238bceSAndroid Build Coastguard Worker             << "Using a program similar to the previous one, except with a gather function call as follows:\n"
1412*35238bceSAndroid Build Coastguard Worker             << genGatherFuncCall(m_gatherType, m_textureFormat, gatherArgs, refZExpr, getOffsetRange(), 0)
1413*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
1414*35238bceSAndroid Build Coastguard Worker     if (!m_program->isOk())
1415*35238bceSAndroid Build Coastguard Worker     {
1416*35238bceSAndroid Build Coastguard Worker         if (m_currentIteration != 0)
1417*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << *m_program;
1418*35238bceSAndroid Build Coastguard Worker         TCU_FAIL("Failed to build program");
1419*35238bceSAndroid Build Coastguard Worker     }
1420*35238bceSAndroid Build Coastguard Worker 
1421*35238bceSAndroid Build Coastguard Worker     // Render.
1422*35238bceSAndroid Build Coastguard Worker 
1423*35238bceSAndroid Build Coastguard Worker     gl.viewport(0, 0, RENDER_SIZE.x(), RENDER_SIZE.y());
1424*35238bceSAndroid Build Coastguard Worker     gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
1425*35238bceSAndroid Build Coastguard Worker     gl.clear(GL_COLOR_BUFFER_BIT);
1426*35238bceSAndroid Build Coastguard Worker 
1427*35238bceSAndroid Build Coastguard Worker     {
1428*35238bceSAndroid Build Coastguard Worker         const float position[4 * 2] = {
1429*35238bceSAndroid Build Coastguard Worker             -1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f,
1430*35238bceSAndroid Build Coastguard Worker         };
1431*35238bceSAndroid Build Coastguard Worker 
1432*35238bceSAndroid Build Coastguard Worker         const float normalizedCoord[4 * 2] = {
1433*35238bceSAndroid Build Coastguard Worker             0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1434*35238bceSAndroid Build Coastguard Worker         };
1435*35238bceSAndroid Build Coastguard Worker 
1436*35238bceSAndroid Build Coastguard Worker         const vector<float> texCoord = computeQuadTexCoord(m_currentIteration);
1437*35238bceSAndroid Build Coastguard Worker 
1438*35238bceSAndroid Build Coastguard Worker         vector<glu::VertexArrayBinding> attrBindings;
1439*35238bceSAndroid Build Coastguard Worker         attrBindings.push_back(glu::va::Float("a_position", 2, 4, 0, &position[0]));
1440*35238bceSAndroid Build Coastguard Worker         attrBindings.push_back(glu::va::Float("a_texCoord", (int)texCoord.size() / 4, 4, 0, &texCoord[0]));
1441*35238bceSAndroid Build Coastguard Worker         if (needNormalizedCoordInShader)
1442*35238bceSAndroid Build Coastguard Worker             attrBindings.push_back(glu::va::Float("a_normalizedCoord", 2, 4, 0, &normalizedCoord[0]));
1443*35238bceSAndroid Build Coastguard Worker 
1444*35238bceSAndroid Build Coastguard Worker         const uint16_t indices[6] = {0, 1, 2, 2, 1, 3};
1445*35238bceSAndroid Build Coastguard Worker 
1446*35238bceSAndroid Build Coastguard Worker         gl.useProgram(m_program->getProgram());
1447*35238bceSAndroid Build Coastguard Worker 
1448*35238bceSAndroid Build Coastguard Worker         {
1449*35238bceSAndroid Build Coastguard Worker             const int samplerUniformLocation = gl.getUniformLocation(m_program->getProgram(), "u_sampler");
1450*35238bceSAndroid Build Coastguard Worker             TCU_CHECK(samplerUniformLocation >= 0);
1451*35238bceSAndroid Build Coastguard Worker             gl.uniform1i(samplerUniformLocation, 0);
1452*35238bceSAndroid Build Coastguard Worker         }
1453*35238bceSAndroid Build Coastguard Worker 
1454*35238bceSAndroid Build Coastguard Worker         if (needPixelCoordInShader)
1455*35238bceSAndroid Build Coastguard Worker         {
1456*35238bceSAndroid Build Coastguard Worker             const int viewportSizeUniformLocation = gl.getUniformLocation(m_program->getProgram(), "u_viewportSize");
1457*35238bceSAndroid Build Coastguard Worker             TCU_CHECK(viewportSizeUniformLocation >= 0);
1458*35238bceSAndroid Build Coastguard Worker             gl.uniform2f(viewportSizeUniformLocation, (float)RENDER_SIZE.x(), (float)RENDER_SIZE.y());
1459*35238bceSAndroid Build Coastguard Worker         }
1460*35238bceSAndroid Build Coastguard Worker 
1461*35238bceSAndroid Build Coastguard Worker         if (texCoord.size() == 2 * 4)
1462*35238bceSAndroid Build Coastguard Worker         {
1463*35238bceSAndroid Build Coastguard Worker             Vec2 texCoordVec[4];
1464*35238bceSAndroid Build Coastguard Worker             computeTexCoordVecs(texCoord, texCoordVec);
1465*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "Texture coordinates run from " << texCoordVec[0] << " to " << texCoordVec[3]
1466*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
1467*35238bceSAndroid Build Coastguard Worker         }
1468*35238bceSAndroid Build Coastguard Worker         else if (texCoord.size() == 3 * 4)
1469*35238bceSAndroid Build Coastguard Worker         {
1470*35238bceSAndroid Build Coastguard Worker             Vec3 texCoordVec[4];
1471*35238bceSAndroid Build Coastguard Worker             computeTexCoordVecs(texCoord, texCoordVec);
1472*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "Texture coordinates run from " << texCoordVec[0] << " to " << texCoordVec[3]
1473*35238bceSAndroid Build Coastguard Worker                 << TestLog::EndMessage;
1474*35238bceSAndroid Build Coastguard Worker         }
1475*35238bceSAndroid Build Coastguard Worker         else
1476*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
1477*35238bceSAndroid Build Coastguard Worker 
1478*35238bceSAndroid Build Coastguard Worker         glu::draw(renderCtx, m_program->getProgram(), (int)attrBindings.size(), &attrBindings[0],
1479*35238bceSAndroid Build Coastguard Worker                   glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
1480*35238bceSAndroid Build Coastguard Worker     }
1481*35238bceSAndroid Build Coastguard Worker 
1482*35238bceSAndroid Build Coastguard Worker     // Verify result.
1483*35238bceSAndroid Build Coastguard Worker 
1484*35238bceSAndroid Build Coastguard Worker     {
1485*35238bceSAndroid Build Coastguard Worker         const tcu::TextureLevel rendered = getPixels(renderCtx, RENDER_SIZE, m_colorBufferFormat);
1486*35238bceSAndroid Build Coastguard Worker 
1487*35238bceSAndroid Build Coastguard Worker         if (!verify(m_currentIteration, rendered.getAccess()))
1488*35238bceSAndroid Build Coastguard Worker         {
1489*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result verification failed");
1490*35238bceSAndroid Build Coastguard Worker             return STOP;
1491*35238bceSAndroid Build Coastguard Worker         }
1492*35238bceSAndroid Build Coastguard Worker     }
1493*35238bceSAndroid Build Coastguard Worker 
1494*35238bceSAndroid Build Coastguard Worker     m_currentIteration++;
1495*35238bceSAndroid Build Coastguard Worker     if (m_currentIteration == (int)getNumIterations())
1496*35238bceSAndroid Build Coastguard Worker     {
1497*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1498*35238bceSAndroid Build Coastguard Worker         return STOP;
1499*35238bceSAndroid Build Coastguard Worker     }
1500*35238bceSAndroid Build Coastguard Worker     else
1501*35238bceSAndroid Build Coastguard Worker         return CONTINUE;
1502*35238bceSAndroid Build Coastguard Worker }
1503*35238bceSAndroid Build Coastguard Worker 
1504*35238bceSAndroid Build Coastguard Worker template <typename TexViewT, typename TexCoordT>
verify(const ConstPixelBufferAccess & rendered,const TexViewT & texture,const TexCoordT (& texCoords)[4],const GatherArgs & gatherArgs) const1505*35238bceSAndroid Build Coastguard Worker bool TextureGatherCase::verify(const ConstPixelBufferAccess &rendered, const TexViewT &texture,
1506*35238bceSAndroid Build Coastguard Worker                                const TexCoordT (&texCoords)[4], const GatherArgs &gatherArgs) const
1507*35238bceSAndroid Build Coastguard Worker {
1508*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
1509*35238bceSAndroid Build Coastguard Worker 
1510*35238bceSAndroid Build Coastguard Worker     if (m_flags & GATHERCASE_MIPMAP_INCOMPLETE)
1511*35238bceSAndroid Build Coastguard Worker     {
1512*35238bceSAndroid Build Coastguard Worker         const int componentNdx = de::max(0, gatherArgs.componentNdx);
1513*35238bceSAndroid Build Coastguard Worker         const Vec4 incompleteColor(0.0f, 0.0f, 0.0f, 1.0f);
1514*35238bceSAndroid Build Coastguard Worker         const Vec4 refColor(incompleteColor[componentNdx]);
1515*35238bceSAndroid Build Coastguard Worker         const bool isOk = verifySingleColored(log, rendered, refColor);
1516*35238bceSAndroid Build Coastguard Worker 
1517*35238bceSAndroid Build Coastguard Worker         if (!isOk)
1518*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "Note: expected color " << refColor << " for all pixels; "
1519*35238bceSAndroid Build Coastguard Worker                 << incompleteColor[componentNdx] << " is component at index " << componentNdx << " in the color "
1520*35238bceSAndroid Build Coastguard Worker                 << incompleteColor << ", which is used for incomplete textures" << TestLog::EndMessage;
1521*35238bceSAndroid Build Coastguard Worker 
1522*35238bceSAndroid Build Coastguard Worker         return isOk;
1523*35238bceSAndroid Build Coastguard Worker     }
1524*35238bceSAndroid Build Coastguard Worker     else
1525*35238bceSAndroid Build Coastguard Worker     {
1526*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_colorBufferFormat.order == tcu::TextureFormat::RGBA);
1527*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_colorBufferFormat.type == tcu::TextureFormat::UNORM_INT8 ||
1528*35238bceSAndroid Build Coastguard Worker                   m_colorBufferFormat.type == tcu::TextureFormat::UNSIGNED_INT8 ||
1529*35238bceSAndroid Build Coastguard Worker                   m_colorBufferFormat.type == tcu::TextureFormat::SIGNED_INT8);
1530*35238bceSAndroid Build Coastguard Worker 
1531*35238bceSAndroid Build Coastguard Worker         const MovePtr<PixelOffsets> pixelOffsets = makePixelOffsetsFunctor(m_gatherType, gatherArgs, getOffsetRange());
1532*35238bceSAndroid Build Coastguard Worker         const tcu::PixelFormat pixelFormat       = tcu::PixelFormat(8, 8, 8, 8);
1533*35238bceSAndroid Build Coastguard Worker         const IVec4 colorBits = tcu::max(glu::TextureTestUtil::getBitsVec(pixelFormat) - 1, tcu::IVec4(0));
1534*35238bceSAndroid Build Coastguard Worker         const IVec3 coordBits = m_textureType == TEXTURETYPE_2D       ? IVec3(20, 20, 0) :
1535*35238bceSAndroid Build Coastguard Worker                                 m_textureType == TEXTURETYPE_CUBE     ? IVec3(10, 10, 10) :
1536*35238bceSAndroid Build Coastguard Worker                                 m_textureType == TEXTURETYPE_2D_ARRAY ? IVec3(20, 20, 20) :
1537*35238bceSAndroid Build Coastguard Worker                                                                         IVec3(-1);
1538*35238bceSAndroid Build Coastguard Worker         const IVec3 uvwBits   = m_textureType == TEXTURETYPE_2D       ? IVec3(7, 7, 0) :
1539*35238bceSAndroid Build Coastguard Worker                                 m_textureType == TEXTURETYPE_CUBE     ? IVec3(6, 6, 0) :
1540*35238bceSAndroid Build Coastguard Worker                                 m_textureType == TEXTURETYPE_2D_ARRAY ? IVec3(7, 7, 7) :
1541*35238bceSAndroid Build Coastguard Worker                                                                         IVec3(-1);
1542*35238bceSAndroid Build Coastguard Worker         tcu::Sampler sampler;
1543*35238bceSAndroid Build Coastguard Worker         sampler.wrapS   = m_wrapS;
1544*35238bceSAndroid Build Coastguard Worker         sampler.wrapT   = m_wrapT;
1545*35238bceSAndroid Build Coastguard Worker         sampler.compare = m_shadowCompareMode;
1546*35238bceSAndroid Build Coastguard Worker 
1547*35238bceSAndroid Build Coastguard Worker         if (isDepthFormat(m_textureFormat))
1548*35238bceSAndroid Build Coastguard Worker         {
1549*35238bceSAndroid Build Coastguard Worker             tcu::TexComparePrecision comparePrec;
1550*35238bceSAndroid Build Coastguard Worker             comparePrec.coordBits     = coordBits;
1551*35238bceSAndroid Build Coastguard Worker             comparePrec.uvwBits       = uvwBits;
1552*35238bceSAndroid Build Coastguard Worker             comparePrec.referenceBits = 16;
1553*35238bceSAndroid Build Coastguard Worker             comparePrec.resultBits    = pixelFormat.redBits - 1;
1554*35238bceSAndroid Build Coastguard Worker 
1555*35238bceSAndroid Build Coastguard Worker             return verifyGatherOffsetsCompare(log, rendered, texture, texCoords, sampler, comparePrec,
1556*35238bceSAndroid Build Coastguard Worker                                               PixelCompareRefZDefault(RENDER_SIZE), *pixelOffsets);
1557*35238bceSAndroid Build Coastguard Worker         }
1558*35238bceSAndroid Build Coastguard Worker         else
1559*35238bceSAndroid Build Coastguard Worker         {
1560*35238bceSAndroid Build Coastguard Worker             const int componentNdx = de::max(0, gatherArgs.componentNdx);
1561*35238bceSAndroid Build Coastguard Worker 
1562*35238bceSAndroid Build Coastguard Worker             if (isUnormFormatType(m_textureFormat.type))
1563*35238bceSAndroid Build Coastguard Worker             {
1564*35238bceSAndroid Build Coastguard Worker                 tcu::LookupPrecision lookupPrec;
1565*35238bceSAndroid Build Coastguard Worker                 lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(colorBits);
1566*35238bceSAndroid Build Coastguard Worker                 lookupPrec.coordBits      = coordBits;
1567*35238bceSAndroid Build Coastguard Worker                 lookupPrec.uvwBits        = uvwBits;
1568*35238bceSAndroid Build Coastguard Worker                 lookupPrec.colorMask      = glu::TextureTestUtil::getCompareMask(pixelFormat);
1569*35238bceSAndroid Build Coastguard Worker                 return verifyGatherOffsets<float>(log, rendered, texture, texCoords, sampler, lookupPrec, componentNdx,
1570*35238bceSAndroid Build Coastguard Worker                                                   *pixelOffsets);
1571*35238bceSAndroid Build Coastguard Worker             }
1572*35238bceSAndroid Build Coastguard Worker             else if (isUIntFormatType(m_textureFormat.type) || isSIntFormatType(m_textureFormat.type))
1573*35238bceSAndroid Build Coastguard Worker             {
1574*35238bceSAndroid Build Coastguard Worker                 tcu::IntLookupPrecision lookupPrec;
1575*35238bceSAndroid Build Coastguard Worker                 lookupPrec.colorThreshold = UVec4(0);
1576*35238bceSAndroid Build Coastguard Worker                 lookupPrec.coordBits      = coordBits;
1577*35238bceSAndroid Build Coastguard Worker                 lookupPrec.uvwBits        = uvwBits;
1578*35238bceSAndroid Build Coastguard Worker                 lookupPrec.colorMask      = glu::TextureTestUtil::getCompareMask(pixelFormat);
1579*35238bceSAndroid Build Coastguard Worker 
1580*35238bceSAndroid Build Coastguard Worker                 if (isUIntFormatType(m_textureFormat.type))
1581*35238bceSAndroid Build Coastguard Worker                     return verifyGatherOffsets<uint32_t>(log, rendered, texture, texCoords, sampler, lookupPrec,
1582*35238bceSAndroid Build Coastguard Worker                                                          componentNdx, *pixelOffsets);
1583*35238bceSAndroid Build Coastguard Worker                 else if (isSIntFormatType(m_textureFormat.type))
1584*35238bceSAndroid Build Coastguard Worker                     return verifyGatherOffsets<int32_t>(log, rendered, texture, texCoords, sampler, lookupPrec,
1585*35238bceSAndroid Build Coastguard Worker                                                         componentNdx, *pixelOffsets);
1586*35238bceSAndroid Build Coastguard Worker                 else
1587*35238bceSAndroid Build Coastguard Worker                 {
1588*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
1589*35238bceSAndroid Build Coastguard Worker                     return false;
1590*35238bceSAndroid Build Coastguard Worker                 }
1591*35238bceSAndroid Build Coastguard Worker             }
1592*35238bceSAndroid Build Coastguard Worker             else
1593*35238bceSAndroid Build Coastguard Worker             {
1594*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
1595*35238bceSAndroid Build Coastguard Worker                 return false;
1596*35238bceSAndroid Build Coastguard Worker             }
1597*35238bceSAndroid Build Coastguard Worker         }
1598*35238bceSAndroid Build Coastguard Worker     }
1599*35238bceSAndroid Build Coastguard Worker }
1600*35238bceSAndroid Build Coastguard Worker 
generateBasic2DCaseIterations(GatherType gatherType,const tcu::TextureFormat & textureFormat,const IVec2 & offsetRange)1601*35238bceSAndroid Build Coastguard Worker vector<GatherArgs> generateBasic2DCaseIterations(GatherType gatherType, const tcu::TextureFormat &textureFormat,
1602*35238bceSAndroid Build Coastguard Worker                                                  const IVec2 &offsetRange)
1603*35238bceSAndroid Build Coastguard Worker {
1604*35238bceSAndroid Build Coastguard Worker     const int numComponentCases =
1605*35238bceSAndroid Build Coastguard Worker         isDepthFormat(textureFormat) ?
1606*35238bceSAndroid Build Coastguard Worker             1 :
1607*35238bceSAndroid Build Coastguard Worker             4 + 1; // \note For non-depth textures, test explicit components 0 to 3 and implicit component 0.
1608*35238bceSAndroid Build Coastguard Worker     vector<GatherArgs> result;
1609*35238bceSAndroid Build Coastguard Worker 
1610*35238bceSAndroid Build Coastguard Worker     for (int componentCaseNdx = 0; componentCaseNdx < numComponentCases; componentCaseNdx++)
1611*35238bceSAndroid Build Coastguard Worker     {
1612*35238bceSAndroid Build Coastguard Worker         const int componentNdx = componentCaseNdx - 1;
1613*35238bceSAndroid Build Coastguard Worker 
1614*35238bceSAndroid Build Coastguard Worker         switch (gatherType)
1615*35238bceSAndroid Build Coastguard Worker         {
1616*35238bceSAndroid Build Coastguard Worker         case GATHERTYPE_BASIC:
1617*35238bceSAndroid Build Coastguard Worker             result.push_back(GatherArgs(componentNdx));
1618*35238bceSAndroid Build Coastguard Worker             break;
1619*35238bceSAndroid Build Coastguard Worker 
1620*35238bceSAndroid Build Coastguard Worker         case GATHERTYPE_OFFSET:
1621*35238bceSAndroid Build Coastguard Worker         {
1622*35238bceSAndroid Build Coastguard Worker             const int min  = offsetRange.x();
1623*35238bceSAndroid Build Coastguard Worker             const int max  = offsetRange.y();
1624*35238bceSAndroid Build Coastguard Worker             const int hmin = divRoundToZero(min, 2);
1625*35238bceSAndroid Build Coastguard Worker             const int hmax = divRoundToZero(max, 2);
1626*35238bceSAndroid Build Coastguard Worker 
1627*35238bceSAndroid Build Coastguard Worker             result.push_back(GatherArgs(componentNdx, IVec2(min, max)));
1628*35238bceSAndroid Build Coastguard Worker 
1629*35238bceSAndroid Build Coastguard Worker             if (componentCaseNdx ==
1630*35238bceSAndroid Build Coastguard Worker                 0) // Don't test all offsets variants for all color components (they should be pretty orthogonal).
1631*35238bceSAndroid Build Coastguard Worker             {
1632*35238bceSAndroid Build Coastguard Worker                 result.push_back(GatherArgs(componentNdx, IVec2(min, min)));
1633*35238bceSAndroid Build Coastguard Worker                 result.push_back(GatherArgs(componentNdx, IVec2(max, min)));
1634*35238bceSAndroid Build Coastguard Worker                 result.push_back(GatherArgs(componentNdx, IVec2(max, max)));
1635*35238bceSAndroid Build Coastguard Worker 
1636*35238bceSAndroid Build Coastguard Worker                 result.push_back(GatherArgs(componentNdx, IVec2(0, hmax)));
1637*35238bceSAndroid Build Coastguard Worker                 result.push_back(GatherArgs(componentNdx, IVec2(hmin, 0)));
1638*35238bceSAndroid Build Coastguard Worker                 result.push_back(GatherArgs(componentNdx, IVec2(0, 0)));
1639*35238bceSAndroid Build Coastguard Worker             }
1640*35238bceSAndroid Build Coastguard Worker 
1641*35238bceSAndroid Build Coastguard Worker             break;
1642*35238bceSAndroid Build Coastguard Worker         }
1643*35238bceSAndroid Build Coastguard Worker 
1644*35238bceSAndroid Build Coastguard Worker         case GATHERTYPE_OFFSET_DYNAMIC:
1645*35238bceSAndroid Build Coastguard Worker             result.push_back(GatherArgs(componentNdx));
1646*35238bceSAndroid Build Coastguard Worker             break;
1647*35238bceSAndroid Build Coastguard Worker 
1648*35238bceSAndroid Build Coastguard Worker         case GATHERTYPE_OFFSETS:
1649*35238bceSAndroid Build Coastguard Worker         {
1650*35238bceSAndroid Build Coastguard Worker             const int min  = offsetRange.x();
1651*35238bceSAndroid Build Coastguard Worker             const int max  = offsetRange.y();
1652*35238bceSAndroid Build Coastguard Worker             const int hmin = divRoundToZero(min, 2);
1653*35238bceSAndroid Build Coastguard Worker             const int hmax = divRoundToZero(max, 2);
1654*35238bceSAndroid Build Coastguard Worker 
1655*35238bceSAndroid Build Coastguard Worker             result.push_back(
1656*35238bceSAndroid Build Coastguard Worker                 GatherArgs(componentNdx, IVec2(min, min), IVec2(min, max), IVec2(max, min), IVec2(max, max)));
1657*35238bceSAndroid Build Coastguard Worker 
1658*35238bceSAndroid Build Coastguard Worker             if (componentCaseNdx ==
1659*35238bceSAndroid Build Coastguard Worker                 0) // Don't test all offsets variants for all color components (they should be pretty orthogonal).
1660*35238bceSAndroid Build Coastguard Worker                 result.push_back(
1661*35238bceSAndroid Build Coastguard Worker                     GatherArgs(componentNdx, IVec2(min, hmax), IVec2(hmin, max), IVec2(0, hmax), IVec2(hmax, 0)));
1662*35238bceSAndroid Build Coastguard Worker             break;
1663*35238bceSAndroid Build Coastguard Worker         }
1664*35238bceSAndroid Build Coastguard Worker 
1665*35238bceSAndroid Build Coastguard Worker         default:
1666*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
1667*35238bceSAndroid Build Coastguard Worker         }
1668*35238bceSAndroid Build Coastguard Worker     }
1669*35238bceSAndroid Build Coastguard Worker 
1670*35238bceSAndroid Build Coastguard Worker     return result;
1671*35238bceSAndroid Build Coastguard Worker }
1672*35238bceSAndroid Build Coastguard Worker 
1673*35238bceSAndroid Build Coastguard Worker class TextureGather2DCase : public TextureGatherCase
1674*35238bceSAndroid Build Coastguard Worker {
1675*35238bceSAndroid Build Coastguard Worker public:
TextureGather2DCase(Context & context,const char * name,const char * description,GatherType gatherType,OffsetSize offsetSize,tcu::TextureFormat textureFormat,tcu::Sampler::CompareMode shadowCompareMode,tcu::Sampler::WrapMode wrapS,tcu::Sampler::WrapMode wrapT,const MaybeTextureSwizzle & texSwizzle,tcu::Sampler::FilterMode minFilter,tcu::Sampler::FilterMode magFilter,int baseLevel,uint32_t flags,const IVec2 & textureSize)1676*35238bceSAndroid Build Coastguard Worker     TextureGather2DCase(Context &context, const char *name, const char *description, GatherType gatherType,
1677*35238bceSAndroid Build Coastguard Worker                         OffsetSize offsetSize, tcu::TextureFormat textureFormat,
1678*35238bceSAndroid Build Coastguard Worker                         tcu::Sampler::CompareMode shadowCompareMode, tcu::Sampler::WrapMode wrapS,
1679*35238bceSAndroid Build Coastguard Worker                         tcu::Sampler::WrapMode wrapT, const MaybeTextureSwizzle &texSwizzle,
1680*35238bceSAndroid Build Coastguard Worker                         tcu::Sampler::FilterMode minFilter, tcu::Sampler::FilterMode magFilter, int baseLevel,
1681*35238bceSAndroid Build Coastguard Worker                         uint32_t flags, const IVec2 &textureSize)
1682*35238bceSAndroid Build Coastguard Worker         : TextureGatherCase(context, name, description, TEXTURETYPE_2D, gatherType, offsetSize, textureFormat,
1683*35238bceSAndroid Build Coastguard Worker                             shadowCompareMode, wrapS, wrapT, texSwizzle, minFilter, magFilter, baseLevel, flags)
1684*35238bceSAndroid Build Coastguard Worker         , m_textureSize(textureSize)
1685*35238bceSAndroid Build Coastguard Worker         , m_swizzledTexture(tcu::TextureFormat(), 1, 1)
1686*35238bceSAndroid Build Coastguard Worker     {
1687*35238bceSAndroid Build Coastguard Worker     }
1688*35238bceSAndroid Build Coastguard Worker 
1689*35238bceSAndroid Build Coastguard Worker protected:
1690*35238bceSAndroid Build Coastguard Worker     void generateIterations(void);
1691*35238bceSAndroid Build Coastguard Worker     void createAndUploadTexture(void);
getNumIterations(void) const1692*35238bceSAndroid Build Coastguard Worker     int getNumIterations(void) const
1693*35238bceSAndroid Build Coastguard Worker     {
1694*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(!m_iterations.empty());
1695*35238bceSAndroid Build Coastguard Worker         return (int)m_iterations.size();
1696*35238bceSAndroid Build Coastguard Worker     }
getGatherArgs(int iterationNdx) const1697*35238bceSAndroid Build Coastguard Worker     GatherArgs getGatherArgs(int iterationNdx) const
1698*35238bceSAndroid Build Coastguard Worker     {
1699*35238bceSAndroid Build Coastguard Worker         return m_iterations[iterationNdx];
1700*35238bceSAndroid Build Coastguard Worker     }
1701*35238bceSAndroid Build Coastguard Worker     vector<float> computeQuadTexCoord(int iterationNdx) const;
1702*35238bceSAndroid Build Coastguard Worker     bool verify(int iterationNdx, const ConstPixelBufferAccess &rendered) const;
1703*35238bceSAndroid Build Coastguard Worker 
1704*35238bceSAndroid Build Coastguard Worker private:
1705*35238bceSAndroid Build Coastguard Worker     const IVec2 m_textureSize;
1706*35238bceSAndroid Build Coastguard Worker 
1707*35238bceSAndroid Build Coastguard Worker     MovePtr<glu::Texture2D> m_texture;
1708*35238bceSAndroid Build Coastguard Worker     tcu::Texture2D m_swizzledTexture;
1709*35238bceSAndroid Build Coastguard Worker     vector<GatherArgs> m_iterations;
1710*35238bceSAndroid Build Coastguard Worker };
1711*35238bceSAndroid Build Coastguard Worker 
computeQuadTexCoord(int) const1712*35238bceSAndroid Build Coastguard Worker vector<float> TextureGather2DCase::computeQuadTexCoord(int /* iterationNdx */) const
1713*35238bceSAndroid Build Coastguard Worker {
1714*35238bceSAndroid Build Coastguard Worker     vector<float> res;
1715*35238bceSAndroid Build Coastguard Worker     glu::TextureTestUtil::computeQuadTexCoord2D(res, Vec2(-0.3f, -0.4f), Vec2(1.5f, 1.6f));
1716*35238bceSAndroid Build Coastguard Worker     return res;
1717*35238bceSAndroid Build Coastguard Worker }
1718*35238bceSAndroid Build Coastguard Worker 
generateIterations(void)1719*35238bceSAndroid Build Coastguard Worker void TextureGather2DCase::generateIterations(void)
1720*35238bceSAndroid Build Coastguard Worker {
1721*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_iterations.empty());
1722*35238bceSAndroid Build Coastguard Worker     m_iterations = generateBasic2DCaseIterations(m_gatherType, m_textureFormat, getOffsetRange());
1723*35238bceSAndroid Build Coastguard Worker }
1724*35238bceSAndroid Build Coastguard Worker 
createAndUploadTexture(void)1725*35238bceSAndroid Build Coastguard Worker void TextureGather2DCase::createAndUploadTexture(void)
1726*35238bceSAndroid Build Coastguard Worker {
1727*35238bceSAndroid Build Coastguard Worker     const glu::RenderContext &renderCtx     = m_context.getRenderContext();
1728*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl                = renderCtx.getFunctions();
1729*35238bceSAndroid Build Coastguard Worker     const tcu::TextureFormatInfo texFmtInfo = tcu::getTextureFormatInfo(m_textureFormat);
1730*35238bceSAndroid Build Coastguard Worker 
1731*35238bceSAndroid Build Coastguard Worker     m_texture = MovePtr<glu::Texture2D>(
1732*35238bceSAndroid Build Coastguard Worker         new glu::Texture2D(renderCtx, glu::getInternalFormat(m_textureFormat), m_textureSize.x(), m_textureSize.y()));
1733*35238bceSAndroid Build Coastguard Worker 
1734*35238bceSAndroid Build Coastguard Worker     {
1735*35238bceSAndroid Build Coastguard Worker         tcu::Texture2D &refTexture = m_texture->getRefTexture();
1736*35238bceSAndroid Build Coastguard Worker         const int levelBegin       = m_baseLevel;
1737*35238bceSAndroid Build Coastguard Worker         const int levelEnd         = isMipmapFilter(m_minFilter) && !(m_flags & GATHERCASE_MIPMAP_INCOMPLETE) ?
1738*35238bceSAndroid Build Coastguard Worker                                          refTexture.getNumLevels() :
1739*35238bceSAndroid Build Coastguard Worker                                          m_baseLevel + 1;
1740*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_baseLevel < refTexture.getNumLevels());
1741*35238bceSAndroid Build Coastguard Worker 
1742*35238bceSAndroid Build Coastguard Worker         for (int levelNdx = levelBegin; levelNdx < levelEnd; levelNdx++)
1743*35238bceSAndroid Build Coastguard Worker         {
1744*35238bceSAndroid Build Coastguard Worker             refTexture.allocLevel(levelNdx);
1745*35238bceSAndroid Build Coastguard Worker             const PixelBufferAccess &level = refTexture.getLevel(levelNdx);
1746*35238bceSAndroid Build Coastguard Worker             fillWithRandomColorTiles(level, texFmtInfo.valueMin, texFmtInfo.valueMax,
1747*35238bceSAndroid Build Coastguard Worker                                      (uint32_t)m_testCtx.getCommandLine().getBaseSeed());
1748*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Image("InputTextureLevel" + de::toString(levelNdx),
1749*35238bceSAndroid Build Coastguard Worker                                                  "Input texture, level " + de::toString(levelNdx), level)
1750*35238bceSAndroid Build Coastguard Worker                                << TestLog::Message << "Note: texture level's size is "
1751*35238bceSAndroid Build Coastguard Worker                                << IVec2(level.getWidth(), level.getHeight()) << TestLog::EndMessage;
1752*35238bceSAndroid Build Coastguard Worker         }
1753*35238bceSAndroid Build Coastguard Worker 
1754*35238bceSAndroid Build Coastguard Worker         swizzleTexture(m_swizzledTexture, refTexture, m_textureSwizzle);
1755*35238bceSAndroid Build Coastguard Worker     }
1756*35238bceSAndroid Build Coastguard Worker 
1757*35238bceSAndroid Build Coastguard Worker     gl.activeTexture(GL_TEXTURE0);
1758*35238bceSAndroid Build Coastguard Worker     m_texture->upload();
1759*35238bceSAndroid Build Coastguard Worker }
1760*35238bceSAndroid Build Coastguard Worker 
verify(int iterationNdx,const ConstPixelBufferAccess & rendered) const1761*35238bceSAndroid Build Coastguard Worker bool TextureGather2DCase::verify(int iterationNdx, const ConstPixelBufferAccess &rendered) const
1762*35238bceSAndroid Build Coastguard Worker {
1763*35238bceSAndroid Build Coastguard Worker     Vec2 texCoords[4];
1764*35238bceSAndroid Build Coastguard Worker     computeTexCoordVecs(computeQuadTexCoord(iterationNdx), texCoords);
1765*35238bceSAndroid Build Coastguard Worker     return TextureGatherCase::verify(rendered, getOneLevelSubView(tcu::Texture2DView(m_swizzledTexture), m_baseLevel),
1766*35238bceSAndroid Build Coastguard Worker                                      texCoords, m_iterations[iterationNdx]);
1767*35238bceSAndroid Build Coastguard Worker }
1768*35238bceSAndroid Build Coastguard Worker 
1769*35238bceSAndroid Build Coastguard Worker class TextureGather2DArrayCase : public TextureGatherCase
1770*35238bceSAndroid Build Coastguard Worker {
1771*35238bceSAndroid Build Coastguard Worker public:
TextureGather2DArrayCase(Context & context,const char * name,const char * description,GatherType gatherType,OffsetSize offsetSize,tcu::TextureFormat textureFormat,tcu::Sampler::CompareMode shadowCompareMode,tcu::Sampler::WrapMode wrapS,tcu::Sampler::WrapMode wrapT,const MaybeTextureSwizzle & texSwizzle,tcu::Sampler::FilterMode minFilter,tcu::Sampler::FilterMode magFilter,int baseLevel,uint32_t flags,const IVec3 & textureSize)1772*35238bceSAndroid Build Coastguard Worker     TextureGather2DArrayCase(Context &context, const char *name, const char *description, GatherType gatherType,
1773*35238bceSAndroid Build Coastguard Worker                              OffsetSize offsetSize, tcu::TextureFormat textureFormat,
1774*35238bceSAndroid Build Coastguard Worker                              tcu::Sampler::CompareMode shadowCompareMode, tcu::Sampler::WrapMode wrapS,
1775*35238bceSAndroid Build Coastguard Worker                              tcu::Sampler::WrapMode wrapT, const MaybeTextureSwizzle &texSwizzle,
1776*35238bceSAndroid Build Coastguard Worker                              tcu::Sampler::FilterMode minFilter, tcu::Sampler::FilterMode magFilter, int baseLevel,
1777*35238bceSAndroid Build Coastguard Worker                              uint32_t flags, const IVec3 &textureSize)
1778*35238bceSAndroid Build Coastguard Worker         : TextureGatherCase(context, name, description, TEXTURETYPE_2D_ARRAY, gatherType, offsetSize, textureFormat,
1779*35238bceSAndroid Build Coastguard Worker                             shadowCompareMode, wrapS, wrapT, texSwizzle, minFilter, magFilter, baseLevel, flags)
1780*35238bceSAndroid Build Coastguard Worker         , m_textureSize(textureSize)
1781*35238bceSAndroid Build Coastguard Worker         , m_swizzledTexture(tcu::TextureFormat(), 1, 1, 1)
1782*35238bceSAndroid Build Coastguard Worker     {
1783*35238bceSAndroid Build Coastguard Worker     }
1784*35238bceSAndroid Build Coastguard Worker 
1785*35238bceSAndroid Build Coastguard Worker protected:
1786*35238bceSAndroid Build Coastguard Worker     void generateIterations(void);
1787*35238bceSAndroid Build Coastguard Worker     void createAndUploadTexture(void);
getNumIterations(void) const1788*35238bceSAndroid Build Coastguard Worker     int getNumIterations(void) const
1789*35238bceSAndroid Build Coastguard Worker     {
1790*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(!m_iterations.empty());
1791*35238bceSAndroid Build Coastguard Worker         return (int)m_iterations.size();
1792*35238bceSAndroid Build Coastguard Worker     }
getGatherArgs(int iterationNdx) const1793*35238bceSAndroid Build Coastguard Worker     GatherArgs getGatherArgs(int iterationNdx) const
1794*35238bceSAndroid Build Coastguard Worker     {
1795*35238bceSAndroid Build Coastguard Worker         return m_iterations[iterationNdx].gatherArgs;
1796*35238bceSAndroid Build Coastguard Worker     }
1797*35238bceSAndroid Build Coastguard Worker     vector<float> computeQuadTexCoord(int iterationNdx) const;
1798*35238bceSAndroid Build Coastguard Worker     bool verify(int iterationNdx, const ConstPixelBufferAccess &rendered) const;
1799*35238bceSAndroid Build Coastguard Worker 
1800*35238bceSAndroid Build Coastguard Worker private:
1801*35238bceSAndroid Build Coastguard Worker     struct Iteration
1802*35238bceSAndroid Build Coastguard Worker     {
1803*35238bceSAndroid Build Coastguard Worker         GatherArgs gatherArgs;
1804*35238bceSAndroid Build Coastguard Worker         int layerNdx;
1805*35238bceSAndroid Build Coastguard Worker     };
1806*35238bceSAndroid Build Coastguard Worker 
1807*35238bceSAndroid Build Coastguard Worker     const IVec3 m_textureSize;
1808*35238bceSAndroid Build Coastguard Worker 
1809*35238bceSAndroid Build Coastguard Worker     MovePtr<glu::Texture2DArray> m_texture;
1810*35238bceSAndroid Build Coastguard Worker     tcu::Texture2DArray m_swizzledTexture;
1811*35238bceSAndroid Build Coastguard Worker     vector<Iteration> m_iterations;
1812*35238bceSAndroid Build Coastguard Worker };
1813*35238bceSAndroid Build Coastguard Worker 
computeQuadTexCoord(int iterationNdx) const1814*35238bceSAndroid Build Coastguard Worker vector<float> TextureGather2DArrayCase::computeQuadTexCoord(int iterationNdx) const
1815*35238bceSAndroid Build Coastguard Worker {
1816*35238bceSAndroid Build Coastguard Worker     vector<float> res;
1817*35238bceSAndroid Build Coastguard Worker     glu::TextureTestUtil::computeQuadTexCoord2DArray(res, m_iterations[iterationNdx].layerNdx, Vec2(-0.3f, -0.4f),
1818*35238bceSAndroid Build Coastguard Worker                                                      Vec2(1.5f, 1.6f));
1819*35238bceSAndroid Build Coastguard Worker     return res;
1820*35238bceSAndroid Build Coastguard Worker }
1821*35238bceSAndroid Build Coastguard Worker 
generateIterations(void)1822*35238bceSAndroid Build Coastguard Worker void TextureGather2DArrayCase::generateIterations(void)
1823*35238bceSAndroid Build Coastguard Worker {
1824*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_iterations.empty());
1825*35238bceSAndroid Build Coastguard Worker 
1826*35238bceSAndroid Build Coastguard Worker     const vector<GatherArgs> basicIterations =
1827*35238bceSAndroid Build Coastguard Worker         generateBasic2DCaseIterations(m_gatherType, m_textureFormat, getOffsetRange());
1828*35238bceSAndroid Build Coastguard Worker 
1829*35238bceSAndroid Build Coastguard Worker     // \note Out-of-bounds layer indices are tested too.
1830*35238bceSAndroid Build Coastguard Worker     for (int layerNdx = -1; layerNdx < m_textureSize.z() + 1; layerNdx++)
1831*35238bceSAndroid Build Coastguard Worker     {
1832*35238bceSAndroid Build Coastguard Worker         // Don't duplicate all cases for all layers.
1833*35238bceSAndroid Build Coastguard Worker         if (layerNdx == 0)
1834*35238bceSAndroid Build Coastguard Worker         {
1835*35238bceSAndroid Build Coastguard Worker             for (int basicNdx = 0; basicNdx < (int)basicIterations.size(); basicNdx++)
1836*35238bceSAndroid Build Coastguard Worker             {
1837*35238bceSAndroid Build Coastguard Worker                 m_iterations.push_back(Iteration());
1838*35238bceSAndroid Build Coastguard Worker                 m_iterations.back().gatherArgs = basicIterations[basicNdx];
1839*35238bceSAndroid Build Coastguard Worker                 m_iterations.back().layerNdx   = layerNdx;
1840*35238bceSAndroid Build Coastguard Worker             }
1841*35238bceSAndroid Build Coastguard Worker         }
1842*35238bceSAndroid Build Coastguard Worker         else
1843*35238bceSAndroid Build Coastguard Worker         {
1844*35238bceSAndroid Build Coastguard Worker             // For other layers than 0, only test one component and one set of offsets per layer.
1845*35238bceSAndroid Build Coastguard Worker             for (int basicNdx = 0; basicNdx < (int)basicIterations.size(); basicNdx++)
1846*35238bceSAndroid Build Coastguard Worker             {
1847*35238bceSAndroid Build Coastguard Worker                 if (isDepthFormat(m_textureFormat) || basicIterations[basicNdx].componentNdx == (layerNdx + 2) % 4)
1848*35238bceSAndroid Build Coastguard Worker                 {
1849*35238bceSAndroid Build Coastguard Worker                     m_iterations.push_back(Iteration());
1850*35238bceSAndroid Build Coastguard Worker                     m_iterations.back().gatherArgs = basicIterations[basicNdx];
1851*35238bceSAndroid Build Coastguard Worker                     m_iterations.back().layerNdx   = layerNdx;
1852*35238bceSAndroid Build Coastguard Worker                     break;
1853*35238bceSAndroid Build Coastguard Worker                 }
1854*35238bceSAndroid Build Coastguard Worker             }
1855*35238bceSAndroid Build Coastguard Worker         }
1856*35238bceSAndroid Build Coastguard Worker     }
1857*35238bceSAndroid Build Coastguard Worker }
1858*35238bceSAndroid Build Coastguard Worker 
createAndUploadTexture(void)1859*35238bceSAndroid Build Coastguard Worker void TextureGather2DArrayCase::createAndUploadTexture(void)
1860*35238bceSAndroid Build Coastguard Worker {
1861*35238bceSAndroid Build Coastguard Worker     TestLog &log                            = m_testCtx.getLog();
1862*35238bceSAndroid Build Coastguard Worker     const glu::RenderContext &renderCtx     = m_context.getRenderContext();
1863*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl                = renderCtx.getFunctions();
1864*35238bceSAndroid Build Coastguard Worker     const tcu::TextureFormatInfo texFmtInfo = tcu::getTextureFormatInfo(m_textureFormat);
1865*35238bceSAndroid Build Coastguard Worker 
1866*35238bceSAndroid Build Coastguard Worker     m_texture = MovePtr<glu::Texture2DArray>(new glu::Texture2DArray(
1867*35238bceSAndroid Build Coastguard Worker         renderCtx, glu::getInternalFormat(m_textureFormat), m_textureSize.x(), m_textureSize.y(), m_textureSize.z()));
1868*35238bceSAndroid Build Coastguard Worker 
1869*35238bceSAndroid Build Coastguard Worker     {
1870*35238bceSAndroid Build Coastguard Worker         tcu::Texture2DArray &refTexture = m_texture->getRefTexture();
1871*35238bceSAndroid Build Coastguard Worker         const int levelBegin            = m_baseLevel;
1872*35238bceSAndroid Build Coastguard Worker         const int levelEnd              = isMipmapFilter(m_minFilter) && !(m_flags & GATHERCASE_MIPMAP_INCOMPLETE) ?
1873*35238bceSAndroid Build Coastguard Worker                                               refTexture.getNumLevels() :
1874*35238bceSAndroid Build Coastguard Worker                                               m_baseLevel + 1;
1875*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_baseLevel < refTexture.getNumLevels());
1876*35238bceSAndroid Build Coastguard Worker 
1877*35238bceSAndroid Build Coastguard Worker         for (int levelNdx = levelBegin; levelNdx < levelEnd; levelNdx++)
1878*35238bceSAndroid Build Coastguard Worker         {
1879*35238bceSAndroid Build Coastguard Worker             refTexture.allocLevel(levelNdx);
1880*35238bceSAndroid Build Coastguard Worker             const PixelBufferAccess &level = refTexture.getLevel(levelNdx);
1881*35238bceSAndroid Build Coastguard Worker             fillWithRandomColorTiles(level, texFmtInfo.valueMin, texFmtInfo.valueMax,
1882*35238bceSAndroid Build Coastguard Worker                                      (uint32_t)m_testCtx.getCommandLine().getBaseSeed());
1883*35238bceSAndroid Build Coastguard Worker 
1884*35238bceSAndroid Build Coastguard Worker             log << TestLog::ImageSet("InputTextureLevel", "Input texture, level " + de::toString(levelNdx));
1885*35238bceSAndroid Build Coastguard Worker             for (int layerNdx = 0; layerNdx < m_textureSize.z(); layerNdx++)
1886*35238bceSAndroid Build Coastguard Worker                 log << TestLog::Image("InputTextureLevel" + de::toString(layerNdx) + "Layer" + de::toString(layerNdx),
1887*35238bceSAndroid Build Coastguard Worker                                       "Layer " + de::toString(layerNdx),
1888*35238bceSAndroid Build Coastguard Worker                                       tcu::getSubregion(level, 0, 0, layerNdx, level.getWidth(), level.getHeight(), 1));
1889*35238bceSAndroid Build Coastguard Worker             log << TestLog::EndImageSet << TestLog::Message << "Note: texture level's size is "
1890*35238bceSAndroid Build Coastguard Worker                 << IVec3(level.getWidth(), level.getHeight(), level.getDepth()) << TestLog::EndMessage;
1891*35238bceSAndroid Build Coastguard Worker         }
1892*35238bceSAndroid Build Coastguard Worker 
1893*35238bceSAndroid Build Coastguard Worker         swizzleTexture(m_swizzledTexture, refTexture, m_textureSwizzle);
1894*35238bceSAndroid Build Coastguard Worker     }
1895*35238bceSAndroid Build Coastguard Worker 
1896*35238bceSAndroid Build Coastguard Worker     gl.activeTexture(GL_TEXTURE0);
1897*35238bceSAndroid Build Coastguard Worker     m_texture->upload();
1898*35238bceSAndroid Build Coastguard Worker }
1899*35238bceSAndroid Build Coastguard Worker 
verify(int iterationNdx,const ConstPixelBufferAccess & rendered) const1900*35238bceSAndroid Build Coastguard Worker bool TextureGather2DArrayCase::verify(int iterationNdx, const ConstPixelBufferAccess &rendered) const
1901*35238bceSAndroid Build Coastguard Worker {
1902*35238bceSAndroid Build Coastguard Worker     Vec3 texCoords[4];
1903*35238bceSAndroid Build Coastguard Worker     computeTexCoordVecs(computeQuadTexCoord(iterationNdx), texCoords);
1904*35238bceSAndroid Build Coastguard Worker     return TextureGatherCase::verify(rendered,
1905*35238bceSAndroid Build Coastguard Worker                                      getOneLevelSubView(tcu::Texture2DArrayView(m_swizzledTexture), m_baseLevel),
1906*35238bceSAndroid Build Coastguard Worker                                      texCoords, m_iterations[iterationNdx].gatherArgs);
1907*35238bceSAndroid Build Coastguard Worker }
1908*35238bceSAndroid Build Coastguard Worker 
1909*35238bceSAndroid Build Coastguard Worker // \note Cube case always uses just basic textureGather(); offset versions are not defined for cube maps.
1910*35238bceSAndroid Build Coastguard Worker class TextureGatherCubeCase : public TextureGatherCase
1911*35238bceSAndroid Build Coastguard Worker {
1912*35238bceSAndroid Build Coastguard Worker public:
TextureGatherCubeCase(Context & context,const char * name,const char * description,tcu::TextureFormat textureFormat,tcu::Sampler::CompareMode shadowCompareMode,tcu::Sampler::WrapMode wrapS,tcu::Sampler::WrapMode wrapT,const MaybeTextureSwizzle & texSwizzle,tcu::Sampler::FilterMode minFilter,tcu::Sampler::FilterMode magFilter,int baseLevel,uint32_t flags,int textureSize)1913*35238bceSAndroid Build Coastguard Worker     TextureGatherCubeCase(Context &context, const char *name, const char *description, tcu::TextureFormat textureFormat,
1914*35238bceSAndroid Build Coastguard Worker                           tcu::Sampler::CompareMode shadowCompareMode, tcu::Sampler::WrapMode wrapS,
1915*35238bceSAndroid Build Coastguard Worker                           tcu::Sampler::WrapMode wrapT, const MaybeTextureSwizzle &texSwizzle,
1916*35238bceSAndroid Build Coastguard Worker                           tcu::Sampler::FilterMode minFilter, tcu::Sampler::FilterMode magFilter, int baseLevel,
1917*35238bceSAndroid Build Coastguard Worker                           uint32_t flags, int textureSize)
1918*35238bceSAndroid Build Coastguard Worker         : TextureGatherCase(context, name, description, TEXTURETYPE_CUBE, GATHERTYPE_BASIC, OFFSETSIZE_NONE,
1919*35238bceSAndroid Build Coastguard Worker                             textureFormat, shadowCompareMode, wrapS, wrapT, texSwizzle, minFilter, magFilter, baseLevel,
1920*35238bceSAndroid Build Coastguard Worker                             flags)
1921*35238bceSAndroid Build Coastguard Worker         , m_textureSize(textureSize)
1922*35238bceSAndroid Build Coastguard Worker         , m_swizzledTexture(tcu::TextureFormat(), 1)
1923*35238bceSAndroid Build Coastguard Worker     {
1924*35238bceSAndroid Build Coastguard Worker     }
1925*35238bceSAndroid Build Coastguard Worker 
1926*35238bceSAndroid Build Coastguard Worker protected:
1927*35238bceSAndroid Build Coastguard Worker     void generateIterations(void);
1928*35238bceSAndroid Build Coastguard Worker     void createAndUploadTexture(void);
getNumIterations(void) const1929*35238bceSAndroid Build Coastguard Worker     int getNumIterations(void) const
1930*35238bceSAndroid Build Coastguard Worker     {
1931*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(!m_iterations.empty());
1932*35238bceSAndroid Build Coastguard Worker         return (int)m_iterations.size();
1933*35238bceSAndroid Build Coastguard Worker     }
getGatherArgs(int iterationNdx) const1934*35238bceSAndroid Build Coastguard Worker     GatherArgs getGatherArgs(int iterationNdx) const
1935*35238bceSAndroid Build Coastguard Worker     {
1936*35238bceSAndroid Build Coastguard Worker         return m_iterations[iterationNdx].gatherArgs;
1937*35238bceSAndroid Build Coastguard Worker     }
1938*35238bceSAndroid Build Coastguard Worker     vector<float> computeQuadTexCoord(int iterationNdx) const;
1939*35238bceSAndroid Build Coastguard Worker     bool verify(int iterationNdx, const ConstPixelBufferAccess &rendered) const;
1940*35238bceSAndroid Build Coastguard Worker 
1941*35238bceSAndroid Build Coastguard Worker private:
1942*35238bceSAndroid Build Coastguard Worker     struct Iteration
1943*35238bceSAndroid Build Coastguard Worker     {
1944*35238bceSAndroid Build Coastguard Worker         GatherArgs gatherArgs;
1945*35238bceSAndroid Build Coastguard Worker         tcu::CubeFace face;
1946*35238bceSAndroid Build Coastguard Worker     };
1947*35238bceSAndroid Build Coastguard Worker 
1948*35238bceSAndroid Build Coastguard Worker     const int m_textureSize;
1949*35238bceSAndroid Build Coastguard Worker 
1950*35238bceSAndroid Build Coastguard Worker     MovePtr<glu::TextureCube> m_texture;
1951*35238bceSAndroid Build Coastguard Worker     tcu::TextureCube m_swizzledTexture;
1952*35238bceSAndroid Build Coastguard Worker     vector<Iteration> m_iterations;
1953*35238bceSAndroid Build Coastguard Worker };
1954*35238bceSAndroid Build Coastguard Worker 
computeQuadTexCoord(int iterationNdx) const1955*35238bceSAndroid Build Coastguard Worker vector<float> TextureGatherCubeCase::computeQuadTexCoord(int iterationNdx) const
1956*35238bceSAndroid Build Coastguard Worker {
1957*35238bceSAndroid Build Coastguard Worker     const bool corners = (m_flags & GATHERCASE_DONT_SAMPLE_CUBE_CORNERS) == 0;
1958*35238bceSAndroid Build Coastguard Worker     const Vec2 minC    = corners ? Vec2(-1.2f) : Vec2(-0.6f, -1.2f);
1959*35238bceSAndroid Build Coastguard Worker     const Vec2 maxC    = corners ? Vec2(1.2f) : Vec2(0.6f, 1.2f);
1960*35238bceSAndroid Build Coastguard Worker     vector<float> res;
1961*35238bceSAndroid Build Coastguard Worker     glu::TextureTestUtil::computeQuadTexCoordCube(res, m_iterations[iterationNdx].face, minC, maxC);
1962*35238bceSAndroid Build Coastguard Worker     return res;
1963*35238bceSAndroid Build Coastguard Worker }
1964*35238bceSAndroid Build Coastguard Worker 
generateIterations(void)1965*35238bceSAndroid Build Coastguard Worker void TextureGatherCubeCase::generateIterations(void)
1966*35238bceSAndroid Build Coastguard Worker {
1967*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_iterations.empty());
1968*35238bceSAndroid Build Coastguard Worker 
1969*35238bceSAndroid Build Coastguard Worker     const vector<GatherArgs> basicIterations =
1970*35238bceSAndroid Build Coastguard Worker         generateBasic2DCaseIterations(m_gatherType, m_textureFormat, getOffsetRange());
1971*35238bceSAndroid Build Coastguard Worker 
1972*35238bceSAndroid Build Coastguard Worker     for (int cubeFaceI = 0; cubeFaceI < tcu::CUBEFACE_LAST; cubeFaceI++)
1973*35238bceSAndroid Build Coastguard Worker     {
1974*35238bceSAndroid Build Coastguard Worker         const tcu::CubeFace cubeFace = (tcu::CubeFace)cubeFaceI;
1975*35238bceSAndroid Build Coastguard Worker 
1976*35238bceSAndroid Build Coastguard Worker         // Don't duplicate all cases for all faces.
1977*35238bceSAndroid Build Coastguard Worker         if (cubeFaceI == 0)
1978*35238bceSAndroid Build Coastguard Worker         {
1979*35238bceSAndroid Build Coastguard Worker             for (int basicNdx = 0; basicNdx < (int)basicIterations.size(); basicNdx++)
1980*35238bceSAndroid Build Coastguard Worker             {
1981*35238bceSAndroid Build Coastguard Worker                 m_iterations.push_back(Iteration());
1982*35238bceSAndroid Build Coastguard Worker                 m_iterations.back().gatherArgs = basicIterations[basicNdx];
1983*35238bceSAndroid Build Coastguard Worker                 m_iterations.back().face       = cubeFace;
1984*35238bceSAndroid Build Coastguard Worker             }
1985*35238bceSAndroid Build Coastguard Worker         }
1986*35238bceSAndroid Build Coastguard Worker         else
1987*35238bceSAndroid Build Coastguard Worker         {
1988*35238bceSAndroid Build Coastguard Worker             // For other faces than first, only test one component per face.
1989*35238bceSAndroid Build Coastguard Worker             for (int basicNdx = 0; basicNdx < (int)basicIterations.size(); basicNdx++)
1990*35238bceSAndroid Build Coastguard Worker             {
1991*35238bceSAndroid Build Coastguard Worker                 if (isDepthFormat(m_textureFormat) || basicIterations[basicNdx].componentNdx == cubeFaceI % 4)
1992*35238bceSAndroid Build Coastguard Worker                 {
1993*35238bceSAndroid Build Coastguard Worker                     m_iterations.push_back(Iteration());
1994*35238bceSAndroid Build Coastguard Worker                     m_iterations.back().gatherArgs = basicIterations[basicNdx];
1995*35238bceSAndroid Build Coastguard Worker                     m_iterations.back().face       = cubeFace;
1996*35238bceSAndroid Build Coastguard Worker                     break;
1997*35238bceSAndroid Build Coastguard Worker                 }
1998*35238bceSAndroid Build Coastguard Worker             }
1999*35238bceSAndroid Build Coastguard Worker         }
2000*35238bceSAndroid Build Coastguard Worker     }
2001*35238bceSAndroid Build Coastguard Worker }
2002*35238bceSAndroid Build Coastguard Worker 
createAndUploadTexture(void)2003*35238bceSAndroid Build Coastguard Worker void TextureGatherCubeCase::createAndUploadTexture(void)
2004*35238bceSAndroid Build Coastguard Worker {
2005*35238bceSAndroid Build Coastguard Worker     TestLog &log                            = m_testCtx.getLog();
2006*35238bceSAndroid Build Coastguard Worker     const glu::RenderContext &renderCtx     = m_context.getRenderContext();
2007*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl                = renderCtx.getFunctions();
2008*35238bceSAndroid Build Coastguard Worker     const tcu::TextureFormatInfo texFmtInfo = tcu::getTextureFormatInfo(m_textureFormat);
2009*35238bceSAndroid Build Coastguard Worker 
2010*35238bceSAndroid Build Coastguard Worker     m_texture = MovePtr<glu::TextureCube>(
2011*35238bceSAndroid Build Coastguard Worker         new glu::TextureCube(renderCtx, glu::getInternalFormat(m_textureFormat), m_textureSize));
2012*35238bceSAndroid Build Coastguard Worker 
2013*35238bceSAndroid Build Coastguard Worker     {
2014*35238bceSAndroid Build Coastguard Worker         tcu::TextureCube &refTexture = m_texture->getRefTexture();
2015*35238bceSAndroid Build Coastguard Worker         const int levelBegin         = m_baseLevel;
2016*35238bceSAndroid Build Coastguard Worker         const int levelEnd           = isMipmapFilter(m_minFilter) && !(m_flags & GATHERCASE_MIPMAP_INCOMPLETE) ?
2017*35238bceSAndroid Build Coastguard Worker                                            refTexture.getNumLevels() :
2018*35238bceSAndroid Build Coastguard Worker                                            m_baseLevel + 1;
2019*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_baseLevel < refTexture.getNumLevels());
2020*35238bceSAndroid Build Coastguard Worker 
2021*35238bceSAndroid Build Coastguard Worker         for (int levelNdx = levelBegin; levelNdx < levelEnd; levelNdx++)
2022*35238bceSAndroid Build Coastguard Worker         {
2023*35238bceSAndroid Build Coastguard Worker             log << TestLog::ImageSet("InputTextureLevel" + de::toString(levelNdx),
2024*35238bceSAndroid Build Coastguard Worker                                      "Input texture, level " + de::toString(levelNdx));
2025*35238bceSAndroid Build Coastguard Worker 
2026*35238bceSAndroid Build Coastguard Worker             for (int cubeFaceI = 0; cubeFaceI < tcu::CUBEFACE_LAST; cubeFaceI++)
2027*35238bceSAndroid Build Coastguard Worker             {
2028*35238bceSAndroid Build Coastguard Worker                 const tcu::CubeFace cubeFace = (tcu::CubeFace)cubeFaceI;
2029*35238bceSAndroid Build Coastguard Worker                 refTexture.allocLevel(cubeFace, levelNdx);
2030*35238bceSAndroid Build Coastguard Worker                 const PixelBufferAccess &levelFace = refTexture.getLevelFace(levelNdx, cubeFace);
2031*35238bceSAndroid Build Coastguard Worker                 fillWithRandomColorTiles(levelFace, texFmtInfo.valueMin, texFmtInfo.valueMax,
2032*35238bceSAndroid Build Coastguard Worker                                          (uint32_t)m_testCtx.getCommandLine().getBaseSeed() ^ (uint32_t)cubeFaceI);
2033*35238bceSAndroid Build Coastguard Worker 
2034*35238bceSAndroid Build Coastguard Worker                 m_testCtx.getLog() << TestLog::Image("InputTextureLevel" + de::toString(levelNdx) + "Face" +
2035*35238bceSAndroid Build Coastguard Worker                                                          de::toString((int)cubeFace),
2036*35238bceSAndroid Build Coastguard Worker                                                      de::toString(cubeFace), levelFace);
2037*35238bceSAndroid Build Coastguard Worker             }
2038*35238bceSAndroid Build Coastguard Worker 
2039*35238bceSAndroid Build Coastguard Worker             log << TestLog::EndImageSet << TestLog::Message << "Note: texture level's size is "
2040*35238bceSAndroid Build Coastguard Worker                 << refTexture.getLevelFace(levelNdx, tcu::CUBEFACE_NEGATIVE_X).getWidth() << TestLog::EndMessage;
2041*35238bceSAndroid Build Coastguard Worker         }
2042*35238bceSAndroid Build Coastguard Worker 
2043*35238bceSAndroid Build Coastguard Worker         swizzleTexture(m_swizzledTexture, refTexture, m_textureSwizzle);
2044*35238bceSAndroid Build Coastguard Worker     }
2045*35238bceSAndroid Build Coastguard Worker 
2046*35238bceSAndroid Build Coastguard Worker     gl.activeTexture(GL_TEXTURE0);
2047*35238bceSAndroid Build Coastguard Worker     m_texture->upload();
2048*35238bceSAndroid Build Coastguard Worker }
2049*35238bceSAndroid Build Coastguard Worker 
verify(int iterationNdx,const ConstPixelBufferAccess & rendered) const2050*35238bceSAndroid Build Coastguard Worker bool TextureGatherCubeCase::verify(int iterationNdx, const ConstPixelBufferAccess &rendered) const
2051*35238bceSAndroid Build Coastguard Worker {
2052*35238bceSAndroid Build Coastguard Worker     Vec3 texCoords[4];
2053*35238bceSAndroid Build Coastguard Worker     computeTexCoordVecs(computeQuadTexCoord(iterationNdx), texCoords);
2054*35238bceSAndroid Build Coastguard Worker     return TextureGatherCase::verify(rendered, getOneLevelSubView(tcu::TextureCubeView(m_swizzledTexture), m_baseLevel),
2055*35238bceSAndroid Build Coastguard Worker                                      texCoords, m_iterations[iterationNdx].gatherArgs);
2056*35238bceSAndroid Build Coastguard Worker }
2057*35238bceSAndroid Build Coastguard Worker 
makeTextureGatherCase(TextureType textureType,Context & context,const char * name,const char * description,GatherType gatherType,OffsetSize offsetSize,tcu::TextureFormat textureFormat,tcu::Sampler::CompareMode shadowCompareMode,tcu::Sampler::WrapMode wrapS,tcu::Sampler::WrapMode wrapT,const MaybeTextureSwizzle & texSwizzle,tcu::Sampler::FilterMode minFilter,tcu::Sampler::FilterMode magFilter,int baseLevel,const IVec3 & textureSize,uint32_t flags=0)2058*35238bceSAndroid Build Coastguard Worker static inline TextureGatherCase *makeTextureGatherCase(
2059*35238bceSAndroid Build Coastguard Worker     TextureType textureType, Context &context, const char *name, const char *description, GatherType gatherType,
2060*35238bceSAndroid Build Coastguard Worker     OffsetSize offsetSize, tcu::TextureFormat textureFormat, tcu::Sampler::CompareMode shadowCompareMode,
2061*35238bceSAndroid Build Coastguard Worker     tcu::Sampler::WrapMode wrapS, tcu::Sampler::WrapMode wrapT, const MaybeTextureSwizzle &texSwizzle,
2062*35238bceSAndroid Build Coastguard Worker     tcu::Sampler::FilterMode minFilter, tcu::Sampler::FilterMode magFilter, int baseLevel, const IVec3 &textureSize,
2063*35238bceSAndroid Build Coastguard Worker     uint32_t flags = 0)
2064*35238bceSAndroid Build Coastguard Worker {
2065*35238bceSAndroid Build Coastguard Worker     switch (textureType)
2066*35238bceSAndroid Build Coastguard Worker     {
2067*35238bceSAndroid Build Coastguard Worker     case TEXTURETYPE_2D:
2068*35238bceSAndroid Build Coastguard Worker         return new TextureGather2DCase(context, name, description, gatherType, offsetSize, textureFormat,
2069*35238bceSAndroid Build Coastguard Worker                                        shadowCompareMode, wrapS, wrapT, texSwizzle, minFilter, magFilter, baseLevel,
2070*35238bceSAndroid Build Coastguard Worker                                        flags, textureSize.swizzle(0, 1));
2071*35238bceSAndroid Build Coastguard Worker 
2072*35238bceSAndroid Build Coastguard Worker     case TEXTURETYPE_2D_ARRAY:
2073*35238bceSAndroid Build Coastguard Worker         return new TextureGather2DArrayCase(context, name, description, gatherType, offsetSize, textureFormat,
2074*35238bceSAndroid Build Coastguard Worker                                             shadowCompareMode, wrapS, wrapT, texSwizzle, minFilter, magFilter,
2075*35238bceSAndroid Build Coastguard Worker                                             baseLevel, flags, textureSize);
2076*35238bceSAndroid Build Coastguard Worker 
2077*35238bceSAndroid Build Coastguard Worker     case TEXTURETYPE_CUBE:
2078*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(gatherType == GATHERTYPE_BASIC);
2079*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(offsetSize == OFFSETSIZE_NONE);
2080*35238bceSAndroid Build Coastguard Worker         return new TextureGatherCubeCase(context, name, description, textureFormat, shadowCompareMode, wrapS, wrapT,
2081*35238bceSAndroid Build Coastguard Worker                                          texSwizzle, minFilter, magFilter, baseLevel, flags, textureSize.x());
2082*35238bceSAndroid Build Coastguard Worker 
2083*35238bceSAndroid Build Coastguard Worker     default:
2084*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2085*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
2086*35238bceSAndroid Build Coastguard Worker     }
2087*35238bceSAndroid Build Coastguard Worker }
2088*35238bceSAndroid Build Coastguard Worker 
2089*35238bceSAndroid Build Coastguard Worker } // namespace
2090*35238bceSAndroid Build Coastguard Worker 
TextureGatherTests(Context & context)2091*35238bceSAndroid Build Coastguard Worker TextureGatherTests::TextureGatherTests(Context &context) : TestCaseGroup(context, "gather", "textureGather* tests")
2092*35238bceSAndroid Build Coastguard Worker {
2093*35238bceSAndroid Build Coastguard Worker }
2094*35238bceSAndroid Build Coastguard Worker 
compareModeName(tcu::Sampler::CompareMode mode)2095*35238bceSAndroid Build Coastguard Worker static inline const char *compareModeName(tcu::Sampler::CompareMode mode)
2096*35238bceSAndroid Build Coastguard Worker {
2097*35238bceSAndroid Build Coastguard Worker     switch (mode)
2098*35238bceSAndroid Build Coastguard Worker     {
2099*35238bceSAndroid Build Coastguard Worker     case tcu::Sampler::COMPAREMODE_LESS:
2100*35238bceSAndroid Build Coastguard Worker         return "less";
2101*35238bceSAndroid Build Coastguard Worker     case tcu::Sampler::COMPAREMODE_LESS_OR_EQUAL:
2102*35238bceSAndroid Build Coastguard Worker         return "less_or_equal";
2103*35238bceSAndroid Build Coastguard Worker     case tcu::Sampler::COMPAREMODE_GREATER:
2104*35238bceSAndroid Build Coastguard Worker         return "greater";
2105*35238bceSAndroid Build Coastguard Worker     case tcu::Sampler::COMPAREMODE_GREATER_OR_EQUAL:
2106*35238bceSAndroid Build Coastguard Worker         return "greater_or_equal";
2107*35238bceSAndroid Build Coastguard Worker     case tcu::Sampler::COMPAREMODE_EQUAL:
2108*35238bceSAndroid Build Coastguard Worker         return "equal";
2109*35238bceSAndroid Build Coastguard Worker     case tcu::Sampler::COMPAREMODE_NOT_EQUAL:
2110*35238bceSAndroid Build Coastguard Worker         return "not_equal";
2111*35238bceSAndroid Build Coastguard Worker     case tcu::Sampler::COMPAREMODE_ALWAYS:
2112*35238bceSAndroid Build Coastguard Worker         return "always";
2113*35238bceSAndroid Build Coastguard Worker     case tcu::Sampler::COMPAREMODE_NEVER:
2114*35238bceSAndroid Build Coastguard Worker         return "never";
2115*35238bceSAndroid Build Coastguard Worker     default:
2116*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
2117*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
2118*35238bceSAndroid Build Coastguard Worker     }
2119*35238bceSAndroid Build Coastguard Worker }
2120*35238bceSAndroid Build Coastguard Worker 
init(void)2121*35238bceSAndroid Build Coastguard Worker void TextureGatherTests::init(void)
2122*35238bceSAndroid Build Coastguard Worker {
2123*35238bceSAndroid Build Coastguard Worker     const struct
2124*35238bceSAndroid Build Coastguard Worker     {
2125*35238bceSAndroid Build Coastguard Worker         const char *name;
2126*35238bceSAndroid Build Coastguard Worker         TextureType type;
2127*35238bceSAndroid Build Coastguard Worker     } textureTypes[] = {{"2d", TEXTURETYPE_2D}, {"2d_array", TEXTURETYPE_2D_ARRAY}, {"cube", TEXTURETYPE_CUBE}};
2128*35238bceSAndroid Build Coastguard Worker 
2129*35238bceSAndroid Build Coastguard Worker     const struct
2130*35238bceSAndroid Build Coastguard Worker     {
2131*35238bceSAndroid Build Coastguard Worker         const char *name;
2132*35238bceSAndroid Build Coastguard Worker         tcu::TextureFormat format;
2133*35238bceSAndroid Build Coastguard Worker     } formats[] = {{"rgba8", tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)},
2134*35238bceSAndroid Build Coastguard Worker                    {"rgba8ui", tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8)},
2135*35238bceSAndroid Build Coastguard Worker                    {"rgba8i", tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT8)},
2136*35238bceSAndroid Build Coastguard Worker                    {"depth32f", tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT)}};
2137*35238bceSAndroid Build Coastguard Worker 
2138*35238bceSAndroid Build Coastguard Worker     const struct
2139*35238bceSAndroid Build Coastguard Worker     {
2140*35238bceSAndroid Build Coastguard Worker         const char *name;
2141*35238bceSAndroid Build Coastguard Worker         IVec3 size;
2142*35238bceSAndroid Build Coastguard Worker     } textureSizes[] = {{"size_pot", IVec3(64, 64, 3)}, {"size_npot", IVec3(17, 23, 3)}};
2143*35238bceSAndroid Build Coastguard Worker 
2144*35238bceSAndroid Build Coastguard Worker     const struct
2145*35238bceSAndroid Build Coastguard Worker     {
2146*35238bceSAndroid Build Coastguard Worker         const char *name;
2147*35238bceSAndroid Build Coastguard Worker         tcu::Sampler::WrapMode mode;
2148*35238bceSAndroid Build Coastguard Worker     } wrapModes[] = {{"clamp_to_edge", tcu::Sampler::CLAMP_TO_EDGE},
2149*35238bceSAndroid Build Coastguard Worker                      {"repeat", tcu::Sampler::REPEAT_GL},
2150*35238bceSAndroid Build Coastguard Worker                      {"mirrored_repeat", tcu::Sampler::MIRRORED_REPEAT_GL}};
2151*35238bceSAndroid Build Coastguard Worker 
2152*35238bceSAndroid Build Coastguard Worker     for (int gatherTypeI = 0; gatherTypeI < GATHERTYPE_LAST; gatherTypeI++)
2153*35238bceSAndroid Build Coastguard Worker     {
2154*35238bceSAndroid Build Coastguard Worker         const GatherType gatherType = (GatherType)gatherTypeI;
2155*35238bceSAndroid Build Coastguard Worker         TestCaseGroup *const gatherTypeGroup =
2156*35238bceSAndroid Build Coastguard Worker             new TestCaseGroup(m_context, gatherTypeName(gatherType), gatherTypeDescription(gatherType));
2157*35238bceSAndroid Build Coastguard Worker         addChild(gatherTypeGroup);
2158*35238bceSAndroid Build Coastguard Worker 
2159*35238bceSAndroid Build Coastguard Worker         for (int offsetSizeI = 0; offsetSizeI < OFFSETSIZE_LAST; offsetSizeI++)
2160*35238bceSAndroid Build Coastguard Worker         {
2161*35238bceSAndroid Build Coastguard Worker             const OffsetSize offsetSize = (OffsetSize)offsetSizeI;
2162*35238bceSAndroid Build Coastguard Worker             if ((gatherType == GATHERTYPE_BASIC) != (offsetSize == OFFSETSIZE_NONE))
2163*35238bceSAndroid Build Coastguard Worker                 continue;
2164*35238bceSAndroid Build Coastguard Worker 
2165*35238bceSAndroid Build Coastguard Worker             TestCaseGroup *const offsetSizeGroup =
2166*35238bceSAndroid Build Coastguard Worker                 offsetSize == OFFSETSIZE_NONE ?
2167*35238bceSAndroid Build Coastguard Worker                     gatherTypeGroup :
2168*35238bceSAndroid Build Coastguard Worker                     new TestCaseGroup(m_context,
2169*35238bceSAndroid Build Coastguard Worker                                       offsetSize == OFFSETSIZE_MINIMUM_REQUIRED       ? "min_required_offset" :
2170*35238bceSAndroid Build Coastguard Worker                                       offsetSize == OFFSETSIZE_IMPLEMENTATION_MAXIMUM ? "implementation_offset" :
2171*35238bceSAndroid Build Coastguard Worker                                                                                         DE_NULL,
2172*35238bceSAndroid Build Coastguard Worker                                       offsetSize == OFFSETSIZE_MINIMUM_REQUIRED ?
2173*35238bceSAndroid Build Coastguard Worker                                           "Use offsets within GL minimum required range" :
2174*35238bceSAndroid Build Coastguard Worker                                       offsetSize == OFFSETSIZE_IMPLEMENTATION_MAXIMUM ?
2175*35238bceSAndroid Build Coastguard Worker                                           "Use offsets within the implementation range" :
2176*35238bceSAndroid Build Coastguard Worker                                           DE_NULL);
2177*35238bceSAndroid Build Coastguard Worker             if (offsetSizeGroup != gatherTypeGroup)
2178*35238bceSAndroid Build Coastguard Worker                 gatherTypeGroup->addChild(offsetSizeGroup);
2179*35238bceSAndroid Build Coastguard Worker 
2180*35238bceSAndroid Build Coastguard Worker             for (int textureTypeNdx = 0; textureTypeNdx < DE_LENGTH_OF_ARRAY(textureTypes); textureTypeNdx++)
2181*35238bceSAndroid Build Coastguard Worker             {
2182*35238bceSAndroid Build Coastguard Worker                 const TextureType textureType = textureTypes[textureTypeNdx].type;
2183*35238bceSAndroid Build Coastguard Worker 
2184*35238bceSAndroid Build Coastguard Worker                 if (textureType == TEXTURETYPE_CUBE && gatherType != GATHERTYPE_BASIC)
2185*35238bceSAndroid Build Coastguard Worker                     continue;
2186*35238bceSAndroid Build Coastguard Worker 
2187*35238bceSAndroid Build Coastguard Worker                 TestCaseGroup *const textureTypeGroup =
2188*35238bceSAndroid Build Coastguard Worker                     new TestCaseGroup(m_context, textureTypes[textureTypeNdx].name, "");
2189*35238bceSAndroid Build Coastguard Worker                 offsetSizeGroup->addChild(textureTypeGroup);
2190*35238bceSAndroid Build Coastguard Worker 
2191*35238bceSAndroid Build Coastguard Worker                 for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
2192*35238bceSAndroid Build Coastguard Worker                 {
2193*35238bceSAndroid Build Coastguard Worker                     const tcu::TextureFormat &format = formats[formatNdx].format;
2194*35238bceSAndroid Build Coastguard Worker                     TestCaseGroup *const formatGroup = new TestCaseGroup(m_context, formats[formatNdx].name, "");
2195*35238bceSAndroid Build Coastguard Worker                     textureTypeGroup->addChild(formatGroup);
2196*35238bceSAndroid Build Coastguard Worker 
2197*35238bceSAndroid Build Coastguard Worker                     for (int noCornersI = 0; noCornersI <= ((textureType == TEXTURETYPE_CUBE) ? 1 : 0); noCornersI++)
2198*35238bceSAndroid Build Coastguard Worker                     {
2199*35238bceSAndroid Build Coastguard Worker                         const bool noCorners = noCornersI != 0;
2200*35238bceSAndroid Build Coastguard Worker                         TestCaseGroup *const cornersGroup =
2201*35238bceSAndroid Build Coastguard Worker                             noCorners ?
2202*35238bceSAndroid Build Coastguard Worker                                 new TestCaseGroup(m_context, "no_corners",
2203*35238bceSAndroid Build Coastguard Worker                                                   "Test case variants that don't sample around cube map corners") :
2204*35238bceSAndroid Build Coastguard Worker                                 formatGroup;
2205*35238bceSAndroid Build Coastguard Worker 
2206*35238bceSAndroid Build Coastguard Worker                         if (formatGroup != cornersGroup)
2207*35238bceSAndroid Build Coastguard Worker                             formatGroup->addChild(cornersGroup);
2208*35238bceSAndroid Build Coastguard Worker 
2209*35238bceSAndroid Build Coastguard Worker                         for (int textureSizeNdx = 0; textureSizeNdx < DE_LENGTH_OF_ARRAY(textureSizes);
2210*35238bceSAndroid Build Coastguard Worker                              textureSizeNdx++)
2211*35238bceSAndroid Build Coastguard Worker                         {
2212*35238bceSAndroid Build Coastguard Worker                             const IVec3 &textureSize = textureSizes[textureSizeNdx].size;
2213*35238bceSAndroid Build Coastguard Worker                             TestCaseGroup *const textureSizeGroup =
2214*35238bceSAndroid Build Coastguard Worker                                 new TestCaseGroup(m_context, textureSizes[textureSizeNdx].name, "");
2215*35238bceSAndroid Build Coastguard Worker                             cornersGroup->addChild(textureSizeGroup);
2216*35238bceSAndroid Build Coastguard Worker 
2217*35238bceSAndroid Build Coastguard Worker                             for (int compareModeI = 0; compareModeI < tcu::Sampler::COMPAREMODE_LAST; compareModeI++)
2218*35238bceSAndroid Build Coastguard Worker                             {
2219*35238bceSAndroid Build Coastguard Worker                                 const tcu::Sampler::CompareMode compareMode = (tcu::Sampler::CompareMode)compareModeI;
2220*35238bceSAndroid Build Coastguard Worker 
2221*35238bceSAndroid Build Coastguard Worker                                 if ((compareMode != tcu::Sampler::COMPAREMODE_NONE) != isDepthFormat(format))
2222*35238bceSAndroid Build Coastguard Worker                                     continue;
2223*35238bceSAndroid Build Coastguard Worker 
2224*35238bceSAndroid Build Coastguard Worker                                 if (compareMode != tcu::Sampler::COMPAREMODE_NONE &&
2225*35238bceSAndroid Build Coastguard Worker                                     compareMode != tcu::Sampler::COMPAREMODE_LESS &&
2226*35238bceSAndroid Build Coastguard Worker                                     compareMode != tcu::Sampler::COMPAREMODE_GREATER)
2227*35238bceSAndroid Build Coastguard Worker                                     continue;
2228*35238bceSAndroid Build Coastguard Worker 
2229*35238bceSAndroid Build Coastguard Worker                                 TestCaseGroup *const compareModeGroup =
2230*35238bceSAndroid Build Coastguard Worker                                     compareMode == tcu::Sampler::COMPAREMODE_NONE ?
2231*35238bceSAndroid Build Coastguard Worker                                         textureSizeGroup :
2232*35238bceSAndroid Build Coastguard Worker                                         new TestCaseGroup(
2233*35238bceSAndroid Build Coastguard Worker                                             m_context, (string() + "compare_" + compareModeName(compareMode)).c_str(),
2234*35238bceSAndroid Build Coastguard Worker                                             "");
2235*35238bceSAndroid Build Coastguard Worker                                 if (compareModeGroup != textureSizeGroup)
2236*35238bceSAndroid Build Coastguard Worker                                     textureSizeGroup->addChild(compareModeGroup);
2237*35238bceSAndroid Build Coastguard Worker 
2238*35238bceSAndroid Build Coastguard Worker                                 for (int wrapCaseNdx = 0; wrapCaseNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapCaseNdx++)
2239*35238bceSAndroid Build Coastguard Worker                                 {
2240*35238bceSAndroid Build Coastguard Worker                                     const int wrapSNdx = wrapCaseNdx;
2241*35238bceSAndroid Build Coastguard Worker                                     const int wrapTNdx = (wrapCaseNdx + 1) % DE_LENGTH_OF_ARRAY(wrapModes);
2242*35238bceSAndroid Build Coastguard Worker                                     const tcu::Sampler::WrapMode wrapS = wrapModes[wrapSNdx].mode;
2243*35238bceSAndroid Build Coastguard Worker                                     const tcu::Sampler::WrapMode wrapT = wrapModes[wrapTNdx].mode;
2244*35238bceSAndroid Build Coastguard Worker 
2245*35238bceSAndroid Build Coastguard Worker                                     const string caseName =
2246*35238bceSAndroid Build Coastguard Worker                                         string() + wrapModes[wrapSNdx].name + "_" + wrapModes[wrapTNdx].name;
2247*35238bceSAndroid Build Coastguard Worker 
2248*35238bceSAndroid Build Coastguard Worker                                     compareModeGroup->addChild(makeTextureGatherCase(
2249*35238bceSAndroid Build Coastguard Worker                                         textureType, m_context, caseName.c_str(), "", gatherType, offsetSize, format,
2250*35238bceSAndroid Build Coastguard Worker                                         compareMode, wrapS, wrapT, MaybeTextureSwizzle::createNoneTextureSwizzle(),
2251*35238bceSAndroid Build Coastguard Worker                                         tcu::Sampler::NEAREST, tcu::Sampler::NEAREST, 0, textureSize,
2252*35238bceSAndroid Build Coastguard Worker                                         noCorners ? GATHERCASE_DONT_SAMPLE_CUBE_CORNERS : 0));
2253*35238bceSAndroid Build Coastguard Worker                                 }
2254*35238bceSAndroid Build Coastguard Worker                             }
2255*35238bceSAndroid Build Coastguard Worker                         }
2256*35238bceSAndroid Build Coastguard Worker                     }
2257*35238bceSAndroid Build Coastguard Worker 
2258*35238bceSAndroid Build Coastguard Worker                     if (offsetSize !=
2259*35238bceSAndroid Build Coastguard Worker                         OFFSETSIZE_MINIMUM_REQUIRED) // Don't test all features for both offset size types, as they should be rather orthogonal.
2260*35238bceSAndroid Build Coastguard Worker                     {
2261*35238bceSAndroid Build Coastguard Worker                         if (!isDepthFormat(format))
2262*35238bceSAndroid Build Coastguard Worker                         {
2263*35238bceSAndroid Build Coastguard Worker                             TestCaseGroup *const swizzleGroup = new TestCaseGroup(m_context, "texture_swizzle", "");
2264*35238bceSAndroid Build Coastguard Worker                             formatGroup->addChild(swizzleGroup);
2265*35238bceSAndroid Build Coastguard Worker 
2266*35238bceSAndroid Build Coastguard Worker                             DE_STATIC_ASSERT(TEXTURESWIZZLECOMPONENT_R == 0);
2267*35238bceSAndroid Build Coastguard Worker                             for (int swizzleCaseNdx = 0; swizzleCaseNdx < TEXTURESWIZZLECOMPONENT_LAST;
2268*35238bceSAndroid Build Coastguard Worker                                  swizzleCaseNdx++)
2269*35238bceSAndroid Build Coastguard Worker                             {
2270*35238bceSAndroid Build Coastguard Worker                                 MaybeTextureSwizzle swizzle = MaybeTextureSwizzle::createSomeTextureSwizzle();
2271*35238bceSAndroid Build Coastguard Worker                                 string caseName;
2272*35238bceSAndroid Build Coastguard Worker 
2273*35238bceSAndroid Build Coastguard Worker                                 for (int i = 0; i < 4; i++)
2274*35238bceSAndroid Build Coastguard Worker                                 {
2275*35238bceSAndroid Build Coastguard Worker                                     swizzle.getSwizzle()[i] =
2276*35238bceSAndroid Build Coastguard Worker                                         (TextureSwizzleComponent)((swizzleCaseNdx + i) %
2277*35238bceSAndroid Build Coastguard Worker                                                                   (int)TEXTURESWIZZLECOMPONENT_LAST);
2278*35238bceSAndroid Build Coastguard Worker                                     caseName += (i > 0 ? "_" : "") + de::toLower(de::toString(swizzle.getSwizzle()[i]));
2279*35238bceSAndroid Build Coastguard Worker                                 }
2280*35238bceSAndroid Build Coastguard Worker 
2281*35238bceSAndroid Build Coastguard Worker                                 swizzleGroup->addChild(makeTextureGatherCase(
2282*35238bceSAndroid Build Coastguard Worker                                     textureType, m_context, caseName.c_str(), "", gatherType, offsetSize, format,
2283*35238bceSAndroid Build Coastguard Worker                                     tcu::Sampler::COMPAREMODE_NONE, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
2284*35238bceSAndroid Build Coastguard Worker                                     swizzle, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST, 0, IVec3(64, 64, 3)));
2285*35238bceSAndroid Build Coastguard Worker                             }
2286*35238bceSAndroid Build Coastguard Worker                         }
2287*35238bceSAndroid Build Coastguard Worker 
2288*35238bceSAndroid Build Coastguard Worker                         {
2289*35238bceSAndroid Build Coastguard Worker                             TestCaseGroup *const filterModeGroup =
2290*35238bceSAndroid Build Coastguard Worker                                 new TestCaseGroup(m_context, "filter_mode", "Test that filter modes have no effect");
2291*35238bceSAndroid Build Coastguard Worker                             formatGroup->addChild(filterModeGroup);
2292*35238bceSAndroid Build Coastguard Worker 
2293*35238bceSAndroid Build Coastguard Worker                             const struct
2294*35238bceSAndroid Build Coastguard Worker                             {
2295*35238bceSAndroid Build Coastguard Worker                                 const char *name;
2296*35238bceSAndroid Build Coastguard Worker                                 tcu::Sampler::FilterMode filter;
2297*35238bceSAndroid Build Coastguard Worker                             } magFilters[] = {{"linear", tcu::Sampler::LINEAR}, {"nearest", tcu::Sampler::NEAREST}};
2298*35238bceSAndroid Build Coastguard Worker 
2299*35238bceSAndroid Build Coastguard Worker                             const struct
2300*35238bceSAndroid Build Coastguard Worker                             {
2301*35238bceSAndroid Build Coastguard Worker                                 const char *name;
2302*35238bceSAndroid Build Coastguard Worker                                 tcu::Sampler::FilterMode filter;
2303*35238bceSAndroid Build Coastguard Worker                             } minFilters[] = {
2304*35238bceSAndroid Build Coastguard Worker                                 // \note Don't test NEAREST here, as it's covered by other cases.
2305*35238bceSAndroid Build Coastguard Worker                                 {"linear", tcu::Sampler::LINEAR},
2306*35238bceSAndroid Build Coastguard Worker                                 {"nearest_mipmap_nearest", tcu::Sampler::NEAREST_MIPMAP_NEAREST},
2307*35238bceSAndroid Build Coastguard Worker                                 {"nearest_mipmap_linear", tcu::Sampler::NEAREST_MIPMAP_LINEAR},
2308*35238bceSAndroid Build Coastguard Worker                                 {"linear_mipmap_nearest", tcu::Sampler::LINEAR_MIPMAP_NEAREST},
2309*35238bceSAndroid Build Coastguard Worker                                 {"linear_mipmap_linear", tcu::Sampler::LINEAR_MIPMAP_LINEAR},
2310*35238bceSAndroid Build Coastguard Worker                             };
2311*35238bceSAndroid Build Coastguard Worker 
2312*35238bceSAndroid Build Coastguard Worker                             for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilters); minFilterNdx++)
2313*35238bceSAndroid Build Coastguard Worker                                 for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilters);
2314*35238bceSAndroid Build Coastguard Worker                                      magFilterNdx++)
2315*35238bceSAndroid Build Coastguard Worker                                 {
2316*35238bceSAndroid Build Coastguard Worker                                     const tcu::Sampler::FilterMode minFilter    = minFilters[minFilterNdx].filter;
2317*35238bceSAndroid Build Coastguard Worker                                     const tcu::Sampler::FilterMode magFilter    = magFilters[magFilterNdx].filter;
2318*35238bceSAndroid Build Coastguard Worker                                     const tcu::Sampler::CompareMode compareMode = isDepthFormat(format) ?
2319*35238bceSAndroid Build Coastguard Worker                                                                                       tcu::Sampler::COMPAREMODE_LESS :
2320*35238bceSAndroid Build Coastguard Worker                                                                                       tcu::Sampler::COMPAREMODE_NONE;
2321*35238bceSAndroid Build Coastguard Worker 
2322*35238bceSAndroid Build Coastguard Worker                                     if ((isUnormFormatType(format.type) || isDepthFormat(format)) &&
2323*35238bceSAndroid Build Coastguard Worker                                         magFilter == tcu::Sampler::NEAREST)
2324*35238bceSAndroid Build Coastguard Worker                                         continue; // Covered by other cases.
2325*35238bceSAndroid Build Coastguard Worker                                     if ((isUIntFormatType(format.type) || isSIntFormatType(format.type)) &&
2326*35238bceSAndroid Build Coastguard Worker                                         (magFilter != tcu::Sampler::NEAREST ||
2327*35238bceSAndroid Build Coastguard Worker                                          minFilter != tcu::Sampler::NEAREST_MIPMAP_NEAREST))
2328*35238bceSAndroid Build Coastguard Worker                                         continue;
2329*35238bceSAndroid Build Coastguard Worker 
2330*35238bceSAndroid Build Coastguard Worker                                     const string caseName = string() + "min_" + minFilters[minFilterNdx].name +
2331*35238bceSAndroid Build Coastguard Worker                                                             "_mag_" + magFilters[magFilterNdx].name;
2332*35238bceSAndroid Build Coastguard Worker 
2333*35238bceSAndroid Build Coastguard Worker                                     filterModeGroup->addChild(makeTextureGatherCase(
2334*35238bceSAndroid Build Coastguard Worker                                         textureType, m_context, caseName.c_str(), "", gatherType, offsetSize, format,
2335*35238bceSAndroid Build Coastguard Worker                                         compareMode, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
2336*35238bceSAndroid Build Coastguard Worker                                         MaybeTextureSwizzle::createNoneTextureSwizzle(), minFilter, magFilter, 0,
2337*35238bceSAndroid Build Coastguard Worker                                         IVec3(64, 64, 3)));
2338*35238bceSAndroid Build Coastguard Worker                                 }
2339*35238bceSAndroid Build Coastguard Worker                         }
2340*35238bceSAndroid Build Coastguard Worker 
2341*35238bceSAndroid Build Coastguard Worker                         {
2342*35238bceSAndroid Build Coastguard Worker                             TestCaseGroup *const baseLevelGroup = new TestCaseGroup(m_context, "base_level", "");
2343*35238bceSAndroid Build Coastguard Worker                             formatGroup->addChild(baseLevelGroup);
2344*35238bceSAndroid Build Coastguard Worker 
2345*35238bceSAndroid Build Coastguard Worker                             for (int baseLevel = 1; baseLevel <= 2; baseLevel++)
2346*35238bceSAndroid Build Coastguard Worker                             {
2347*35238bceSAndroid Build Coastguard Worker                                 const string caseName                       = "level_" + de::toString(baseLevel);
2348*35238bceSAndroid Build Coastguard Worker                                 const tcu::Sampler::CompareMode compareMode = isDepthFormat(format) ?
2349*35238bceSAndroid Build Coastguard Worker                                                                                   tcu::Sampler::COMPAREMODE_LESS :
2350*35238bceSAndroid Build Coastguard Worker                                                                                   tcu::Sampler::COMPAREMODE_NONE;
2351*35238bceSAndroid Build Coastguard Worker                                 baseLevelGroup->addChild(makeTextureGatherCase(
2352*35238bceSAndroid Build Coastguard Worker                                     textureType, m_context, caseName.c_str(), "", gatherType, offsetSize, format,
2353*35238bceSAndroid Build Coastguard Worker                                     compareMode, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
2354*35238bceSAndroid Build Coastguard Worker                                     MaybeTextureSwizzle::createNoneTextureSwizzle(), tcu::Sampler::NEAREST,
2355*35238bceSAndroid Build Coastguard Worker                                     tcu::Sampler::NEAREST, baseLevel, IVec3(64, 64, 3)));
2356*35238bceSAndroid Build Coastguard Worker                             }
2357*35238bceSAndroid Build Coastguard Worker                         }
2358*35238bceSAndroid Build Coastguard Worker 
2359*35238bceSAndroid Build Coastguard Worker                         // What shadow textures should return for incomplete textures is unclear.
2360*35238bceSAndroid Build Coastguard Worker                         // Integer and unsigned integer lookups from incomplete textures return undefined values.
2361*35238bceSAndroid Build Coastguard Worker                         if (!isDepthFormat(format) && !isSIntFormatType(format.type) && !isUIntFormatType(format.type))
2362*35238bceSAndroid Build Coastguard Worker                         {
2363*35238bceSAndroid Build Coastguard Worker                             TestCaseGroup *const incompleteGroup = new TestCaseGroup(
2364*35238bceSAndroid Build Coastguard Worker                                 m_context, "incomplete",
2365*35238bceSAndroid Build Coastguard Worker                                 "Test that textureGather* takes components from (0,0,0,1) for incomplete textures");
2366*35238bceSAndroid Build Coastguard Worker                             formatGroup->addChild(incompleteGroup);
2367*35238bceSAndroid Build Coastguard Worker 
2368*35238bceSAndroid Build Coastguard Worker                             const tcu::Sampler::CompareMode compareMode =
2369*35238bceSAndroid Build Coastguard Worker                                 isDepthFormat(format) ? tcu::Sampler::COMPAREMODE_LESS : tcu::Sampler::COMPAREMODE_NONE;
2370*35238bceSAndroid Build Coastguard Worker                             incompleteGroup->addChild(makeTextureGatherCase(
2371*35238bceSAndroid Build Coastguard Worker                                 textureType, m_context, "mipmap_incomplete", "", gatherType, offsetSize, format,
2372*35238bceSAndroid Build Coastguard Worker                                 compareMode, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL,
2373*35238bceSAndroid Build Coastguard Worker                                 MaybeTextureSwizzle::createNoneTextureSwizzle(), tcu::Sampler::NEAREST_MIPMAP_NEAREST,
2374*35238bceSAndroid Build Coastguard Worker                                 tcu::Sampler::NEAREST, 0, IVec3(64, 64, 3), GATHERCASE_MIPMAP_INCOMPLETE));
2375*35238bceSAndroid Build Coastguard Worker                         }
2376*35238bceSAndroid Build Coastguard Worker                     }
2377*35238bceSAndroid Build Coastguard Worker                 }
2378*35238bceSAndroid Build Coastguard Worker             }
2379*35238bceSAndroid Build Coastguard Worker         }
2380*35238bceSAndroid Build Coastguard Worker     }
2381*35238bceSAndroid Build Coastguard Worker }
2382*35238bceSAndroid Build Coastguard Worker 
2383*35238bceSAndroid Build Coastguard Worker } // namespace Functional
2384*35238bceSAndroid Build Coastguard Worker } // namespace gles31
2385*35238bceSAndroid Build Coastguard Worker } // namespace deqp
2386