xref: /aosp_15_r20/external/deqp/framework/opengl/gluTextureTestUtil.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES Utilities
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 Utility functions and structures for texture tests. This code
22*35238bceSAndroid Build Coastguard Worker  * is originated from the modules/glshared/glsTextureTestUtil.hpp and it
23*35238bceSAndroid Build Coastguard Worker  * is tightly coupled with the GLES and Vulkan texture tests!
24*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include "gluTextureTestUtil.hpp"
27*35238bceSAndroid Build Coastguard Worker 
28*35238bceSAndroid Build Coastguard Worker #include "tcuFloat.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuImageCompare.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "tcuVectorUtil.hpp"
32*35238bceSAndroid Build Coastguard Worker 
33*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
34*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
35*35238bceSAndroid Build Coastguard Worker 
36*35238bceSAndroid Build Coastguard Worker #include <string>
37*35238bceSAndroid Build Coastguard Worker 
38*35238bceSAndroid Build Coastguard Worker using std::string;
39*35238bceSAndroid Build Coastguard Worker 
40*35238bceSAndroid Build Coastguard Worker namespace glu
41*35238bceSAndroid Build Coastguard Worker {
42*35238bceSAndroid Build Coastguard Worker 
43*35238bceSAndroid Build Coastguard Worker namespace TextureTestUtil
44*35238bceSAndroid Build Coastguard Worker {
45*35238bceSAndroid Build Coastguard Worker 
46*35238bceSAndroid Build Coastguard Worker enum
47*35238bceSAndroid Build Coastguard Worker {
48*35238bceSAndroid Build Coastguard Worker     MIN_SUBPIXEL_BITS = 4
49*35238bceSAndroid Build Coastguard Worker };
50*35238bceSAndroid Build Coastguard Worker 
getSamplerType(tcu::TextureFormat format)51*35238bceSAndroid Build Coastguard Worker SamplerType getSamplerType(tcu::TextureFormat format)
52*35238bceSAndroid Build Coastguard Worker {
53*35238bceSAndroid Build Coastguard Worker     using tcu::TextureFormat;
54*35238bceSAndroid Build Coastguard Worker 
55*35238bceSAndroid Build Coastguard Worker     switch (format.type)
56*35238bceSAndroid Build Coastguard Worker     {
57*35238bceSAndroid Build Coastguard Worker     case TextureFormat::SIGNED_INT8:
58*35238bceSAndroid Build Coastguard Worker     case TextureFormat::SIGNED_INT16:
59*35238bceSAndroid Build Coastguard Worker     case TextureFormat::SIGNED_INT32:
60*35238bceSAndroid Build Coastguard Worker         return SAMPLERTYPE_INT;
61*35238bceSAndroid Build Coastguard Worker 
62*35238bceSAndroid Build Coastguard Worker     case TextureFormat::UNSIGNED_INT8:
63*35238bceSAndroid Build Coastguard Worker     case TextureFormat::UNSIGNED_INT32:
64*35238bceSAndroid Build Coastguard Worker     case TextureFormat::UNSIGNED_INT_1010102_REV:
65*35238bceSAndroid Build Coastguard Worker         return SAMPLERTYPE_UINT;
66*35238bceSAndroid Build Coastguard Worker 
67*35238bceSAndroid Build Coastguard Worker     // Texture formats used in depth/stencil textures.
68*35238bceSAndroid Build Coastguard Worker     case TextureFormat::UNSIGNED_INT16:
69*35238bceSAndroid Build Coastguard Worker     case TextureFormat::UNSIGNED_INT_24_8:
70*35238bceSAndroid Build Coastguard Worker         return (format.order == TextureFormat::D || format.order == TextureFormat::DS) ? SAMPLERTYPE_FLOAT :
71*35238bceSAndroid Build Coastguard Worker                                                                                          SAMPLERTYPE_UINT;
72*35238bceSAndroid Build Coastguard Worker 
73*35238bceSAndroid Build Coastguard Worker     default:
74*35238bceSAndroid Build Coastguard Worker         return SAMPLERTYPE_FLOAT;
75*35238bceSAndroid Build Coastguard Worker     }
76*35238bceSAndroid Build Coastguard Worker }
77*35238bceSAndroid Build Coastguard Worker 
getFetchSamplerType(tcu::TextureFormat format)78*35238bceSAndroid Build Coastguard Worker SamplerType getFetchSamplerType(tcu::TextureFormat format)
79*35238bceSAndroid Build Coastguard Worker {
80*35238bceSAndroid Build Coastguard Worker     using tcu::TextureFormat;
81*35238bceSAndroid Build Coastguard Worker 
82*35238bceSAndroid Build Coastguard Worker     switch (format.type)
83*35238bceSAndroid Build Coastguard Worker     {
84*35238bceSAndroid Build Coastguard Worker     case TextureFormat::SIGNED_INT8:
85*35238bceSAndroid Build Coastguard Worker     case TextureFormat::SIGNED_INT16:
86*35238bceSAndroid Build Coastguard Worker     case TextureFormat::SIGNED_INT32:
87*35238bceSAndroid Build Coastguard Worker         return SAMPLERTYPE_FETCH_INT;
88*35238bceSAndroid Build Coastguard Worker 
89*35238bceSAndroid Build Coastguard Worker     case TextureFormat::UNSIGNED_INT8:
90*35238bceSAndroid Build Coastguard Worker     case TextureFormat::UNSIGNED_INT32:
91*35238bceSAndroid Build Coastguard Worker     case TextureFormat::UNSIGNED_INT_1010102_REV:
92*35238bceSAndroid Build Coastguard Worker         return SAMPLERTYPE_FETCH_UINT;
93*35238bceSAndroid Build Coastguard Worker 
94*35238bceSAndroid Build Coastguard Worker     // Texture formats used in depth/stencil textures.
95*35238bceSAndroid Build Coastguard Worker     case TextureFormat::UNSIGNED_INT16:
96*35238bceSAndroid Build Coastguard Worker     case TextureFormat::UNSIGNED_INT_24_8:
97*35238bceSAndroid Build Coastguard Worker         return (format.order == TextureFormat::D || format.order == TextureFormat::DS) ? SAMPLERTYPE_FETCH_FLOAT :
98*35238bceSAndroid Build Coastguard Worker                                                                                          SAMPLERTYPE_FETCH_UINT;
99*35238bceSAndroid Build Coastguard Worker 
100*35238bceSAndroid Build Coastguard Worker     default:
101*35238bceSAndroid Build Coastguard Worker         return SAMPLERTYPE_FETCH_FLOAT;
102*35238bceSAndroid Build Coastguard Worker     }
103*35238bceSAndroid Build Coastguard Worker }
104*35238bceSAndroid Build Coastguard Worker 
getSubView(const tcu::Texture1DView & view,int baseLevel,int maxLevel,tcu::ImageViewMinLodParams * minLodParams DE_UNUSED_ATTR)105*35238bceSAndroid Build Coastguard Worker static tcu::Texture1DView getSubView(const tcu::Texture1DView &view, int baseLevel, int maxLevel,
106*35238bceSAndroid Build Coastguard Worker                                      tcu::ImageViewMinLodParams *minLodParams DE_UNUSED_ATTR)
107*35238bceSAndroid Build Coastguard Worker {
108*35238bceSAndroid Build Coastguard Worker     const int clampedBase = de::clamp(baseLevel, 0, view.getNumLevels() - 1);
109*35238bceSAndroid Build Coastguard Worker     const int clampedMax  = de::clamp(maxLevel, clampedBase, view.getNumLevels() - 1);
110*35238bceSAndroid Build Coastguard Worker     const int numLevels   = clampedMax - clampedBase + 1;
111*35238bceSAndroid Build Coastguard Worker     return tcu::Texture1DView(numLevels, view.getLevels() + clampedBase);
112*35238bceSAndroid Build Coastguard Worker }
113*35238bceSAndroid Build Coastguard Worker 
getSubView(const tcu::Texture2DView & view,int baseLevel,int maxLevel,tcu::ImageViewMinLodParams * minLodParams=DE_NULL)114*35238bceSAndroid Build Coastguard Worker static tcu::Texture2DView getSubView(const tcu::Texture2DView &view, int baseLevel, int maxLevel,
115*35238bceSAndroid Build Coastguard Worker                                      tcu::ImageViewMinLodParams *minLodParams = DE_NULL)
116*35238bceSAndroid Build Coastguard Worker {
117*35238bceSAndroid Build Coastguard Worker     const int clampedBase = de::clamp(baseLevel, 0, view.getNumLevels() - 1);
118*35238bceSAndroid Build Coastguard Worker     const int clampedMax  = de::clamp(maxLevel, clampedBase, view.getNumLevels() - 1);
119*35238bceSAndroid Build Coastguard Worker     const int numLevels   = clampedMax - clampedBase + 1;
120*35238bceSAndroid Build Coastguard Worker     return tcu::Texture2DView(numLevels, view.getLevels() + clampedBase, view.isES2(), minLodParams);
121*35238bceSAndroid Build Coastguard Worker }
122*35238bceSAndroid Build Coastguard Worker 
getSubView(const tcu::TextureCubeView & view,int baseLevel,int maxLevel,tcu::ImageViewMinLodParams * minLodParams=DE_NULL)123*35238bceSAndroid Build Coastguard Worker static tcu::TextureCubeView getSubView(const tcu::TextureCubeView &view, int baseLevel, int maxLevel,
124*35238bceSAndroid Build Coastguard Worker                                        tcu::ImageViewMinLodParams *minLodParams = DE_NULL)
125*35238bceSAndroid Build Coastguard Worker {
126*35238bceSAndroid Build Coastguard Worker     const int clampedBase = de::clamp(baseLevel, 0, view.getNumLevels() - 1);
127*35238bceSAndroid Build Coastguard Worker     const int clampedMax  = de::clamp(maxLevel, clampedBase, view.getNumLevels() - 1);
128*35238bceSAndroid Build Coastguard Worker     const int numLevels   = clampedMax - clampedBase + 1;
129*35238bceSAndroid Build Coastguard Worker     const tcu::ConstPixelBufferAccess *levels[tcu::CUBEFACE_LAST];
130*35238bceSAndroid Build Coastguard Worker 
131*35238bceSAndroid Build Coastguard Worker     for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
132*35238bceSAndroid Build Coastguard Worker         levels[face] = view.getFaceLevels((tcu::CubeFace)face) + clampedBase;
133*35238bceSAndroid Build Coastguard Worker 
134*35238bceSAndroid Build Coastguard Worker     return tcu::TextureCubeView(numLevels, levels, false, minLodParams);
135*35238bceSAndroid Build Coastguard Worker }
136*35238bceSAndroid Build Coastguard Worker 
getSubView(const tcu::Texture3DView & view,int baseLevel,int maxLevel,tcu::ImageViewMinLodParams * minLodParams=DE_NULL)137*35238bceSAndroid Build Coastguard Worker static tcu::Texture3DView getSubView(const tcu::Texture3DView &view, int baseLevel, int maxLevel,
138*35238bceSAndroid Build Coastguard Worker                                      tcu::ImageViewMinLodParams *minLodParams = DE_NULL)
139*35238bceSAndroid Build Coastguard Worker {
140*35238bceSAndroid Build Coastguard Worker     const int clampedBase = de::clamp(baseLevel, 0, view.getNumLevels() - 1);
141*35238bceSAndroid Build Coastguard Worker     const int clampedMax  = de::clamp(maxLevel, clampedBase, view.getNumLevels() - 1);
142*35238bceSAndroid Build Coastguard Worker     const int numLevels   = clampedMax - clampedBase + 1;
143*35238bceSAndroid Build Coastguard Worker     return tcu::Texture3DView(numLevels, view.getLevels() + clampedBase, false, minLodParams);
144*35238bceSAndroid Build Coastguard Worker }
145*35238bceSAndroid Build Coastguard Worker 
getSubView(const tcu::TextureCubeArrayView & view,int baseLevel,int maxLevel,tcu::ImageViewMinLodParams * minLodParams DE_UNUSED_ATTR=DE_NULL)146*35238bceSAndroid Build Coastguard Worker static tcu::TextureCubeArrayView getSubView(const tcu::TextureCubeArrayView &view, int baseLevel, int maxLevel,
147*35238bceSAndroid Build Coastguard Worker                                             tcu::ImageViewMinLodParams *minLodParams DE_UNUSED_ATTR = DE_NULL)
148*35238bceSAndroid Build Coastguard Worker {
149*35238bceSAndroid Build Coastguard Worker     const int clampedBase = de::clamp(baseLevel, 0, view.getNumLevels() - 1);
150*35238bceSAndroid Build Coastguard Worker     const int clampedMax  = de::clamp(maxLevel, clampedBase, view.getNumLevels() - 1);
151*35238bceSAndroid Build Coastguard Worker     const int numLevels   = clampedMax - clampedBase + 1;
152*35238bceSAndroid Build Coastguard Worker     return tcu::TextureCubeArrayView(numLevels, view.getLevels() + clampedBase);
153*35238bceSAndroid Build Coastguard Worker }
154*35238bceSAndroid Build Coastguard Worker 
linearInterpolate(float t,float minVal,float maxVal)155*35238bceSAndroid Build Coastguard Worker inline float linearInterpolate(float t, float minVal, float maxVal)
156*35238bceSAndroid Build Coastguard Worker {
157*35238bceSAndroid Build Coastguard Worker     return minVal + (maxVal - minVal) * t;
158*35238bceSAndroid Build Coastguard Worker }
159*35238bceSAndroid Build Coastguard Worker 
linearInterpolate(float t,const tcu::Vec4 & a,const tcu::Vec4 & b)160*35238bceSAndroid Build Coastguard Worker inline tcu::Vec4 linearInterpolate(float t, const tcu::Vec4 &a, const tcu::Vec4 &b)
161*35238bceSAndroid Build Coastguard Worker {
162*35238bceSAndroid Build Coastguard Worker     return a + (b - a) * t;
163*35238bceSAndroid Build Coastguard Worker }
164*35238bceSAndroid Build Coastguard Worker 
bilinearInterpolate(float x,float y,const tcu::Vec4 & quad)165*35238bceSAndroid Build Coastguard Worker inline float bilinearInterpolate(float x, float y, const tcu::Vec4 &quad)
166*35238bceSAndroid Build Coastguard Worker {
167*35238bceSAndroid Build Coastguard Worker     float w00 = (1.0f - x) * (1.0f - y);
168*35238bceSAndroid Build Coastguard Worker     float w01 = (1.0f - x) * y;
169*35238bceSAndroid Build Coastguard Worker     float w10 = x * (1.0f - y);
170*35238bceSAndroid Build Coastguard Worker     float w11 = x * y;
171*35238bceSAndroid Build Coastguard Worker     return quad.x() * w00 + quad.y() * w10 + quad.z() * w01 + quad.w() * w11;
172*35238bceSAndroid Build Coastguard Worker }
173*35238bceSAndroid Build Coastguard Worker 
triangleInterpolate(float v0,float v1,float v2,float x,float y)174*35238bceSAndroid Build Coastguard Worker float triangleInterpolate(float v0, float v1, float v2, float x, float y)
175*35238bceSAndroid Build Coastguard Worker {
176*35238bceSAndroid Build Coastguard Worker     return v0 + (v2 - v0) * x + (v1 - v0) * y;
177*35238bceSAndroid Build Coastguard Worker }
178*35238bceSAndroid Build Coastguard Worker 
triangleInterpolate(const tcu::Vec3 & v,float x,float y)179*35238bceSAndroid Build Coastguard Worker float triangleInterpolate(const tcu::Vec3 &v, float x, float y)
180*35238bceSAndroid Build Coastguard Worker {
181*35238bceSAndroid Build Coastguard Worker     return triangleInterpolate(v.x(), v.y(), v.z(), x, y);
182*35238bceSAndroid Build Coastguard Worker }
183*35238bceSAndroid Build Coastguard Worker 
184*35238bceSAndroid Build Coastguard Worker // 1D lookup LOD computation.
185*35238bceSAndroid Build Coastguard Worker 
computeLodFromDerivates(LodMode mode,float dudx,float dudy)186*35238bceSAndroid Build Coastguard Worker float computeLodFromDerivates(LodMode mode, float dudx, float dudy)
187*35238bceSAndroid Build Coastguard Worker {
188*35238bceSAndroid Build Coastguard Worker     float p = 0.0f;
189*35238bceSAndroid Build Coastguard Worker     switch (mode)
190*35238bceSAndroid Build Coastguard Worker     {
191*35238bceSAndroid Build Coastguard Worker     // \note [mika] Min and max bounds equal to exact with 1D textures
192*35238bceSAndroid Build Coastguard Worker     case LODMODE_EXACT:
193*35238bceSAndroid Build Coastguard Worker     case LODMODE_MIN_BOUND:
194*35238bceSAndroid Build Coastguard Worker     case LODMODE_MAX_BOUND:
195*35238bceSAndroid Build Coastguard Worker         p = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
196*35238bceSAndroid Build Coastguard Worker         break;
197*35238bceSAndroid Build Coastguard Worker 
198*35238bceSAndroid Build Coastguard Worker     default:
199*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
200*35238bceSAndroid Build Coastguard Worker     }
201*35238bceSAndroid Build Coastguard Worker 
202*35238bceSAndroid Build Coastguard Worker     return deFloatLog2(p);
203*35238bceSAndroid Build Coastguard Worker }
204*35238bceSAndroid Build Coastguard Worker 
computeNonProjectedTriLod(LodMode mode,const tcu::IVec2 & dstSize,int32_t srcSize,const tcu::Vec3 & sq)205*35238bceSAndroid Build Coastguard Worker float computeNonProjectedTriLod(LodMode mode, const tcu::IVec2 &dstSize, int32_t srcSize, const tcu::Vec3 &sq)
206*35238bceSAndroid Build Coastguard Worker {
207*35238bceSAndroid Build Coastguard Worker     float dux = (sq.z() - sq.x()) * (float)srcSize;
208*35238bceSAndroid Build Coastguard Worker     float duy = (sq.y() - sq.x()) * (float)srcSize;
209*35238bceSAndroid Build Coastguard Worker     float dx  = (float)dstSize.x();
210*35238bceSAndroid Build Coastguard Worker     float dy  = (float)dstSize.y();
211*35238bceSAndroid Build Coastguard Worker 
212*35238bceSAndroid Build Coastguard Worker     return computeLodFromDerivates(mode, dux / dx, duy / dy);
213*35238bceSAndroid Build Coastguard Worker }
214*35238bceSAndroid Build Coastguard Worker 
215*35238bceSAndroid Build Coastguard Worker // 2D lookup LOD computation.
216*35238bceSAndroid Build Coastguard Worker 
computeLodFromDerivates(LodMode mode,float dudx,float dvdx,float dudy,float dvdy)217*35238bceSAndroid Build Coastguard Worker float computeLodFromDerivates(LodMode mode, float dudx, float dvdx, float dudy, float dvdy)
218*35238bceSAndroid Build Coastguard Worker {
219*35238bceSAndroid Build Coastguard Worker     float p = 0.0f;
220*35238bceSAndroid Build Coastguard Worker     switch (mode)
221*35238bceSAndroid Build Coastguard Worker     {
222*35238bceSAndroid Build Coastguard Worker     case LODMODE_EXACT:
223*35238bceSAndroid Build Coastguard Worker         p = de::max(deFloatSqrt(dudx * dudx + dvdx * dvdx), deFloatSqrt(dudy * dudy + dvdy * dvdy));
224*35238bceSAndroid Build Coastguard Worker         break;
225*35238bceSAndroid Build Coastguard Worker 
226*35238bceSAndroid Build Coastguard Worker     case LODMODE_MIN_BOUND:
227*35238bceSAndroid Build Coastguard Worker     case LODMODE_MAX_BOUND:
228*35238bceSAndroid Build Coastguard Worker     {
229*35238bceSAndroid Build Coastguard Worker         float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
230*35238bceSAndroid Build Coastguard Worker         float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy));
231*35238bceSAndroid Build Coastguard Worker 
232*35238bceSAndroid Build Coastguard Worker         p = mode == LODMODE_MIN_BOUND ? de::max(mu, mv) : mu + mv;
233*35238bceSAndroid Build Coastguard Worker         break;
234*35238bceSAndroid Build Coastguard Worker     }
235*35238bceSAndroid Build Coastguard Worker 
236*35238bceSAndroid Build Coastguard Worker     default:
237*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
238*35238bceSAndroid Build Coastguard Worker     }
239*35238bceSAndroid Build Coastguard Worker 
240*35238bceSAndroid Build Coastguard Worker     return deFloatLog2(p);
241*35238bceSAndroid Build Coastguard Worker }
242*35238bceSAndroid Build Coastguard Worker 
computeNonProjectedTriLod(LodMode mode,const tcu::IVec2 & dstSize,const tcu::IVec2 & srcSize,const tcu::Vec3 & sq,const tcu::Vec3 & tq)243*35238bceSAndroid Build Coastguard Worker float computeNonProjectedTriLod(LodMode mode, const tcu::IVec2 &dstSize, const tcu::IVec2 &srcSize, const tcu::Vec3 &sq,
244*35238bceSAndroid Build Coastguard Worker                                 const tcu::Vec3 &tq)
245*35238bceSAndroid Build Coastguard Worker {
246*35238bceSAndroid Build Coastguard Worker     float dux = (sq.z() - sq.x()) * (float)srcSize.x();
247*35238bceSAndroid Build Coastguard Worker     float duy = (sq.y() - sq.x()) * (float)srcSize.x();
248*35238bceSAndroid Build Coastguard Worker     float dvx = (tq.z() - tq.x()) * (float)srcSize.y();
249*35238bceSAndroid Build Coastguard Worker     float dvy = (tq.y() - tq.x()) * (float)srcSize.y();
250*35238bceSAndroid Build Coastguard Worker     float dx  = (float)dstSize.x();
251*35238bceSAndroid Build Coastguard Worker     float dy  = (float)dstSize.y();
252*35238bceSAndroid Build Coastguard Worker 
253*35238bceSAndroid Build Coastguard Worker     return computeLodFromDerivates(mode, dux / dx, dvx / dx, duy / dy, dvy / dy);
254*35238bceSAndroid Build Coastguard Worker }
255*35238bceSAndroid Build Coastguard Worker 
256*35238bceSAndroid Build Coastguard Worker // 3D lookup LOD computation.
257*35238bceSAndroid Build Coastguard Worker 
computeLodFromDerivates(LodMode mode,float dudx,float dvdx,float dwdx,float dudy,float dvdy,float dwdy)258*35238bceSAndroid Build Coastguard Worker float computeLodFromDerivates(LodMode mode, float dudx, float dvdx, float dwdx, float dudy, float dvdy, float dwdy)
259*35238bceSAndroid Build Coastguard Worker {
260*35238bceSAndroid Build Coastguard Worker     float p = 0.0f;
261*35238bceSAndroid Build Coastguard Worker     switch (mode)
262*35238bceSAndroid Build Coastguard Worker     {
263*35238bceSAndroid Build Coastguard Worker     case LODMODE_EXACT:
264*35238bceSAndroid Build Coastguard Worker         p = de::max(deFloatSqrt(dudx * dudx + dvdx * dvdx + dwdx * dwdx),
265*35238bceSAndroid Build Coastguard Worker                     deFloatSqrt(dudy * dudy + dvdy * dvdy + dwdy * dwdy));
266*35238bceSAndroid Build Coastguard Worker         break;
267*35238bceSAndroid Build Coastguard Worker 
268*35238bceSAndroid Build Coastguard Worker     case LODMODE_MIN_BOUND:
269*35238bceSAndroid Build Coastguard Worker     case LODMODE_MAX_BOUND:
270*35238bceSAndroid Build Coastguard Worker     {
271*35238bceSAndroid Build Coastguard Worker         float mu = de::max(deFloatAbs(dudx), deFloatAbs(dudy));
272*35238bceSAndroid Build Coastguard Worker         float mv = de::max(deFloatAbs(dvdx), deFloatAbs(dvdy));
273*35238bceSAndroid Build Coastguard Worker         float mw = de::max(deFloatAbs(dwdx), deFloatAbs(dwdy));
274*35238bceSAndroid Build Coastguard Worker 
275*35238bceSAndroid Build Coastguard Worker         p = mode == LODMODE_MIN_BOUND ? de::max(de::max(mu, mv), mw) : (mu + mv + mw);
276*35238bceSAndroid Build Coastguard Worker         break;
277*35238bceSAndroid Build Coastguard Worker     }
278*35238bceSAndroid Build Coastguard Worker 
279*35238bceSAndroid Build Coastguard Worker     default:
280*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
281*35238bceSAndroid Build Coastguard Worker     }
282*35238bceSAndroid Build Coastguard Worker 
283*35238bceSAndroid Build Coastguard Worker     return deFloatLog2(p);
284*35238bceSAndroid Build Coastguard Worker }
285*35238bceSAndroid Build Coastguard Worker 
computeNonProjectedTriLod(LodMode mode,const tcu::IVec2 & dstSize,const tcu::IVec3 & srcSize,const tcu::Vec3 & sq,const tcu::Vec3 & tq,const tcu::Vec3 & rq)286*35238bceSAndroid Build Coastguard Worker float computeNonProjectedTriLod(LodMode mode, const tcu::IVec2 &dstSize, const tcu::IVec3 &srcSize, const tcu::Vec3 &sq,
287*35238bceSAndroid Build Coastguard Worker                                 const tcu::Vec3 &tq, const tcu::Vec3 &rq)
288*35238bceSAndroid Build Coastguard Worker {
289*35238bceSAndroid Build Coastguard Worker     float dux = (sq.z() - sq.x()) * (float)srcSize.x();
290*35238bceSAndroid Build Coastguard Worker     float duy = (sq.y() - sq.x()) * (float)srcSize.x();
291*35238bceSAndroid Build Coastguard Worker     float dvx = (tq.z() - tq.x()) * (float)srcSize.y();
292*35238bceSAndroid Build Coastguard Worker     float dvy = (tq.y() - tq.x()) * (float)srcSize.y();
293*35238bceSAndroid Build Coastguard Worker     float dwx = (rq.z() - rq.x()) * (float)srcSize.z();
294*35238bceSAndroid Build Coastguard Worker     float dwy = (rq.y() - rq.x()) * (float)srcSize.z();
295*35238bceSAndroid Build Coastguard Worker     float dx  = (float)dstSize.x();
296*35238bceSAndroid Build Coastguard Worker     float dy  = (float)dstSize.y();
297*35238bceSAndroid Build Coastguard Worker 
298*35238bceSAndroid Build Coastguard Worker     return computeLodFromDerivates(mode, dux / dx, dvx / dx, dwx / dx, duy / dy, dvy / dy, dwy / dy);
299*35238bceSAndroid Build Coastguard Worker }
300*35238bceSAndroid Build Coastguard Worker 
projectedTriInterpolate(const tcu::Vec3 & s,const tcu::Vec3 & w,float nx,float ny)301*35238bceSAndroid Build Coastguard Worker static inline float projectedTriInterpolate(const tcu::Vec3 &s, const tcu::Vec3 &w, float nx, float ny)
302*35238bceSAndroid Build Coastguard Worker {
303*35238bceSAndroid Build Coastguard Worker     return (s[0] * (1.0f - nx - ny) / w[0] + s[1] * ny / w[1] + s[2] * nx / w[2]) /
304*35238bceSAndroid Build Coastguard Worker            ((1.0f - nx - ny) / w[0] + ny / w[1] + nx / w[2]);
305*35238bceSAndroid Build Coastguard Worker }
306*35238bceSAndroid Build Coastguard Worker 
triDerivateX(const tcu::Vec3 & s,const tcu::Vec3 & w,float wx,float width,float ny)307*35238bceSAndroid Build Coastguard Worker static inline float triDerivateX(const tcu::Vec3 &s, const tcu::Vec3 &w, float wx, float width, float ny)
308*35238bceSAndroid Build Coastguard Worker {
309*35238bceSAndroid Build Coastguard Worker     float d = w[1] * w[2] * (width * (ny - 1.0f) + wx) - w[0] * (w[2] * width * ny + w[1] * wx);
310*35238bceSAndroid Build Coastguard Worker     return (w[0] * w[1] * w[2] * width *
311*35238bceSAndroid Build Coastguard Worker             (w[1] * (s[0] - s[2]) * (ny - 1.0f) + ny * (w[2] * (s[1] - s[0]) + w[0] * (s[2] - s[1])))) /
312*35238bceSAndroid Build Coastguard Worker            (d * d);
313*35238bceSAndroid Build Coastguard Worker }
314*35238bceSAndroid Build Coastguard Worker 
triDerivateY(const tcu::Vec3 & s,const tcu::Vec3 & w,float wy,float height,float nx)315*35238bceSAndroid Build Coastguard Worker static inline float triDerivateY(const tcu::Vec3 &s, const tcu::Vec3 &w, float wy, float height, float nx)
316*35238bceSAndroid Build Coastguard Worker {
317*35238bceSAndroid Build Coastguard Worker     float d = w[1] * w[2] * (height * (nx - 1.0f) + wy) - w[0] * (w[1] * height * nx + w[2] * wy);
318*35238bceSAndroid Build Coastguard Worker     return (w[0] * w[1] * w[2] * height *
319*35238bceSAndroid Build Coastguard Worker             (w[2] * (s[0] - s[1]) * (nx - 1.0f) + nx * (w[0] * (s[1] - s[2]) + w[1] * (s[2] - s[0])))) /
320*35238bceSAndroid Build Coastguard Worker            (d * d);
321*35238bceSAndroid Build Coastguard Worker }
322*35238bceSAndroid Build Coastguard Worker 
323*35238bceSAndroid Build Coastguard Worker // 1D lookup LOD.
computeProjectedTriLod(LodMode mode,const tcu::Vec3 & u,const tcu::Vec3 & projection,float wx,float wy,float width,float height)324*35238bceSAndroid Build Coastguard Worker static float computeProjectedTriLod(LodMode mode, const tcu::Vec3 &u, const tcu::Vec3 &projection, float wx, float wy,
325*35238bceSAndroid Build Coastguard Worker                                     float width, float height)
326*35238bceSAndroid Build Coastguard Worker {
327*35238bceSAndroid Build Coastguard Worker     // Exact derivatives.
328*35238bceSAndroid Build Coastguard Worker     float dudx = triDerivateX(u, projection, wx, width, wy / height);
329*35238bceSAndroid Build Coastguard Worker     float dudy = triDerivateY(u, projection, wy, height, wx / width);
330*35238bceSAndroid Build Coastguard Worker 
331*35238bceSAndroid Build Coastguard Worker     return computeLodFromDerivates(mode, dudx, dudy);
332*35238bceSAndroid Build Coastguard Worker }
333*35238bceSAndroid Build Coastguard Worker 
334*35238bceSAndroid Build Coastguard Worker // 2D lookup LOD.
computeProjectedTriLod(LodMode mode,const tcu::Vec3 & u,const tcu::Vec3 & v,const tcu::Vec3 & projection,float wx,float wy,float width,float height)335*35238bceSAndroid Build Coastguard Worker static float computeProjectedTriLod(LodMode mode, const tcu::Vec3 &u, const tcu::Vec3 &v, const tcu::Vec3 &projection,
336*35238bceSAndroid Build Coastguard Worker                                     float wx, float wy, float width, float height)
337*35238bceSAndroid Build Coastguard Worker {
338*35238bceSAndroid Build Coastguard Worker     // Exact derivatives.
339*35238bceSAndroid Build Coastguard Worker     float dudx = triDerivateX(u, projection, wx, width, wy / height);
340*35238bceSAndroid Build Coastguard Worker     float dvdx = triDerivateX(v, projection, wx, width, wy / height);
341*35238bceSAndroid Build Coastguard Worker     float dudy = triDerivateY(u, projection, wy, height, wx / width);
342*35238bceSAndroid Build Coastguard Worker     float dvdy = triDerivateY(v, projection, wy, height, wx / width);
343*35238bceSAndroid Build Coastguard Worker 
344*35238bceSAndroid Build Coastguard Worker     return computeLodFromDerivates(mode, dudx, dvdx, dudy, dvdy);
345*35238bceSAndroid Build Coastguard Worker }
346*35238bceSAndroid Build Coastguard Worker 
347*35238bceSAndroid Build Coastguard Worker // 3D lookup LOD.
computeProjectedTriLod(LodMode mode,const tcu::Vec3 & u,const tcu::Vec3 & v,const tcu::Vec3 & w,const tcu::Vec3 & projection,float wx,float wy,float width,float height)348*35238bceSAndroid Build Coastguard Worker static float computeProjectedTriLod(LodMode mode, const tcu::Vec3 &u, const tcu::Vec3 &v, const tcu::Vec3 &w,
349*35238bceSAndroid Build Coastguard Worker                                     const tcu::Vec3 &projection, float wx, float wy, float width, float height)
350*35238bceSAndroid Build Coastguard Worker {
351*35238bceSAndroid Build Coastguard Worker     // Exact derivatives.
352*35238bceSAndroid Build Coastguard Worker     float dudx = triDerivateX(u, projection, wx, width, wy / height);
353*35238bceSAndroid Build Coastguard Worker     float dvdx = triDerivateX(v, projection, wx, width, wy / height);
354*35238bceSAndroid Build Coastguard Worker     float dwdx = triDerivateX(w, projection, wx, width, wy / height);
355*35238bceSAndroid Build Coastguard Worker     float dudy = triDerivateY(u, projection, wy, height, wx / width);
356*35238bceSAndroid Build Coastguard Worker     float dvdy = triDerivateY(v, projection, wy, height, wx / width);
357*35238bceSAndroid Build Coastguard Worker     float dwdy = triDerivateY(w, projection, wy, height, wx / width);
358*35238bceSAndroid Build Coastguard Worker 
359*35238bceSAndroid Build Coastguard Worker     return computeLodFromDerivates(mode, dudx, dvdx, dwdx, dudy, dvdy, dwdy);
360*35238bceSAndroid Build Coastguard Worker }
361*35238bceSAndroid Build Coastguard Worker 
execSample(const tcu::Texture1DView & src,const ReferenceParams & params,float s,float lod)362*35238bceSAndroid Build Coastguard Worker static inline tcu::Vec4 execSample(const tcu::Texture1DView &src, const ReferenceParams &params, float s, float lod)
363*35238bceSAndroid Build Coastguard Worker {
364*35238bceSAndroid Build Coastguard Worker     if (params.samplerType == SAMPLERTYPE_SHADOW)
365*35238bceSAndroid Build Coastguard Worker         return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, lod), 0.0, 0.0, 1.0f);
366*35238bceSAndroid Build Coastguard Worker     else
367*35238bceSAndroid Build Coastguard Worker         return src.sample(params.sampler, s, lod);
368*35238bceSAndroid Build Coastguard Worker }
369*35238bceSAndroid Build Coastguard Worker 
execSample(const tcu::Texture2DView & src,const ReferenceParams & params,float s,float t,float lod)370*35238bceSAndroid Build Coastguard Worker static inline tcu::Vec4 execSample(const tcu::Texture2DView &src, const ReferenceParams &params, float s, float t,
371*35238bceSAndroid Build Coastguard Worker                                    float lod)
372*35238bceSAndroid Build Coastguard Worker {
373*35238bceSAndroid Build Coastguard Worker     if (params.samplerType == SAMPLERTYPE_SHADOW)
374*35238bceSAndroid Build Coastguard Worker         return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, t, lod), 0.0, 0.0, 1.0f);
375*35238bceSAndroid Build Coastguard Worker     else
376*35238bceSAndroid Build Coastguard Worker         return src.sample(params.sampler, s, t, lod);
377*35238bceSAndroid Build Coastguard Worker }
378*35238bceSAndroid Build Coastguard Worker 
execSample(const tcu::TextureCubeView & src,const ReferenceParams & params,float s,float t,float r,float lod)379*35238bceSAndroid Build Coastguard Worker static inline tcu::Vec4 execSample(const tcu::TextureCubeView &src, const ReferenceParams &params, float s, float t,
380*35238bceSAndroid Build Coastguard Worker                                    float r, float lod)
381*35238bceSAndroid Build Coastguard Worker {
382*35238bceSAndroid Build Coastguard Worker     if (params.samplerType == SAMPLERTYPE_SHADOW)
383*35238bceSAndroid Build Coastguard Worker         return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, t, r, lod), 0.0, 0.0, 1.0f);
384*35238bceSAndroid Build Coastguard Worker     else
385*35238bceSAndroid Build Coastguard Worker         return src.sample(params.sampler, s, t, r, lod);
386*35238bceSAndroid Build Coastguard Worker }
387*35238bceSAndroid Build Coastguard Worker 
execSample(const tcu::Texture2DArrayView & src,const ReferenceParams & params,float s,float t,float r,float lod)388*35238bceSAndroid Build Coastguard Worker static inline tcu::Vec4 execSample(const tcu::Texture2DArrayView &src, const ReferenceParams &params, float s, float t,
389*35238bceSAndroid Build Coastguard Worker                                    float r, float lod)
390*35238bceSAndroid Build Coastguard Worker {
391*35238bceSAndroid Build Coastguard Worker     if (params.samplerType == SAMPLERTYPE_SHADOW)
392*35238bceSAndroid Build Coastguard Worker         return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, t, r, lod), 0.0, 0.0, 1.0f);
393*35238bceSAndroid Build Coastguard Worker     else
394*35238bceSAndroid Build Coastguard Worker         return src.sample(params.sampler, s, t, r, lod);
395*35238bceSAndroid Build Coastguard Worker }
396*35238bceSAndroid Build Coastguard Worker 
execSample(const tcu::TextureCubeArrayView & src,const ReferenceParams & params,float s,float t,float r,float q,float lod)397*35238bceSAndroid Build Coastguard Worker static inline tcu::Vec4 execSample(const tcu::TextureCubeArrayView &src, const ReferenceParams &params, float s,
398*35238bceSAndroid Build Coastguard Worker                                    float t, float r, float q, float lod)
399*35238bceSAndroid Build Coastguard Worker {
400*35238bceSAndroid Build Coastguard Worker     if (params.samplerType == SAMPLERTYPE_SHADOW)
401*35238bceSAndroid Build Coastguard Worker         return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, t, r, q, lod), 0.0, 0.0, 1.0f);
402*35238bceSAndroid Build Coastguard Worker     else
403*35238bceSAndroid Build Coastguard Worker         return src.sample(params.sampler, s, t, r, q, lod);
404*35238bceSAndroid Build Coastguard Worker }
405*35238bceSAndroid Build Coastguard Worker 
execSample(const tcu::Texture1DArrayView & src,const ReferenceParams & params,float s,float t,float lod)406*35238bceSAndroid Build Coastguard Worker static inline tcu::Vec4 execSample(const tcu::Texture1DArrayView &src, const ReferenceParams &params, float s, float t,
407*35238bceSAndroid Build Coastguard Worker                                    float lod)
408*35238bceSAndroid Build Coastguard Worker {
409*35238bceSAndroid Build Coastguard Worker     if (params.samplerType == SAMPLERTYPE_SHADOW)
410*35238bceSAndroid Build Coastguard Worker         return tcu::Vec4(src.sampleCompare(params.sampler, params.ref, s, t, lod), 0.0, 0.0, 1.0f);
411*35238bceSAndroid Build Coastguard Worker     else
412*35238bceSAndroid Build Coastguard Worker         return src.sample(params.sampler, s, t, lod);
413*35238bceSAndroid Build Coastguard Worker }
414*35238bceSAndroid Build Coastguard Worker 
sampleTextureNonProjected(const tcu::SurfaceAccess & dst,const tcu::Texture1DView & rawSrc,const tcu::Vec4 & sq,const ReferenceParams & params)415*35238bceSAndroid Build Coastguard Worker static void sampleTextureNonProjected(const tcu::SurfaceAccess &dst, const tcu::Texture1DView &rawSrc,
416*35238bceSAndroid Build Coastguard Worker                                       const tcu::Vec4 &sq, const ReferenceParams &params)
417*35238bceSAndroid Build Coastguard Worker {
418*35238bceSAndroid Build Coastguard Worker     // Separate combined DS formats
419*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
420*35238bceSAndroid Build Coastguard Worker     const tcu::Texture1DView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);
421*35238bceSAndroid Build Coastguard Worker 
422*35238bceSAndroid Build Coastguard Worker     float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;
423*35238bceSAndroid Build Coastguard Worker 
424*35238bceSAndroid Build Coastguard Worker     tcu::IVec2 dstSize = tcu::IVec2(dst.getWidth(), dst.getHeight());
425*35238bceSAndroid Build Coastguard Worker     int srcSize        = src.getWidth();
426*35238bceSAndroid Build Coastguard Worker 
427*35238bceSAndroid Build Coastguard Worker     // Coordinates and lod per triangle.
428*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
429*35238bceSAndroid Build Coastguard Worker     float triLod[2]   = {de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0]) + lodBias,
430*35238bceSAndroid Build Coastguard Worker                                    params.minLod, params.maxLod),
431*35238bceSAndroid Build Coastguard Worker                          de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1]) + lodBias,
432*35238bceSAndroid Build Coastguard Worker                                    params.minLod, params.maxLod)};
433*35238bceSAndroid Build Coastguard Worker 
434*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < dst.getHeight(); y++)
435*35238bceSAndroid Build Coastguard Worker     {
436*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < dst.getWidth(); x++)
437*35238bceSAndroid Build Coastguard Worker         {
438*35238bceSAndroid Build Coastguard Worker             float yf = ((float)y + 0.5f) / (float)dst.getHeight();
439*35238bceSAndroid Build Coastguard Worker             float xf = ((float)x + 0.5f) / (float)dst.getWidth();
440*35238bceSAndroid Build Coastguard Worker 
441*35238bceSAndroid Build Coastguard Worker             int triNdx = xf + yf >= 1.0f ? 1 : 0; // Top left fill rule.
442*35238bceSAndroid Build Coastguard Worker             float triX = triNdx ? 1.0f - xf : xf;
443*35238bceSAndroid Build Coastguard Worker             float triY = triNdx ? 1.0f - yf : yf;
444*35238bceSAndroid Build Coastguard Worker 
445*35238bceSAndroid Build Coastguard Worker             float s   = triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY);
446*35238bceSAndroid Build Coastguard Worker             float lod = triLod[triNdx];
447*35238bceSAndroid Build Coastguard Worker 
448*35238bceSAndroid Build Coastguard Worker             dst.setPixel(execSample(src, params, s, lod) * params.colorScale + params.colorBias, x, y);
449*35238bceSAndroid Build Coastguard Worker         }
450*35238bceSAndroid Build Coastguard Worker     }
451*35238bceSAndroid Build Coastguard Worker }
452*35238bceSAndroid Build Coastguard Worker 
453*35238bceSAndroid Build Coastguard Worker template <class PixelAccess>
sampleTextureNonProjected(const PixelAccess & dst,const tcu::Texture2DView & rawSrc,const tcu::Vec4 & sq,const tcu::Vec4 & tq,const ReferenceParams & params)454*35238bceSAndroid Build Coastguard Worker static void sampleTextureNonProjected(const PixelAccess &dst, const tcu::Texture2DView &rawSrc, const tcu::Vec4 &sq,
455*35238bceSAndroid Build Coastguard Worker                                       const tcu::Vec4 &tq, const ReferenceParams &params)
456*35238bceSAndroid Build Coastguard Worker {
457*35238bceSAndroid Build Coastguard Worker     // Separate combined DS formats
458*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
459*35238bceSAndroid Build Coastguard Worker     tcu::Texture2DView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);
460*35238bceSAndroid Build Coastguard Worker 
461*35238bceSAndroid Build Coastguard Worker     float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;
462*35238bceSAndroid Build Coastguard Worker 
463*35238bceSAndroid Build Coastguard Worker     tcu::IVec2 dstSize = tcu::IVec2(dst.getWidth(), dst.getHeight());
464*35238bceSAndroid Build Coastguard Worker     tcu::IVec2 srcSize = tcu::IVec2(src.getWidth(), src.getHeight());
465*35238bceSAndroid Build Coastguard Worker 
466*35238bceSAndroid Build Coastguard Worker     // Coordinates and lod per triangle.
467*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
468*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
469*35238bceSAndroid Build Coastguard Worker     float triLod[2]   = {
470*35238bceSAndroid Build Coastguard Worker         de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0], triT[0]) + lodBias,
471*35238bceSAndroid Build Coastguard Worker                     params.minLod, params.maxLod),
472*35238bceSAndroid Build Coastguard Worker         de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1], triT[1]) + lodBias,
473*35238bceSAndroid Build Coastguard Worker                     params.minLod, params.maxLod)};
474*35238bceSAndroid Build Coastguard Worker 
475*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < dst.getHeight(); y++)
476*35238bceSAndroid Build Coastguard Worker     {
477*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < dst.getWidth(); x++)
478*35238bceSAndroid Build Coastguard Worker         {
479*35238bceSAndroid Build Coastguard Worker             float yf = ((float)y + 0.5f) / (float)dst.getHeight();
480*35238bceSAndroid Build Coastguard Worker             float xf = ((float)x + 0.5f) / (float)dst.getWidth();
481*35238bceSAndroid Build Coastguard Worker 
482*35238bceSAndroid Build Coastguard Worker             int triNdx = xf + yf >= 1.0f ? 1 : 0; // Top left fill rule.
483*35238bceSAndroid Build Coastguard Worker             float triX = triNdx ? 1.0f - xf : xf;
484*35238bceSAndroid Build Coastguard Worker             float triY = triNdx ? 1.0f - yf : yf;
485*35238bceSAndroid Build Coastguard Worker 
486*35238bceSAndroid Build Coastguard Worker             float s   = triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY);
487*35238bceSAndroid Build Coastguard Worker             float t   = triangleInterpolate(triT[triNdx].x(), triT[triNdx].y(), triT[triNdx].z(), triX, triY);
488*35238bceSAndroid Build Coastguard Worker             float lod = triLod[triNdx];
489*35238bceSAndroid Build Coastguard Worker 
490*35238bceSAndroid Build Coastguard Worker             if (params.imageViewMinLod != 0.0f && params.samplerType == SAMPLERTYPE_FETCH_FLOAT)
491*35238bceSAndroid Build Coastguard Worker                 lod = (float)params.lodTexelFetch;
492*35238bceSAndroid Build Coastguard Worker 
493*35238bceSAndroid Build Coastguard Worker             if (params.float16TexCoord)
494*35238bceSAndroid Build Coastguard Worker             {
495*35238bceSAndroid Build Coastguard Worker                 s = tcu::Float16(s, tcu::ROUND_TO_ZERO).asFloat();
496*35238bceSAndroid Build Coastguard Worker                 t = tcu::Float16(t, tcu::ROUND_TO_ZERO).asFloat();
497*35238bceSAndroid Build Coastguard Worker             }
498*35238bceSAndroid Build Coastguard Worker 
499*35238bceSAndroid Build Coastguard Worker             dst.setPixel(execSample(src, params, s, t, lod) * params.colorScale + params.colorBias, x, y);
500*35238bceSAndroid Build Coastguard Worker         }
501*35238bceSAndroid Build Coastguard Worker     }
502*35238bceSAndroid Build Coastguard Worker }
503*35238bceSAndroid Build Coastguard Worker 
sampleTextureProjected(const tcu::SurfaceAccess & dst,const tcu::Texture1DView & rawSrc,const tcu::Vec4 & sq,const ReferenceParams & params)504*35238bceSAndroid Build Coastguard Worker static void sampleTextureProjected(const tcu::SurfaceAccess &dst, const tcu::Texture1DView &rawSrc, const tcu::Vec4 &sq,
505*35238bceSAndroid Build Coastguard Worker                                    const ReferenceParams &params)
506*35238bceSAndroid Build Coastguard Worker {
507*35238bceSAndroid Build Coastguard Worker     // Separate combined DS formats
508*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
509*35238bceSAndroid Build Coastguard Worker     const tcu::Texture1DView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);
510*35238bceSAndroid Build Coastguard Worker 
511*35238bceSAndroid Build Coastguard Worker     float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;
512*35238bceSAndroid Build Coastguard Worker     float dstW    = (float)dst.getWidth();
513*35238bceSAndroid Build Coastguard Worker     float dstH    = (float)dst.getHeight();
514*35238bceSAndroid Build Coastguard Worker 
515*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 uq = sq * (float)src.getWidth();
516*35238bceSAndroid Build Coastguard Worker 
517*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
518*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triU[2] = {uq.swizzle(0, 1, 2), uq.swizzle(3, 2, 1)};
519*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triW[2] = {params.w.swizzle(0, 1, 2), params.w.swizzle(3, 2, 1)};
520*35238bceSAndroid Build Coastguard Worker 
521*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < dst.getHeight(); py++)
522*35238bceSAndroid Build Coastguard Worker     {
523*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < dst.getWidth(); px++)
524*35238bceSAndroid Build Coastguard Worker         {
525*35238bceSAndroid Build Coastguard Worker             float wx = (float)px + 0.5f;
526*35238bceSAndroid Build Coastguard Worker             float wy = (float)py + 0.5f;
527*35238bceSAndroid Build Coastguard Worker             float nx = wx / dstW;
528*35238bceSAndroid Build Coastguard Worker             float ny = wy / dstH;
529*35238bceSAndroid Build Coastguard Worker 
530*35238bceSAndroid Build Coastguard Worker             int triNdx  = nx + ny >= 1.0f ? 1 : 0;
531*35238bceSAndroid Build Coastguard Worker             float triWx = triNdx ? dstW - wx : wx;
532*35238bceSAndroid Build Coastguard Worker             float triWy = triNdx ? dstH - wy : wy;
533*35238bceSAndroid Build Coastguard Worker             float triNx = triNdx ? 1.0f - nx : nx;
534*35238bceSAndroid Build Coastguard Worker             float triNy = triNdx ? 1.0f - ny : ny;
535*35238bceSAndroid Build Coastguard Worker 
536*35238bceSAndroid Build Coastguard Worker             float s   = projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy);
537*35238bceSAndroid Build Coastguard Worker             float lod = computeProjectedTriLod(params.lodMode, triU[triNdx], triW[triNdx], triWx, triWy,
538*35238bceSAndroid Build Coastguard Worker                                                (float)dst.getWidth(), (float)dst.getHeight()) +
539*35238bceSAndroid Build Coastguard Worker                         lodBias;
540*35238bceSAndroid Build Coastguard Worker 
541*35238bceSAndroid Build Coastguard Worker             dst.setPixel(execSample(src, params, s, lod) * params.colorScale + params.colorBias, px, py);
542*35238bceSAndroid Build Coastguard Worker         }
543*35238bceSAndroid Build Coastguard Worker     }
544*35238bceSAndroid Build Coastguard Worker }
545*35238bceSAndroid Build Coastguard Worker 
546*35238bceSAndroid Build Coastguard Worker template <class PixelAccess>
sampleTextureProjected(const PixelAccess & dst,const tcu::Texture2DView & rawSrc,const tcu::Vec4 & sq,const tcu::Vec4 & tq,const ReferenceParams & params)547*35238bceSAndroid Build Coastguard Worker static void sampleTextureProjected(const PixelAccess &dst, const tcu::Texture2DView &rawSrc, const tcu::Vec4 &sq,
548*35238bceSAndroid Build Coastguard Worker                                    const tcu::Vec4 &tq, const ReferenceParams &params)
549*35238bceSAndroid Build Coastguard Worker {
550*35238bceSAndroid Build Coastguard Worker     // Separate combined DS formats
551*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
552*35238bceSAndroid Build Coastguard Worker     const tcu::Texture2DView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);
553*35238bceSAndroid Build Coastguard Worker 
554*35238bceSAndroid Build Coastguard Worker     float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;
555*35238bceSAndroid Build Coastguard Worker     float dstW    = (float)dst.getWidth();
556*35238bceSAndroid Build Coastguard Worker     float dstH    = (float)dst.getHeight();
557*35238bceSAndroid Build Coastguard Worker 
558*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 uq = sq * (float)src.getWidth();
559*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 vq = tq * (float)src.getHeight();
560*35238bceSAndroid Build Coastguard Worker 
561*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
562*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
563*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triU[2] = {uq.swizzle(0, 1, 2), uq.swizzle(3, 2, 1)};
564*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triV[2] = {vq.swizzle(0, 1, 2), vq.swizzle(3, 2, 1)};
565*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triW[2] = {params.w.swizzle(0, 1, 2), params.w.swizzle(3, 2, 1)};
566*35238bceSAndroid Build Coastguard Worker 
567*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < dst.getHeight(); py++)
568*35238bceSAndroid Build Coastguard Worker     {
569*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < dst.getWidth(); px++)
570*35238bceSAndroid Build Coastguard Worker         {
571*35238bceSAndroid Build Coastguard Worker             float wx = (float)px + 0.5f;
572*35238bceSAndroid Build Coastguard Worker             float wy = (float)py + 0.5f;
573*35238bceSAndroid Build Coastguard Worker             float nx = wx / dstW;
574*35238bceSAndroid Build Coastguard Worker             float ny = wy / dstH;
575*35238bceSAndroid Build Coastguard Worker 
576*35238bceSAndroid Build Coastguard Worker             int triNdx  = nx + ny >= 1.0f ? 1 : 0;
577*35238bceSAndroid Build Coastguard Worker             float triWx = triNdx ? dstW - wx : wx;
578*35238bceSAndroid Build Coastguard Worker             float triWy = triNdx ? dstH - wy : wy;
579*35238bceSAndroid Build Coastguard Worker             float triNx = triNdx ? 1.0f - nx : nx;
580*35238bceSAndroid Build Coastguard Worker             float triNy = triNdx ? 1.0f - ny : ny;
581*35238bceSAndroid Build Coastguard Worker 
582*35238bceSAndroid Build Coastguard Worker             float s   = projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy);
583*35238bceSAndroid Build Coastguard Worker             float t   = projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy);
584*35238bceSAndroid Build Coastguard Worker             float lod = computeProjectedTriLod(params.lodMode, triU[triNdx], triV[triNdx], triW[triNdx], triWx, triWy,
585*35238bceSAndroid Build Coastguard Worker                                                (float)dst.getWidth(), (float)dst.getHeight()) +
586*35238bceSAndroid Build Coastguard Worker                         lodBias;
587*35238bceSAndroid Build Coastguard Worker 
588*35238bceSAndroid Build Coastguard Worker             dst.setPixel(execSample(src, params, s, t, lod) * params.colorScale + params.colorBias, px, py);
589*35238bceSAndroid Build Coastguard Worker         }
590*35238bceSAndroid Build Coastguard Worker     }
591*35238bceSAndroid Build Coastguard Worker }
592*35238bceSAndroid Build Coastguard Worker 
sampleTexture(const tcu::PixelBufferAccess & dst,const tcu::Texture2DView & src,const float * texCoord,const ReferenceParams & params)593*35238bceSAndroid Build Coastguard Worker void sampleTexture(const tcu::PixelBufferAccess &dst, const tcu::Texture2DView &src, const float *texCoord,
594*35238bceSAndroid Build Coastguard Worker                    const ReferenceParams &params)
595*35238bceSAndroid Build Coastguard Worker {
596*35238bceSAndroid Build Coastguard Worker     tcu::ImageViewMinLodParams minLodParams = {
597*35238bceSAndroid Build Coastguard Worker         params.baseLevel, // int baseLevel;
598*35238bceSAndroid Build Coastguard Worker         {
599*35238bceSAndroid Build Coastguard Worker             params.imageViewMinLod,     // float minLod;
600*35238bceSAndroid Build Coastguard Worker             params.imageViewMinLodMode, // ImageViewMinLodMode
601*35238bceSAndroid Build Coastguard Worker         },
602*35238bceSAndroid Build Coastguard Worker         params.samplerType == SAMPLERTYPE_FETCH_FLOAT // bool intTexCoord;
603*35238bceSAndroid Build Coastguard Worker     };
604*35238bceSAndroid Build Coastguard Worker 
605*35238bceSAndroid Build Coastguard Worker     const tcu::Texture2DView view =
606*35238bceSAndroid Build Coastguard Worker         getSubView(src, params.baseLevel, params.maxLevel, params.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL);
607*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[2 + 0], texCoord[4 + 0], texCoord[6 + 0]);
608*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[2 + 1], texCoord[4 + 1], texCoord[6 + 1]);
609*35238bceSAndroid Build Coastguard Worker 
610*35238bceSAndroid Build Coastguard Worker     if (params.flags & ReferenceParams::PROJECTED)
611*35238bceSAndroid Build Coastguard Worker         sampleTextureProjected(dst, view, sq, tq, params);
612*35238bceSAndroid Build Coastguard Worker     else
613*35238bceSAndroid Build Coastguard Worker         sampleTextureNonProjected(dst, view, sq, tq, params);
614*35238bceSAndroid Build Coastguard Worker }
615*35238bceSAndroid Build Coastguard Worker 
sampleTexture(const tcu::SurfaceAccess & dst,const tcu::Texture2DView & src,const float * texCoord,const ReferenceParams & params)616*35238bceSAndroid Build Coastguard Worker void sampleTexture(const tcu::SurfaceAccess &dst, const tcu::Texture2DView &src, const float *texCoord,
617*35238bceSAndroid Build Coastguard Worker                    const ReferenceParams &params)
618*35238bceSAndroid Build Coastguard Worker {
619*35238bceSAndroid Build Coastguard Worker     tcu::ImageViewMinLodParams minLodParams = {
620*35238bceSAndroid Build Coastguard Worker         params.baseLevel, // int baseLevel;
621*35238bceSAndroid Build Coastguard Worker         {
622*35238bceSAndroid Build Coastguard Worker             params.imageViewMinLod,     // float minLod;
623*35238bceSAndroid Build Coastguard Worker             params.imageViewMinLodMode, // ImageViewMinLodMode
624*35238bceSAndroid Build Coastguard Worker         },
625*35238bceSAndroid Build Coastguard Worker         params.samplerType == SAMPLERTYPE_FETCH_FLOAT // bool intTexCoord;
626*35238bceSAndroid Build Coastguard Worker     };
627*35238bceSAndroid Build Coastguard Worker 
628*35238bceSAndroid Build Coastguard Worker     const tcu::Texture2DView view =
629*35238bceSAndroid Build Coastguard Worker         getSubView(src, params.baseLevel, params.maxLevel, params.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL);
630*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[2 + 0], texCoord[4 + 0], texCoord[6 + 0]);
631*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[2 + 1], texCoord[4 + 1], texCoord[6 + 1]);
632*35238bceSAndroid Build Coastguard Worker 
633*35238bceSAndroid Build Coastguard Worker     if (params.flags & ReferenceParams::PROJECTED)
634*35238bceSAndroid Build Coastguard Worker         sampleTextureProjected(dst, view, sq, tq, params);
635*35238bceSAndroid Build Coastguard Worker     else
636*35238bceSAndroid Build Coastguard Worker         sampleTextureNonProjected(dst, view, sq, tq, params);
637*35238bceSAndroid Build Coastguard Worker }
638*35238bceSAndroid Build Coastguard Worker 
sampleTexture(const tcu::SurfaceAccess & dst,const tcu::Texture1DView & src,const float * texCoord,const ReferenceParams & params)639*35238bceSAndroid Build Coastguard Worker void sampleTexture(const tcu::SurfaceAccess &dst, const tcu::Texture1DView &src, const float *texCoord,
640*35238bceSAndroid Build Coastguard Worker                    const ReferenceParams &params)
641*35238bceSAndroid Build Coastguard Worker {
642*35238bceSAndroid Build Coastguard Worker     const tcu::Texture1DView view = getSubView(src, params.baseLevel, params.maxLevel, DE_NULL);
643*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq            = tcu::Vec4(texCoord[0], texCoord[1], texCoord[2], texCoord[3]);
644*35238bceSAndroid Build Coastguard Worker 
645*35238bceSAndroid Build Coastguard Worker     if (params.flags & ReferenceParams::PROJECTED)
646*35238bceSAndroid Build Coastguard Worker         sampleTextureProjected(dst, view, sq, params);
647*35238bceSAndroid Build Coastguard Worker     else
648*35238bceSAndroid Build Coastguard Worker         sampleTextureNonProjected(dst, view, sq, params);
649*35238bceSAndroid Build Coastguard Worker }
650*35238bceSAndroid Build Coastguard Worker 
computeCubeLodFromDerivates(LodMode lodMode,const tcu::Vec3 & coord,const tcu::Vec3 & coordDx,const tcu::Vec3 & coordDy,const int faceSize)651*35238bceSAndroid Build Coastguard Worker static float computeCubeLodFromDerivates(LodMode lodMode, const tcu::Vec3 &coord, const tcu::Vec3 &coordDx,
652*35238bceSAndroid Build Coastguard Worker                                          const tcu::Vec3 &coordDy, const int faceSize)
653*35238bceSAndroid Build Coastguard Worker {
654*35238bceSAndroid Build Coastguard Worker     const tcu::CubeFace face = tcu::selectCubeFace(coord);
655*35238bceSAndroid Build Coastguard Worker     int maNdx                = 0;
656*35238bceSAndroid Build Coastguard Worker     int sNdx                 = 0;
657*35238bceSAndroid Build Coastguard Worker     int tNdx                 = 0;
658*35238bceSAndroid Build Coastguard Worker 
659*35238bceSAndroid Build Coastguard Worker     // \note Derivate signs don't matter when computing lod
660*35238bceSAndroid Build Coastguard Worker     switch (face)
661*35238bceSAndroid Build Coastguard Worker     {
662*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_NEGATIVE_X:
663*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_POSITIVE_X:
664*35238bceSAndroid Build Coastguard Worker         maNdx = 0;
665*35238bceSAndroid Build Coastguard Worker         sNdx  = 2;
666*35238bceSAndroid Build Coastguard Worker         tNdx  = 1;
667*35238bceSAndroid Build Coastguard Worker         break;
668*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_NEGATIVE_Y:
669*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_POSITIVE_Y:
670*35238bceSAndroid Build Coastguard Worker         maNdx = 1;
671*35238bceSAndroid Build Coastguard Worker         sNdx  = 0;
672*35238bceSAndroid Build Coastguard Worker         tNdx  = 2;
673*35238bceSAndroid Build Coastguard Worker         break;
674*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_NEGATIVE_Z:
675*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_POSITIVE_Z:
676*35238bceSAndroid Build Coastguard Worker         maNdx = 2;
677*35238bceSAndroid Build Coastguard Worker         sNdx  = 0;
678*35238bceSAndroid Build Coastguard Worker         tNdx  = 1;
679*35238bceSAndroid Build Coastguard Worker         break;
680*35238bceSAndroid Build Coastguard Worker     default:
681*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
682*35238bceSAndroid Build Coastguard Worker     }
683*35238bceSAndroid Build Coastguard Worker 
684*35238bceSAndroid Build Coastguard Worker     {
685*35238bceSAndroid Build Coastguard Worker         const float sc   = coord[sNdx];
686*35238bceSAndroid Build Coastguard Worker         const float tc   = coord[tNdx];
687*35238bceSAndroid Build Coastguard Worker         const float ma   = de::abs(coord[maNdx]);
688*35238bceSAndroid Build Coastguard Worker         const float scdx = coordDx[sNdx];
689*35238bceSAndroid Build Coastguard Worker         const float tcdx = coordDx[tNdx];
690*35238bceSAndroid Build Coastguard Worker         const float madx = de::abs(coordDx[maNdx]);
691*35238bceSAndroid Build Coastguard Worker         const float scdy = coordDy[sNdx];
692*35238bceSAndroid Build Coastguard Worker         const float tcdy = coordDy[tNdx];
693*35238bceSAndroid Build Coastguard Worker         const float mady = de::abs(coordDy[maNdx]);
694*35238bceSAndroid Build Coastguard Worker         const float dudx = float(faceSize) * 0.5f * (scdx * ma - sc * madx) / (ma * ma);
695*35238bceSAndroid Build Coastguard Worker         const float dvdx = float(faceSize) * 0.5f * (tcdx * ma - tc * madx) / (ma * ma);
696*35238bceSAndroid Build Coastguard Worker         const float dudy = float(faceSize) * 0.5f * (scdy * ma - sc * mady) / (ma * ma);
697*35238bceSAndroid Build Coastguard Worker         const float dvdy = float(faceSize) * 0.5f * (tcdy * ma - tc * mady) / (ma * ma);
698*35238bceSAndroid Build Coastguard Worker 
699*35238bceSAndroid Build Coastguard Worker         return computeLodFromDerivates(lodMode, dudx, dvdx, dudy, dvdy);
700*35238bceSAndroid Build Coastguard Worker     }
701*35238bceSAndroid Build Coastguard Worker }
702*35238bceSAndroid Build Coastguard Worker 
sampleTextureCube(const tcu::SurfaceAccess & dst,const tcu::TextureCubeView & rawSrc,const tcu::Vec4 & sq,const tcu::Vec4 & tq,const tcu::Vec4 & rq,const ReferenceParams & params)703*35238bceSAndroid Build Coastguard Worker static void sampleTextureCube(const tcu::SurfaceAccess &dst, const tcu::TextureCubeView &rawSrc, const tcu::Vec4 &sq,
704*35238bceSAndroid Build Coastguard Worker                               const tcu::Vec4 &tq, const tcu::Vec4 &rq, const ReferenceParams &params)
705*35238bceSAndroid Build Coastguard Worker {
706*35238bceSAndroid Build Coastguard Worker     // Separate combined DS formats
707*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
708*35238bceSAndroid Build Coastguard Worker     const tcu::TextureCubeView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);
709*35238bceSAndroid Build Coastguard Worker 
710*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 dstSize = tcu::IVec2(dst.getWidth(), dst.getHeight());
711*35238bceSAndroid Build Coastguard Worker     const float dstW         = float(dstSize.x());
712*35238bceSAndroid Build Coastguard Worker     const float dstH         = float(dstSize.y());
713*35238bceSAndroid Build Coastguard Worker     const int srcSize        = src.getSize();
714*35238bceSAndroid Build Coastguard Worker 
715*35238bceSAndroid Build Coastguard Worker     // Coordinates per triangle.
716*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
717*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
718*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triR[2] = {rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1)};
719*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triW[2] = {params.w.swizzle(0, 1, 2), params.w.swizzle(3, 2, 1)};
720*35238bceSAndroid Build Coastguard Worker 
721*35238bceSAndroid Build Coastguard Worker     const float lodBias((params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f);
722*35238bceSAndroid Build Coastguard Worker 
723*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < dst.getHeight(); py++)
724*35238bceSAndroid Build Coastguard Worker     {
725*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < dst.getWidth(); px++)
726*35238bceSAndroid Build Coastguard Worker         {
727*35238bceSAndroid Build Coastguard Worker             const float wx = (float)px + 0.5f;
728*35238bceSAndroid Build Coastguard Worker             const float wy = (float)py + 0.5f;
729*35238bceSAndroid Build Coastguard Worker             const float nx = wx / dstW;
730*35238bceSAndroid Build Coastguard Worker             const float ny = wy / dstH;
731*35238bceSAndroid Build Coastguard Worker 
732*35238bceSAndroid Build Coastguard Worker             const int triNdx  = nx + ny >= 1.0f ? 1 : 0;
733*35238bceSAndroid Build Coastguard Worker             const float triNx = triNdx ? 1.0f - nx : nx;
734*35238bceSAndroid Build Coastguard Worker             const float triNy = triNdx ? 1.0f - ny : ny;
735*35238bceSAndroid Build Coastguard Worker 
736*35238bceSAndroid Build Coastguard Worker             const tcu::Vec3 coord(triangleInterpolate(triS[triNdx], triNx, triNy),
737*35238bceSAndroid Build Coastguard Worker                                   triangleInterpolate(triT[triNdx], triNx, triNy),
738*35238bceSAndroid Build Coastguard Worker                                   triangleInterpolate(triR[triNdx], triNx, triNy));
739*35238bceSAndroid Build Coastguard Worker             const tcu::Vec3 coordDx(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
740*35238bceSAndroid Build Coastguard Worker                                     triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
741*35238bceSAndroid Build Coastguard Worker                                     triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy));
742*35238bceSAndroid Build Coastguard Worker             const tcu::Vec3 coordDy(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
743*35238bceSAndroid Build Coastguard Worker                                     triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
744*35238bceSAndroid Build Coastguard Worker                                     triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx));
745*35238bceSAndroid Build Coastguard Worker 
746*35238bceSAndroid Build Coastguard Worker             const float lod =
747*35238bceSAndroid Build Coastguard Worker                 de::clamp(computeCubeLodFromDerivates(params.lodMode, coord, coordDx, coordDy, srcSize) + lodBias,
748*35238bceSAndroid Build Coastguard Worker                           params.minLod, params.maxLod);
749*35238bceSAndroid Build Coastguard Worker 
750*35238bceSAndroid Build Coastguard Worker             dst.setPixel(execSample(src, params, coord.x(), coord.y(), coord.z(), lod) * params.colorScale +
751*35238bceSAndroid Build Coastguard Worker                              params.colorBias,
752*35238bceSAndroid Build Coastguard Worker                          px, py);
753*35238bceSAndroid Build Coastguard Worker         }
754*35238bceSAndroid Build Coastguard Worker     }
755*35238bceSAndroid Build Coastguard Worker }
756*35238bceSAndroid Build Coastguard Worker 
sampleTexture(const tcu::SurfaceAccess & dst,const tcu::TextureCubeView & src,const float * texCoord,const ReferenceParams & params)757*35238bceSAndroid Build Coastguard Worker void sampleTexture(const tcu::SurfaceAccess &dst, const tcu::TextureCubeView &src, const float *texCoord,
758*35238bceSAndroid Build Coastguard Worker                    const ReferenceParams &params)
759*35238bceSAndroid Build Coastguard Worker {
760*35238bceSAndroid Build Coastguard Worker     tcu::ImageViewMinLodParams minLodParams = {
761*35238bceSAndroid Build Coastguard Worker         params.baseLevel, // int baseLevel;
762*35238bceSAndroid Build Coastguard Worker         {
763*35238bceSAndroid Build Coastguard Worker             params.imageViewMinLod,     // float minLod;
764*35238bceSAndroid Build Coastguard Worker             params.imageViewMinLodMode, // ImageViewMinLodMode
765*35238bceSAndroid Build Coastguard Worker         },
766*35238bceSAndroid Build Coastguard Worker         params.samplerType == SAMPLERTYPE_FETCH_FLOAT // bool intTexCoord;
767*35238bceSAndroid Build Coastguard Worker     };
768*35238bceSAndroid Build Coastguard Worker 
769*35238bceSAndroid Build Coastguard Worker     const tcu::TextureCubeView view =
770*35238bceSAndroid Build Coastguard Worker         getSubView(src, params.baseLevel, params.maxLevel, params.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL);
771*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]);
772*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]);
773*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 rq = tcu::Vec4(texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]);
774*35238bceSAndroid Build Coastguard Worker 
775*35238bceSAndroid Build Coastguard Worker     return sampleTextureCube(dst, view, sq, tq, rq, params);
776*35238bceSAndroid Build Coastguard Worker }
777*35238bceSAndroid Build Coastguard Worker 
sampleTextureNonProjected(const tcu::SurfaceAccess & dst,const tcu::Texture2DArrayView & rawSrc,const tcu::Vec4 & sq,const tcu::Vec4 & tq,const tcu::Vec4 & rq,const ReferenceParams & params)778*35238bceSAndroid Build Coastguard Worker static void sampleTextureNonProjected(const tcu::SurfaceAccess &dst, const tcu::Texture2DArrayView &rawSrc,
779*35238bceSAndroid Build Coastguard Worker                                       const tcu::Vec4 &sq, const tcu::Vec4 &tq, const tcu::Vec4 &rq,
780*35238bceSAndroid Build Coastguard Worker                                       const ReferenceParams &params)
781*35238bceSAndroid Build Coastguard Worker {
782*35238bceSAndroid Build Coastguard Worker     // Separate combined DS formats
783*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
784*35238bceSAndroid Build Coastguard Worker     const tcu::Texture2DArrayView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);
785*35238bceSAndroid Build Coastguard Worker 
786*35238bceSAndroid Build Coastguard Worker     float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;
787*35238bceSAndroid Build Coastguard Worker 
788*35238bceSAndroid Build Coastguard Worker     tcu::IVec2 dstSize = tcu::IVec2(dst.getWidth(), dst.getHeight());
789*35238bceSAndroid Build Coastguard Worker     tcu::IVec2 srcSize = tcu::IVec2(src.getWidth(), src.getHeight());
790*35238bceSAndroid Build Coastguard Worker 
791*35238bceSAndroid Build Coastguard Worker     // Coordinates and lod per triangle.
792*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
793*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
794*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triR[2] = {rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1)};
795*35238bceSAndroid Build Coastguard Worker     float triLod[2]   = {
796*35238bceSAndroid Build Coastguard Worker         de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0], triT[0]) + lodBias,
797*35238bceSAndroid Build Coastguard Worker                     params.minLod, params.maxLod),
798*35238bceSAndroid Build Coastguard Worker         de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1], triT[1]) + lodBias,
799*35238bceSAndroid Build Coastguard Worker                     params.minLod, params.maxLod)};
800*35238bceSAndroid Build Coastguard Worker 
801*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < dst.getHeight(); y++)
802*35238bceSAndroid Build Coastguard Worker     {
803*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < dst.getWidth(); x++)
804*35238bceSAndroid Build Coastguard Worker         {
805*35238bceSAndroid Build Coastguard Worker             float yf = ((float)y + 0.5f) / (float)dst.getHeight();
806*35238bceSAndroid Build Coastguard Worker             float xf = ((float)x + 0.5f) / (float)dst.getWidth();
807*35238bceSAndroid Build Coastguard Worker 
808*35238bceSAndroid Build Coastguard Worker             int triNdx = xf + yf >= 1.0f ? 1 : 0; // Top left fill rule.
809*35238bceSAndroid Build Coastguard Worker             float triX = triNdx ? 1.0f - xf : xf;
810*35238bceSAndroid Build Coastguard Worker             float triY = triNdx ? 1.0f - yf : yf;
811*35238bceSAndroid Build Coastguard Worker 
812*35238bceSAndroid Build Coastguard Worker             float s   = triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY);
813*35238bceSAndroid Build Coastguard Worker             float t   = triangleInterpolate(triT[triNdx].x(), triT[triNdx].y(), triT[triNdx].z(), triX, triY);
814*35238bceSAndroid Build Coastguard Worker             float r   = triangleInterpolate(triR[triNdx].x(), triR[triNdx].y(), triR[triNdx].z(), triX, triY);
815*35238bceSAndroid Build Coastguard Worker             float lod = triLod[triNdx];
816*35238bceSAndroid Build Coastguard Worker 
817*35238bceSAndroid Build Coastguard Worker             dst.setPixel(execSample(src, params, s, t, r, lod) * params.colorScale + params.colorBias, x, y);
818*35238bceSAndroid Build Coastguard Worker         }
819*35238bceSAndroid Build Coastguard Worker     }
820*35238bceSAndroid Build Coastguard Worker }
821*35238bceSAndroid Build Coastguard Worker 
sampleTexture(const tcu::SurfaceAccess & dst,const tcu::Texture2DArrayView & src,const float * texCoord,const ReferenceParams & params)822*35238bceSAndroid Build Coastguard Worker void sampleTexture(const tcu::SurfaceAccess &dst, const tcu::Texture2DArrayView &src, const float *texCoord,
823*35238bceSAndroid Build Coastguard Worker                    const ReferenceParams &params)
824*35238bceSAndroid Build Coastguard Worker {
825*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]);
826*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]);
827*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 rq = tcu::Vec4(texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]);
828*35238bceSAndroid Build Coastguard Worker 
829*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!(params.flags & ReferenceParams::PROJECTED)); // \todo [2012-02-17 pyry] Support projected lookups.
830*35238bceSAndroid Build Coastguard Worker     sampleTextureNonProjected(dst, src, sq, tq, rq, params);
831*35238bceSAndroid Build Coastguard Worker }
832*35238bceSAndroid Build Coastguard Worker 
sampleTextureNonProjected(const tcu::SurfaceAccess & dst,const tcu::Texture1DArrayView & rawSrc,const tcu::Vec4 & sq,const tcu::Vec4 & tq,const ReferenceParams & params)833*35238bceSAndroid Build Coastguard Worker static void sampleTextureNonProjected(const tcu::SurfaceAccess &dst, const tcu::Texture1DArrayView &rawSrc,
834*35238bceSAndroid Build Coastguard Worker                                       const tcu::Vec4 &sq, const tcu::Vec4 &tq, const ReferenceParams &params)
835*35238bceSAndroid Build Coastguard Worker {
836*35238bceSAndroid Build Coastguard Worker     // Separate combined DS formats
837*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
838*35238bceSAndroid Build Coastguard Worker     const tcu::Texture1DArrayView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);
839*35238bceSAndroid Build Coastguard Worker 
840*35238bceSAndroid Build Coastguard Worker     float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;
841*35238bceSAndroid Build Coastguard Worker 
842*35238bceSAndroid Build Coastguard Worker     tcu::IVec2 dstSize = tcu::IVec2(dst.getWidth(), dst.getHeight());
843*35238bceSAndroid Build Coastguard Worker     int32_t srcSize    = src.getWidth();
844*35238bceSAndroid Build Coastguard Worker 
845*35238bceSAndroid Build Coastguard Worker     // Coordinates and lod per triangle.
846*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
847*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
848*35238bceSAndroid Build Coastguard Worker     float triLod[2]   = {computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0]) + lodBias,
849*35238bceSAndroid Build Coastguard Worker                          computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1]) + lodBias};
850*35238bceSAndroid Build Coastguard Worker 
851*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < dst.getHeight(); y++)
852*35238bceSAndroid Build Coastguard Worker     {
853*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < dst.getWidth(); x++)
854*35238bceSAndroid Build Coastguard Worker         {
855*35238bceSAndroid Build Coastguard Worker             float yf = ((float)y + 0.5f) / (float)dst.getHeight();
856*35238bceSAndroid Build Coastguard Worker             float xf = ((float)x + 0.5f) / (float)dst.getWidth();
857*35238bceSAndroid Build Coastguard Worker 
858*35238bceSAndroid Build Coastguard Worker             int triNdx = xf + yf >= 1.0f ? 1 : 0; // Top left fill rule.
859*35238bceSAndroid Build Coastguard Worker             float triX = triNdx ? 1.0f - xf : xf;
860*35238bceSAndroid Build Coastguard Worker             float triY = triNdx ? 1.0f - yf : yf;
861*35238bceSAndroid Build Coastguard Worker 
862*35238bceSAndroid Build Coastguard Worker             float s   = triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY);
863*35238bceSAndroid Build Coastguard Worker             float t   = triangleInterpolate(triT[triNdx].x(), triT[triNdx].y(), triT[triNdx].z(), triX, triY);
864*35238bceSAndroid Build Coastguard Worker             float lod = triLod[triNdx];
865*35238bceSAndroid Build Coastguard Worker 
866*35238bceSAndroid Build Coastguard Worker             dst.setPixel(execSample(src, params, s, t, lod) * params.colorScale + params.colorBias, x, y);
867*35238bceSAndroid Build Coastguard Worker         }
868*35238bceSAndroid Build Coastguard Worker     }
869*35238bceSAndroid Build Coastguard Worker }
870*35238bceSAndroid Build Coastguard Worker 
sampleTexture(const tcu::SurfaceAccess & dst,const tcu::Texture1DArrayView & src,const float * texCoord,const ReferenceParams & params)871*35238bceSAndroid Build Coastguard Worker void sampleTexture(const tcu::SurfaceAccess &dst, const tcu::Texture1DArrayView &src, const float *texCoord,
872*35238bceSAndroid Build Coastguard Worker                    const ReferenceParams &params)
873*35238bceSAndroid Build Coastguard Worker {
874*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[2 + 0], texCoord[4 + 0], texCoord[6 + 0]);
875*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[2 + 1], texCoord[4 + 1], texCoord[6 + 1]);
876*35238bceSAndroid Build Coastguard Worker 
877*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!(params.flags & ReferenceParams::PROJECTED)); // \todo [2014-06-09 mika] Support projected lookups.
878*35238bceSAndroid Build Coastguard Worker     sampleTextureNonProjected(dst, src, sq, tq, params);
879*35238bceSAndroid Build Coastguard Worker }
880*35238bceSAndroid Build Coastguard Worker 
sampleTextureNonProjected(const tcu::SurfaceAccess & dst,const tcu::Texture3DView & rawSrc,const tcu::Vec4 & sq,const tcu::Vec4 & tq,const tcu::Vec4 & rq,const ReferenceParams & params)881*35238bceSAndroid Build Coastguard Worker static void sampleTextureNonProjected(const tcu::SurfaceAccess &dst, const tcu::Texture3DView &rawSrc,
882*35238bceSAndroid Build Coastguard Worker                                       const tcu::Vec4 &sq, const tcu::Vec4 &tq, const tcu::Vec4 &rq,
883*35238bceSAndroid Build Coastguard Worker                                       const ReferenceParams &params)
884*35238bceSAndroid Build Coastguard Worker {
885*35238bceSAndroid Build Coastguard Worker     // Separate combined DS formats
886*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
887*35238bceSAndroid Build Coastguard Worker     const tcu::Texture3DView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);
888*35238bceSAndroid Build Coastguard Worker 
889*35238bceSAndroid Build Coastguard Worker     float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;
890*35238bceSAndroid Build Coastguard Worker 
891*35238bceSAndroid Build Coastguard Worker     tcu::IVec2 dstSize = tcu::IVec2(dst.getWidth(), dst.getHeight());
892*35238bceSAndroid Build Coastguard Worker     tcu::IVec3 srcSize = tcu::IVec3(src.getWidth(), src.getHeight(), src.getDepth());
893*35238bceSAndroid Build Coastguard Worker 
894*35238bceSAndroid Build Coastguard Worker     // Coordinates and lod per triangle.
895*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
896*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
897*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triR[2] = {rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1)};
898*35238bceSAndroid Build Coastguard Worker     float triLod[2]   = {
899*35238bceSAndroid Build Coastguard Worker         de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[0], triT[0], triR[0]) + lodBias,
900*35238bceSAndroid Build Coastguard Worker                     params.minLod, params.maxLod),
901*35238bceSAndroid Build Coastguard Worker         de::clamp(computeNonProjectedTriLod(params.lodMode, dstSize, srcSize, triS[1], triT[1], triR[1]) + lodBias,
902*35238bceSAndroid Build Coastguard Worker                     params.minLod, params.maxLod)};
903*35238bceSAndroid Build Coastguard Worker 
904*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < dst.getHeight(); y++)
905*35238bceSAndroid Build Coastguard Worker     {
906*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < dst.getWidth(); x++)
907*35238bceSAndroid Build Coastguard Worker         {
908*35238bceSAndroid Build Coastguard Worker             float yf = ((float)y + 0.5f) / (float)dst.getHeight();
909*35238bceSAndroid Build Coastguard Worker             float xf = ((float)x + 0.5f) / (float)dst.getWidth();
910*35238bceSAndroid Build Coastguard Worker 
911*35238bceSAndroid Build Coastguard Worker             int triNdx = xf + yf >= 1.0f ? 1 : 0; // Top left fill rule.
912*35238bceSAndroid Build Coastguard Worker             float triX = triNdx ? 1.0f - xf : xf;
913*35238bceSAndroid Build Coastguard Worker             float triY = triNdx ? 1.0f - yf : yf;
914*35238bceSAndroid Build Coastguard Worker 
915*35238bceSAndroid Build Coastguard Worker             float s   = triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY);
916*35238bceSAndroid Build Coastguard Worker             float t   = triangleInterpolate(triT[triNdx].x(), triT[triNdx].y(), triT[triNdx].z(), triX, triY);
917*35238bceSAndroid Build Coastguard Worker             float r   = triangleInterpolate(triR[triNdx].x(), triR[triNdx].y(), triR[triNdx].z(), triX, triY);
918*35238bceSAndroid Build Coastguard Worker             float lod = triLod[triNdx];
919*35238bceSAndroid Build Coastguard Worker 
920*35238bceSAndroid Build Coastguard Worker             if (params.imageViewMinLod != 0.0f && params.samplerType == SAMPLERTYPE_FETCH_FLOAT)
921*35238bceSAndroid Build Coastguard Worker                 lod = (float)params.lodTexelFetch;
922*35238bceSAndroid Build Coastguard Worker 
923*35238bceSAndroid Build Coastguard Worker             dst.setPixel(src.sample(params.sampler, s, t, r, lod) * params.colorScale + params.colorBias, x, y);
924*35238bceSAndroid Build Coastguard Worker         }
925*35238bceSAndroid Build Coastguard Worker     }
926*35238bceSAndroid Build Coastguard Worker }
927*35238bceSAndroid Build Coastguard Worker 
sampleTextureProjected(const tcu::SurfaceAccess & dst,const tcu::Texture3DView & rawSrc,const tcu::Vec4 & sq,const tcu::Vec4 & tq,const tcu::Vec4 & rq,const ReferenceParams & params)928*35238bceSAndroid Build Coastguard Worker static void sampleTextureProjected(const tcu::SurfaceAccess &dst, const tcu::Texture3DView &rawSrc, const tcu::Vec4 &sq,
929*35238bceSAndroid Build Coastguard Worker                                    const tcu::Vec4 &tq, const tcu::Vec4 &rq, const ReferenceParams &params)
930*35238bceSAndroid Build Coastguard Worker {
931*35238bceSAndroid Build Coastguard Worker     // Separate combined DS formats
932*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
933*35238bceSAndroid Build Coastguard Worker     const tcu::Texture3DView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);
934*35238bceSAndroid Build Coastguard Worker 
935*35238bceSAndroid Build Coastguard Worker     float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;
936*35238bceSAndroid Build Coastguard Worker     float dstW    = (float)dst.getWidth();
937*35238bceSAndroid Build Coastguard Worker     float dstH    = (float)dst.getHeight();
938*35238bceSAndroid Build Coastguard Worker 
939*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 uq = sq * (float)src.getWidth();
940*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 vq = tq * (float)src.getHeight();
941*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 wq = rq * (float)src.getDepth();
942*35238bceSAndroid Build Coastguard Worker 
943*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
944*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
945*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triR[2] = {rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1)};
946*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triU[2] = {uq.swizzle(0, 1, 2), uq.swizzle(3, 2, 1)};
947*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triV[2] = {vq.swizzle(0, 1, 2), vq.swizzle(3, 2, 1)};
948*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triW[2] = {wq.swizzle(0, 1, 2), wq.swizzle(3, 2, 1)};
949*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triP[2] = {params.w.swizzle(0, 1, 2), params.w.swizzle(3, 2, 1)};
950*35238bceSAndroid Build Coastguard Worker 
951*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < dst.getHeight(); py++)
952*35238bceSAndroid Build Coastguard Worker     {
953*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < dst.getWidth(); px++)
954*35238bceSAndroid Build Coastguard Worker         {
955*35238bceSAndroid Build Coastguard Worker             float wx = (float)px + 0.5f;
956*35238bceSAndroid Build Coastguard Worker             float wy = (float)py + 0.5f;
957*35238bceSAndroid Build Coastguard Worker             float nx = wx / dstW;
958*35238bceSAndroid Build Coastguard Worker             float ny = wy / dstH;
959*35238bceSAndroid Build Coastguard Worker 
960*35238bceSAndroid Build Coastguard Worker             int triNdx  = nx + ny >= 1.0f ? 1 : 0;
961*35238bceSAndroid Build Coastguard Worker             float triWx = triNdx ? dstW - wx : wx;
962*35238bceSAndroid Build Coastguard Worker             float triWy = triNdx ? dstH - wy : wy;
963*35238bceSAndroid Build Coastguard Worker             float triNx = triNdx ? 1.0f - nx : nx;
964*35238bceSAndroid Build Coastguard Worker             float triNy = triNdx ? 1.0f - ny : ny;
965*35238bceSAndroid Build Coastguard Worker 
966*35238bceSAndroid Build Coastguard Worker             float s   = projectedTriInterpolate(triS[triNdx], triP[triNdx], triNx, triNy);
967*35238bceSAndroid Build Coastguard Worker             float t   = projectedTriInterpolate(triT[triNdx], triP[triNdx], triNx, triNy);
968*35238bceSAndroid Build Coastguard Worker             float r   = projectedTriInterpolate(triR[triNdx], triP[triNdx], triNx, triNy);
969*35238bceSAndroid Build Coastguard Worker             float lod = computeProjectedTriLod(params.lodMode, triU[triNdx], triV[triNdx], triW[triNdx], triP[triNdx],
970*35238bceSAndroid Build Coastguard Worker                                                triWx, triWy, (float)dst.getWidth(), (float)dst.getHeight()) +
971*35238bceSAndroid Build Coastguard Worker                         lodBias;
972*35238bceSAndroid Build Coastguard Worker 
973*35238bceSAndroid Build Coastguard Worker             dst.setPixel(src.sample(params.sampler, s, t, r, lod) * params.colorScale + params.colorBias, px, py);
974*35238bceSAndroid Build Coastguard Worker         }
975*35238bceSAndroid Build Coastguard Worker     }
976*35238bceSAndroid Build Coastguard Worker }
977*35238bceSAndroid Build Coastguard Worker 
sampleTexture(const tcu::SurfaceAccess & dst,const tcu::Texture3DView & src,const float * texCoord,const ReferenceParams & params)978*35238bceSAndroid Build Coastguard Worker void sampleTexture(const tcu::SurfaceAccess &dst, const tcu::Texture3DView &src, const float *texCoord,
979*35238bceSAndroid Build Coastguard Worker                    const ReferenceParams &params)
980*35238bceSAndroid Build Coastguard Worker {
981*35238bceSAndroid Build Coastguard Worker     tcu::ImageViewMinLodParams minLodParams = {
982*35238bceSAndroid Build Coastguard Worker         params.baseLevel, // int baseLevel;
983*35238bceSAndroid Build Coastguard Worker         {
984*35238bceSAndroid Build Coastguard Worker             params.imageViewMinLod,     // float minLod;
985*35238bceSAndroid Build Coastguard Worker             params.imageViewMinLodMode, // ImageViewMinLodMode
986*35238bceSAndroid Build Coastguard Worker         },
987*35238bceSAndroid Build Coastguard Worker         params.samplerType == SAMPLERTYPE_FETCH_FLOAT // bool intTexCoord;
988*35238bceSAndroid Build Coastguard Worker     };
989*35238bceSAndroid Build Coastguard Worker 
990*35238bceSAndroid Build Coastguard Worker     const tcu::Texture3DView view =
991*35238bceSAndroid Build Coastguard Worker         getSubView(src, params.baseLevel, params.maxLevel, params.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL);
992*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]);
993*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]);
994*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 rq = tcu::Vec4(texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]);
995*35238bceSAndroid Build Coastguard Worker 
996*35238bceSAndroid Build Coastguard Worker     if (params.flags & ReferenceParams::PROJECTED)
997*35238bceSAndroid Build Coastguard Worker         sampleTextureProjected(dst, view, sq, tq, rq, params);
998*35238bceSAndroid Build Coastguard Worker     else
999*35238bceSAndroid Build Coastguard Worker         sampleTextureNonProjected(dst, view, sq, tq, rq, params);
1000*35238bceSAndroid Build Coastguard Worker }
1001*35238bceSAndroid Build Coastguard Worker 
sampleTextureCubeArray(const tcu::SurfaceAccess & dst,const tcu::TextureCubeArrayView & rawSrc,const tcu::Vec4 & sq,const tcu::Vec4 & tq,const tcu::Vec4 & rq,const tcu::Vec4 & qq,const ReferenceParams & params)1002*35238bceSAndroid Build Coastguard Worker static void sampleTextureCubeArray(const tcu::SurfaceAccess &dst, const tcu::TextureCubeArrayView &rawSrc,
1003*35238bceSAndroid Build Coastguard Worker                                    const tcu::Vec4 &sq, const tcu::Vec4 &tq, const tcu::Vec4 &rq, const tcu::Vec4 &qq,
1004*35238bceSAndroid Build Coastguard Worker                                    const ReferenceParams &params)
1005*35238bceSAndroid Build Coastguard Worker {
1006*35238bceSAndroid Build Coastguard Worker     // Separate combined DS formats
1007*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
1008*35238bceSAndroid Build Coastguard Worker     const tcu::TextureCubeArrayView src = getEffectiveTextureView(rawSrc, srcLevelStorage, params.sampler);
1009*35238bceSAndroid Build Coastguard Worker 
1010*35238bceSAndroid Build Coastguard Worker     const float dstW = (float)dst.getWidth();
1011*35238bceSAndroid Build Coastguard Worker     const float dstH = (float)dst.getHeight();
1012*35238bceSAndroid Build Coastguard Worker 
1013*35238bceSAndroid Build Coastguard Worker     // Coordinates per triangle.
1014*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triS[2]       = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
1015*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triT[2]       = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
1016*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triR[2]       = {rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1)};
1017*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 triQ[2]       = {qq.swizzle(0, 1, 2), qq.swizzle(3, 2, 1)};
1018*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triW[2] = {params.w.swizzle(0, 1, 2), params.w.swizzle(3, 2, 1)};
1019*35238bceSAndroid Build Coastguard Worker 
1020*35238bceSAndroid Build Coastguard Worker     const float lodBias = (params.flags & ReferenceParams::USE_BIAS) ? params.bias : 0.0f;
1021*35238bceSAndroid Build Coastguard Worker 
1022*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < dst.getHeight(); py++)
1023*35238bceSAndroid Build Coastguard Worker     {
1024*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < dst.getWidth(); px++)
1025*35238bceSAndroid Build Coastguard Worker         {
1026*35238bceSAndroid Build Coastguard Worker             const float wx = (float)px + 0.5f;
1027*35238bceSAndroid Build Coastguard Worker             const float wy = (float)py + 0.5f;
1028*35238bceSAndroid Build Coastguard Worker             const float nx = wx / dstW;
1029*35238bceSAndroid Build Coastguard Worker             const float ny = wy / dstH;
1030*35238bceSAndroid Build Coastguard Worker 
1031*35238bceSAndroid Build Coastguard Worker             const int triNdx  = nx + ny >= 1.0f ? 1 : 0;
1032*35238bceSAndroid Build Coastguard Worker             const float triNx = triNdx ? 1.0f - nx : nx;
1033*35238bceSAndroid Build Coastguard Worker             const float triNy = triNdx ? 1.0f - ny : ny;
1034*35238bceSAndroid Build Coastguard Worker 
1035*35238bceSAndroid Build Coastguard Worker             const tcu::Vec3 coord(triangleInterpolate(triS[triNdx], triNx, triNy),
1036*35238bceSAndroid Build Coastguard Worker                                   triangleInterpolate(triT[triNdx], triNx, triNy),
1037*35238bceSAndroid Build Coastguard Worker                                   triangleInterpolate(triR[triNdx], triNx, triNy));
1038*35238bceSAndroid Build Coastguard Worker 
1039*35238bceSAndroid Build Coastguard Worker             const float coordQ = triangleInterpolate(triQ[triNdx], triNx, triNy);
1040*35238bceSAndroid Build Coastguard Worker 
1041*35238bceSAndroid Build Coastguard Worker             const tcu::Vec3 coordDx(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
1042*35238bceSAndroid Build Coastguard Worker                                     triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
1043*35238bceSAndroid Build Coastguard Worker                                     triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy));
1044*35238bceSAndroid Build Coastguard Worker             const tcu::Vec3 coordDy(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
1045*35238bceSAndroid Build Coastguard Worker                                     triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
1046*35238bceSAndroid Build Coastguard Worker                                     triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx));
1047*35238bceSAndroid Build Coastguard Worker 
1048*35238bceSAndroid Build Coastguard Worker             const float lod =
1049*35238bceSAndroid Build Coastguard Worker                 de::clamp(computeCubeLodFromDerivates(params.lodMode, coord, coordDx, coordDy, src.getSize()) + lodBias,
1050*35238bceSAndroid Build Coastguard Worker                           params.minLod, params.maxLod);
1051*35238bceSAndroid Build Coastguard Worker 
1052*35238bceSAndroid Build Coastguard Worker             dst.setPixel(execSample(src, params, coord.x(), coord.y(), coord.z(), coordQ, lod) * params.colorScale +
1053*35238bceSAndroid Build Coastguard Worker                              params.colorBias,
1054*35238bceSAndroid Build Coastguard Worker                          px, py);
1055*35238bceSAndroid Build Coastguard Worker         }
1056*35238bceSAndroid Build Coastguard Worker     }
1057*35238bceSAndroid Build Coastguard Worker }
1058*35238bceSAndroid Build Coastguard Worker 
sampleTexture(const tcu::SurfaceAccess & dst,const tcu::TextureCubeArrayView & src,const float * texCoord,const ReferenceParams & params)1059*35238bceSAndroid Build Coastguard Worker void sampleTexture(const tcu::SurfaceAccess &dst, const tcu::TextureCubeArrayView &src, const float *texCoord,
1060*35238bceSAndroid Build Coastguard Worker                    const ReferenceParams &params)
1061*35238bceSAndroid Build Coastguard Worker {
1062*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[4 + 0], texCoord[8 + 0], texCoord[12 + 0]);
1063*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[4 + 1], texCoord[8 + 1], texCoord[12 + 1]);
1064*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 rq = tcu::Vec4(texCoord[0 + 2], texCoord[4 + 2], texCoord[8 + 2], texCoord[12 + 2]);
1065*35238bceSAndroid Build Coastguard Worker     tcu::Vec4 qq = tcu::Vec4(texCoord[0 + 3], texCoord[4 + 3], texCoord[8 + 3], texCoord[12 + 3]);
1066*35238bceSAndroid Build Coastguard Worker 
1067*35238bceSAndroid Build Coastguard Worker     sampleTextureCubeArray(dst, src, sq, tq, rq, qq, params);
1068*35238bceSAndroid Build Coastguard Worker }
1069*35238bceSAndroid Build Coastguard Worker 
fetchTexture(const tcu::SurfaceAccess & dst,const tcu::ConstPixelBufferAccess & src,const float * texCoord,const tcu::Vec4 & colorScale,const tcu::Vec4 & colorBias)1070*35238bceSAndroid Build Coastguard Worker void fetchTexture(const tcu::SurfaceAccess &dst, const tcu::ConstPixelBufferAccess &src, const float *texCoord,
1071*35238bceSAndroid Build Coastguard Worker                   const tcu::Vec4 &colorScale, const tcu::Vec4 &colorBias)
1072*35238bceSAndroid Build Coastguard Worker {
1073*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq      = tcu::Vec4(texCoord[0], texCoord[1], texCoord[2], texCoord[3]);
1074*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
1075*35238bceSAndroid Build Coastguard Worker 
1076*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < dst.getHeight(); y++)
1077*35238bceSAndroid Build Coastguard Worker     {
1078*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < dst.getWidth(); x++)
1079*35238bceSAndroid Build Coastguard Worker         {
1080*35238bceSAndroid Build Coastguard Worker             const float yf = ((float)y + 0.5f) / (float)dst.getHeight();
1081*35238bceSAndroid Build Coastguard Worker             const float xf = ((float)x + 0.5f) / (float)dst.getWidth();
1082*35238bceSAndroid Build Coastguard Worker 
1083*35238bceSAndroid Build Coastguard Worker             const int triNdx = xf + yf >= 1.0f ? 1 : 0; // Top left fill rule.
1084*35238bceSAndroid Build Coastguard Worker             const float triX = triNdx ? 1.0f - xf : xf;
1085*35238bceSAndroid Build Coastguard Worker             const float triY = triNdx ? 1.0f - yf : yf;
1086*35238bceSAndroid Build Coastguard Worker 
1087*35238bceSAndroid Build Coastguard Worker             const float s = triangleInterpolate(triS[triNdx].x(), triS[triNdx].y(), triS[triNdx].z(), triX, triY);
1088*35238bceSAndroid Build Coastguard Worker 
1089*35238bceSAndroid Build Coastguard Worker             dst.setPixel(src.getPixel((int)s, 0) * colorScale + colorBias, x, y);
1090*35238bceSAndroid Build Coastguard Worker         }
1091*35238bceSAndroid Build Coastguard Worker     }
1092*35238bceSAndroid Build Coastguard Worker }
1093*35238bceSAndroid Build Coastguard Worker 
compareImages(tcu::TestLog & log,const tcu::Surface & reference,const tcu::Surface & rendered,tcu::RGBA threshold)1094*35238bceSAndroid Build Coastguard Worker bool compareImages(tcu::TestLog &log, const tcu::Surface &reference, const tcu::Surface &rendered, tcu::RGBA threshold)
1095*35238bceSAndroid Build Coastguard Worker {
1096*35238bceSAndroid Build Coastguard Worker     return tcu::pixelThresholdCompare(log, "Result", "Image comparison result", reference, rendered, threshold,
1097*35238bceSAndroid Build Coastguard Worker                                       tcu::COMPARE_LOG_RESULT);
1098*35238bceSAndroid Build Coastguard Worker }
1099*35238bceSAndroid Build Coastguard Worker 
compareImages(tcu::TestLog & log,const char * name,const char * desc,const tcu::Surface & reference,const tcu::Surface & rendered,tcu::RGBA threshold)1100*35238bceSAndroid Build Coastguard Worker bool compareImages(tcu::TestLog &log, const char *name, const char *desc, const tcu::Surface &reference,
1101*35238bceSAndroid Build Coastguard Worker                    const tcu::Surface &rendered, tcu::RGBA threshold)
1102*35238bceSAndroid Build Coastguard Worker {
1103*35238bceSAndroid Build Coastguard Worker     return tcu::pixelThresholdCompare(log, name, desc, reference, rendered, threshold, tcu::COMPARE_LOG_RESULT);
1104*35238bceSAndroid Build Coastguard Worker }
1105*35238bceSAndroid Build Coastguard Worker 
measureAccuracy(tcu::TestLog & log,const tcu::Surface & reference,const tcu::Surface & rendered,int bestScoreDiff,int worstScoreDiff)1106*35238bceSAndroid Build Coastguard Worker int measureAccuracy(tcu::TestLog &log, const tcu::Surface &reference, const tcu::Surface &rendered, int bestScoreDiff,
1107*35238bceSAndroid Build Coastguard Worker                     int worstScoreDiff)
1108*35238bceSAndroid Build Coastguard Worker {
1109*35238bceSAndroid Build Coastguard Worker     return tcu::measurePixelDiffAccuracy(log, "Result", "Image comparison result", reference, rendered, bestScoreDiff,
1110*35238bceSAndroid Build Coastguard Worker                                          worstScoreDiff, tcu::COMPARE_LOG_EVERYTHING);
1111*35238bceSAndroid Build Coastguard Worker }
1112*35238bceSAndroid Build Coastguard Worker 
rangeDiff(int x,int a,int b)1113*35238bceSAndroid Build Coastguard Worker inline int rangeDiff(int x, int a, int b)
1114*35238bceSAndroid Build Coastguard Worker {
1115*35238bceSAndroid Build Coastguard Worker     if (x < a)
1116*35238bceSAndroid Build Coastguard Worker         return a - x;
1117*35238bceSAndroid Build Coastguard Worker     else if (x > b)
1118*35238bceSAndroid Build Coastguard Worker         return x - b;
1119*35238bceSAndroid Build Coastguard Worker     else
1120*35238bceSAndroid Build Coastguard Worker         return 0;
1121*35238bceSAndroid Build Coastguard Worker }
1122*35238bceSAndroid Build Coastguard Worker 
rangeDiff(tcu::RGBA p,tcu::RGBA a,tcu::RGBA b)1123*35238bceSAndroid Build Coastguard Worker inline tcu::RGBA rangeDiff(tcu::RGBA p, tcu::RGBA a, tcu::RGBA b)
1124*35238bceSAndroid Build Coastguard Worker {
1125*35238bceSAndroid Build Coastguard Worker     int rMin = de::min(a.getRed(), b.getRed());
1126*35238bceSAndroid Build Coastguard Worker     int rMax = de::max(a.getRed(), b.getRed());
1127*35238bceSAndroid Build Coastguard Worker     int gMin = de::min(a.getGreen(), b.getGreen());
1128*35238bceSAndroid Build Coastguard Worker     int gMax = de::max(a.getGreen(), b.getGreen());
1129*35238bceSAndroid Build Coastguard Worker     int bMin = de::min(a.getBlue(), b.getBlue());
1130*35238bceSAndroid Build Coastguard Worker     int bMax = de::max(a.getBlue(), b.getBlue());
1131*35238bceSAndroid Build Coastguard Worker     int aMin = de::min(a.getAlpha(), b.getAlpha());
1132*35238bceSAndroid Build Coastguard Worker     int aMax = de::max(a.getAlpha(), b.getAlpha());
1133*35238bceSAndroid Build Coastguard Worker 
1134*35238bceSAndroid Build Coastguard Worker     return tcu::RGBA(rangeDiff(p.getRed(), rMin, rMax), rangeDiff(p.getGreen(), gMin, gMax),
1135*35238bceSAndroid Build Coastguard Worker                      rangeDiff(p.getBlue(), bMin, bMax), rangeDiff(p.getAlpha(), aMin, aMax));
1136*35238bceSAndroid Build Coastguard Worker }
1137*35238bceSAndroid Build Coastguard Worker 
rangeCompare(tcu::RGBA p,tcu::RGBA a,tcu::RGBA b,tcu::RGBA threshold)1138*35238bceSAndroid Build Coastguard Worker inline bool rangeCompare(tcu::RGBA p, tcu::RGBA a, tcu::RGBA b, tcu::RGBA threshold)
1139*35238bceSAndroid Build Coastguard Worker {
1140*35238bceSAndroid Build Coastguard Worker     tcu::RGBA diff = rangeDiff(p, a, b);
1141*35238bceSAndroid Build Coastguard Worker     return diff.getRed() <= threshold.getRed() && diff.getGreen() <= threshold.getGreen() &&
1142*35238bceSAndroid Build Coastguard Worker            diff.getBlue() <= threshold.getBlue() && diff.getAlpha() <= threshold.getAlpha();
1143*35238bceSAndroid Build Coastguard Worker }
1144*35238bceSAndroid Build Coastguard Worker 
computeQuadTexCoord1D(std::vector<float> & dst,float left,float right)1145*35238bceSAndroid Build Coastguard Worker void computeQuadTexCoord1D(std::vector<float> &dst, float left, float right)
1146*35238bceSAndroid Build Coastguard Worker {
1147*35238bceSAndroid Build Coastguard Worker     dst.resize(4);
1148*35238bceSAndroid Build Coastguard Worker 
1149*35238bceSAndroid Build Coastguard Worker     dst[0] = left;
1150*35238bceSAndroid Build Coastguard Worker     dst[1] = left;
1151*35238bceSAndroid Build Coastguard Worker     dst[2] = right;
1152*35238bceSAndroid Build Coastguard Worker     dst[3] = right;
1153*35238bceSAndroid Build Coastguard Worker }
1154*35238bceSAndroid Build Coastguard Worker 
computeQuadTexCoord1DArray(std::vector<float> & dst,int layerNdx,float left,float right)1155*35238bceSAndroid Build Coastguard Worker void computeQuadTexCoord1DArray(std::vector<float> &dst, int layerNdx, float left, float right)
1156*35238bceSAndroid Build Coastguard Worker {
1157*35238bceSAndroid Build Coastguard Worker     dst.resize(4 * 2);
1158*35238bceSAndroid Build Coastguard Worker 
1159*35238bceSAndroid Build Coastguard Worker     dst[0] = left;
1160*35238bceSAndroid Build Coastguard Worker     dst[1] = (float)layerNdx;
1161*35238bceSAndroid Build Coastguard Worker     dst[2] = left;
1162*35238bceSAndroid Build Coastguard Worker     dst[3] = (float)layerNdx;
1163*35238bceSAndroid Build Coastguard Worker     dst[4] = right;
1164*35238bceSAndroid Build Coastguard Worker     dst[5] = (float)layerNdx;
1165*35238bceSAndroid Build Coastguard Worker     dst[6] = right;
1166*35238bceSAndroid Build Coastguard Worker     dst[7] = (float)layerNdx;
1167*35238bceSAndroid Build Coastguard Worker }
1168*35238bceSAndroid Build Coastguard Worker 
computeQuadTexCoord2D(std::vector<float> & dst,const tcu::Vec2 & bottomLeft,const tcu::Vec2 & topRight)1169*35238bceSAndroid Build Coastguard Worker void computeQuadTexCoord2D(std::vector<float> &dst, const tcu::Vec2 &bottomLeft, const tcu::Vec2 &topRight)
1170*35238bceSAndroid Build Coastguard Worker {
1171*35238bceSAndroid Build Coastguard Worker     dst.resize(4 * 2);
1172*35238bceSAndroid Build Coastguard Worker 
1173*35238bceSAndroid Build Coastguard Worker     dst[0] = bottomLeft.x();
1174*35238bceSAndroid Build Coastguard Worker     dst[1] = bottomLeft.y();
1175*35238bceSAndroid Build Coastguard Worker     dst[2] = bottomLeft.x();
1176*35238bceSAndroid Build Coastguard Worker     dst[3] = topRight.y();
1177*35238bceSAndroid Build Coastguard Worker     dst[4] = topRight.x();
1178*35238bceSAndroid Build Coastguard Worker     dst[5] = bottomLeft.y();
1179*35238bceSAndroid Build Coastguard Worker     dst[6] = topRight.x();
1180*35238bceSAndroid Build Coastguard Worker     dst[7] = topRight.y();
1181*35238bceSAndroid Build Coastguard Worker }
1182*35238bceSAndroid Build Coastguard Worker 
computeQuadTexCoord2DArray(std::vector<float> & dst,int layerNdx,const tcu::Vec2 & bottomLeft,const tcu::Vec2 & topRight)1183*35238bceSAndroid Build Coastguard Worker void computeQuadTexCoord2DArray(std::vector<float> &dst, int layerNdx, const tcu::Vec2 &bottomLeft,
1184*35238bceSAndroid Build Coastguard Worker                                 const tcu::Vec2 &topRight)
1185*35238bceSAndroid Build Coastguard Worker {
1186*35238bceSAndroid Build Coastguard Worker     dst.resize(4 * 3);
1187*35238bceSAndroid Build Coastguard Worker 
1188*35238bceSAndroid Build Coastguard Worker     dst[0]  = bottomLeft.x();
1189*35238bceSAndroid Build Coastguard Worker     dst[1]  = bottomLeft.y();
1190*35238bceSAndroid Build Coastguard Worker     dst[2]  = (float)layerNdx;
1191*35238bceSAndroid Build Coastguard Worker     dst[3]  = bottomLeft.x();
1192*35238bceSAndroid Build Coastguard Worker     dst[4]  = topRight.y();
1193*35238bceSAndroid Build Coastguard Worker     dst[5]  = (float)layerNdx;
1194*35238bceSAndroid Build Coastguard Worker     dst[6]  = topRight.x();
1195*35238bceSAndroid Build Coastguard Worker     dst[7]  = bottomLeft.y();
1196*35238bceSAndroid Build Coastguard Worker     dst[8]  = (float)layerNdx;
1197*35238bceSAndroid Build Coastguard Worker     dst[9]  = topRight.x();
1198*35238bceSAndroid Build Coastguard Worker     dst[10] = topRight.y();
1199*35238bceSAndroid Build Coastguard Worker     dst[11] = (float)layerNdx;
1200*35238bceSAndroid Build Coastguard Worker }
1201*35238bceSAndroid Build Coastguard Worker 
computeQuadTexCoord3D(std::vector<float> & dst,const tcu::Vec3 & p0,const tcu::Vec3 & p1,const tcu::IVec3 & dirSwz)1202*35238bceSAndroid Build Coastguard Worker void computeQuadTexCoord3D(std::vector<float> &dst, const tcu::Vec3 &p0, const tcu::Vec3 &p1, const tcu::IVec3 &dirSwz)
1203*35238bceSAndroid Build Coastguard Worker {
1204*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 f0 = tcu::Vec3(0.0f, 0.0f, 0.0f).swizzle(dirSwz[0], dirSwz[1], dirSwz[2]);
1205*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 f1 = tcu::Vec3(0.0f, 1.0f, 0.0f).swizzle(dirSwz[0], dirSwz[1], dirSwz[2]);
1206*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 f2 = tcu::Vec3(1.0f, 0.0f, 0.0f).swizzle(dirSwz[0], dirSwz[1], dirSwz[2]);
1207*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 f3 = tcu::Vec3(1.0f, 1.0f, 0.0f).swizzle(dirSwz[0], dirSwz[1], dirSwz[2]);
1208*35238bceSAndroid Build Coastguard Worker 
1209*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 v0 = p0 + (p1 - p0) * f0;
1210*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 v1 = p0 + (p1 - p0) * f1;
1211*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 v2 = p0 + (p1 - p0) * f2;
1212*35238bceSAndroid Build Coastguard Worker     tcu::Vec3 v3 = p0 + (p1 - p0) * f3;
1213*35238bceSAndroid Build Coastguard Worker 
1214*35238bceSAndroid Build Coastguard Worker     dst.resize(4 * 3);
1215*35238bceSAndroid Build Coastguard Worker 
1216*35238bceSAndroid Build Coastguard Worker     dst[0]  = v0.x();
1217*35238bceSAndroid Build Coastguard Worker     dst[1]  = v0.y();
1218*35238bceSAndroid Build Coastguard Worker     dst[2]  = v0.z();
1219*35238bceSAndroid Build Coastguard Worker     dst[3]  = v1.x();
1220*35238bceSAndroid Build Coastguard Worker     dst[4]  = v1.y();
1221*35238bceSAndroid Build Coastguard Worker     dst[5]  = v1.z();
1222*35238bceSAndroid Build Coastguard Worker     dst[6]  = v2.x();
1223*35238bceSAndroid Build Coastguard Worker     dst[7]  = v2.y();
1224*35238bceSAndroid Build Coastguard Worker     dst[8]  = v2.z();
1225*35238bceSAndroid Build Coastguard Worker     dst[9]  = v3.x();
1226*35238bceSAndroid Build Coastguard Worker     dst[10] = v3.y();
1227*35238bceSAndroid Build Coastguard Worker     dst[11] = v3.z();
1228*35238bceSAndroid Build Coastguard Worker }
1229*35238bceSAndroid Build Coastguard Worker 
computeQuadTexCoordCube(std::vector<float> & dst,tcu::CubeFace face)1230*35238bceSAndroid Build Coastguard Worker void computeQuadTexCoordCube(std::vector<float> &dst, tcu::CubeFace face)
1231*35238bceSAndroid Build Coastguard Worker {
1232*35238bceSAndroid Build Coastguard Worker     static const float texCoordNegX[] = {-1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f,
1233*35238bceSAndroid Build Coastguard Worker                                          -1.0f, 1.0f, 1.0f,  -1.0f, -1.0f, 1.0f};
1234*35238bceSAndroid Build Coastguard Worker     static const float texCoordPosX[] = {+1.0f, 1.0f, 1.0f,  +1.0f, -1.0f, 1.0f,
1235*35238bceSAndroid Build Coastguard Worker                                          +1.0f, 1.0f, -1.0f, +1.0f, -1.0f, -1.0f};
1236*35238bceSAndroid Build Coastguard Worker     static const float texCoordNegY[] = {-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f,
1237*35238bceSAndroid Build Coastguard Worker                                          1.0f,  -1.0f, 1.0f, 1.0f,  -1.0f, -1.0f};
1238*35238bceSAndroid Build Coastguard Worker     static const float texCoordPosY[] = {-1.0f, +1.0f, -1.0f, -1.0f, +1.0f, 1.0f,
1239*35238bceSAndroid Build Coastguard Worker                                          1.0f,  +1.0f, -1.0f, 1.0f,  +1.0f, 1.0f};
1240*35238bceSAndroid Build Coastguard Worker     static const float texCoordNegZ[] = {1.0f,  1.0f, -1.0f, 1.0f,  -1.0f, -1.0f,
1241*35238bceSAndroid Build Coastguard Worker                                          -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f};
1242*35238bceSAndroid Build Coastguard Worker     static const float texCoordPosZ[] = {-1.0f, 1.0f, +1.0f, -1.0f, -1.0f, +1.0f,
1243*35238bceSAndroid Build Coastguard Worker                                          1.0f,  1.0f, +1.0f, 1.0f,  -1.0f, +1.0f};
1244*35238bceSAndroid Build Coastguard Worker 
1245*35238bceSAndroid Build Coastguard Worker     const float *texCoord = DE_NULL;
1246*35238bceSAndroid Build Coastguard Worker     int texCoordSize      = DE_LENGTH_OF_ARRAY(texCoordNegX);
1247*35238bceSAndroid Build Coastguard Worker 
1248*35238bceSAndroid Build Coastguard Worker     switch (face)
1249*35238bceSAndroid Build Coastguard Worker     {
1250*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_NEGATIVE_X:
1251*35238bceSAndroid Build Coastguard Worker         texCoord = texCoordNegX;
1252*35238bceSAndroid Build Coastguard Worker         break;
1253*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_POSITIVE_X:
1254*35238bceSAndroid Build Coastguard Worker         texCoord = texCoordPosX;
1255*35238bceSAndroid Build Coastguard Worker         break;
1256*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_NEGATIVE_Y:
1257*35238bceSAndroid Build Coastguard Worker         texCoord = texCoordNegY;
1258*35238bceSAndroid Build Coastguard Worker         break;
1259*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_POSITIVE_Y:
1260*35238bceSAndroid Build Coastguard Worker         texCoord = texCoordPosY;
1261*35238bceSAndroid Build Coastguard Worker         break;
1262*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_NEGATIVE_Z:
1263*35238bceSAndroid Build Coastguard Worker         texCoord = texCoordNegZ;
1264*35238bceSAndroid Build Coastguard Worker         break;
1265*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_POSITIVE_Z:
1266*35238bceSAndroid Build Coastguard Worker         texCoord = texCoordPosZ;
1267*35238bceSAndroid Build Coastguard Worker         break;
1268*35238bceSAndroid Build Coastguard Worker     default:
1269*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1270*35238bceSAndroid Build Coastguard Worker         return;
1271*35238bceSAndroid Build Coastguard Worker     }
1272*35238bceSAndroid Build Coastguard Worker 
1273*35238bceSAndroid Build Coastguard Worker     dst.resize(texCoordSize);
1274*35238bceSAndroid Build Coastguard Worker     std::copy(texCoord, texCoord + texCoordSize, dst.begin());
1275*35238bceSAndroid Build Coastguard Worker }
1276*35238bceSAndroid Build Coastguard Worker 
computeQuadTexCoordCube(std::vector<float> & dst,tcu::CubeFace face,const tcu::Vec2 & bottomLeft,const tcu::Vec2 & topRight)1277*35238bceSAndroid Build Coastguard Worker void computeQuadTexCoordCube(std::vector<float> &dst, tcu::CubeFace face, const tcu::Vec2 &bottomLeft,
1278*35238bceSAndroid Build Coastguard Worker                              const tcu::Vec2 &topRight)
1279*35238bceSAndroid Build Coastguard Worker {
1280*35238bceSAndroid Build Coastguard Worker     int sRow    = 0;
1281*35238bceSAndroid Build Coastguard Worker     int tRow    = 0;
1282*35238bceSAndroid Build Coastguard Worker     int mRow    = 0;
1283*35238bceSAndroid Build Coastguard Worker     float sSign = 1.0f;
1284*35238bceSAndroid Build Coastguard Worker     float tSign = 1.0f;
1285*35238bceSAndroid Build Coastguard Worker     float mSign = 1.0f;
1286*35238bceSAndroid Build Coastguard Worker 
1287*35238bceSAndroid Build Coastguard Worker     switch (face)
1288*35238bceSAndroid Build Coastguard Worker     {
1289*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_NEGATIVE_X:
1290*35238bceSAndroid Build Coastguard Worker         mRow  = 0;
1291*35238bceSAndroid Build Coastguard Worker         sRow  = 2;
1292*35238bceSAndroid Build Coastguard Worker         tRow  = 1;
1293*35238bceSAndroid Build Coastguard Worker         mSign = -1.0f;
1294*35238bceSAndroid Build Coastguard Worker         tSign = -1.0f;
1295*35238bceSAndroid Build Coastguard Worker         break;
1296*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_POSITIVE_X:
1297*35238bceSAndroid Build Coastguard Worker         mRow  = 0;
1298*35238bceSAndroid Build Coastguard Worker         sRow  = 2;
1299*35238bceSAndroid Build Coastguard Worker         tRow  = 1;
1300*35238bceSAndroid Build Coastguard Worker         sSign = -1.0f;
1301*35238bceSAndroid Build Coastguard Worker         tSign = -1.0f;
1302*35238bceSAndroid Build Coastguard Worker         break;
1303*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_NEGATIVE_Y:
1304*35238bceSAndroid Build Coastguard Worker         mRow  = 1;
1305*35238bceSAndroid Build Coastguard Worker         sRow  = 0;
1306*35238bceSAndroid Build Coastguard Worker         tRow  = 2;
1307*35238bceSAndroid Build Coastguard Worker         mSign = -1.0f;
1308*35238bceSAndroid Build Coastguard Worker         tSign = -1.0f;
1309*35238bceSAndroid Build Coastguard Worker         break;
1310*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_POSITIVE_Y:
1311*35238bceSAndroid Build Coastguard Worker         mRow = 1;
1312*35238bceSAndroid Build Coastguard Worker         sRow = 0;
1313*35238bceSAndroid Build Coastguard Worker         tRow = 2;
1314*35238bceSAndroid Build Coastguard Worker         break;
1315*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_NEGATIVE_Z:
1316*35238bceSAndroid Build Coastguard Worker         mRow  = 2;
1317*35238bceSAndroid Build Coastguard Worker         sRow  = 0;
1318*35238bceSAndroid Build Coastguard Worker         tRow  = 1;
1319*35238bceSAndroid Build Coastguard Worker         mSign = -1.0f;
1320*35238bceSAndroid Build Coastguard Worker         sSign = -1.0f;
1321*35238bceSAndroid Build Coastguard Worker         tSign = -1.0f;
1322*35238bceSAndroid Build Coastguard Worker         break;
1323*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_POSITIVE_Z:
1324*35238bceSAndroid Build Coastguard Worker         mRow  = 2;
1325*35238bceSAndroid Build Coastguard Worker         sRow  = 0;
1326*35238bceSAndroid Build Coastguard Worker         tRow  = 1;
1327*35238bceSAndroid Build Coastguard Worker         tSign = -1.0f;
1328*35238bceSAndroid Build Coastguard Worker         break;
1329*35238bceSAndroid Build Coastguard Worker     default:
1330*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1331*35238bceSAndroid Build Coastguard Worker         return;
1332*35238bceSAndroid Build Coastguard Worker     }
1333*35238bceSAndroid Build Coastguard Worker 
1334*35238bceSAndroid Build Coastguard Worker     dst.resize(3 * 4);
1335*35238bceSAndroid Build Coastguard Worker 
1336*35238bceSAndroid Build Coastguard Worker     dst[0 + mRow] = mSign;
1337*35238bceSAndroid Build Coastguard Worker     dst[3 + mRow] = mSign;
1338*35238bceSAndroid Build Coastguard Worker     dst[6 + mRow] = mSign;
1339*35238bceSAndroid Build Coastguard Worker     dst[9 + mRow] = mSign;
1340*35238bceSAndroid Build Coastguard Worker 
1341*35238bceSAndroid Build Coastguard Worker     dst[0 + sRow] = sSign * bottomLeft.x();
1342*35238bceSAndroid Build Coastguard Worker     dst[3 + sRow] = sSign * bottomLeft.x();
1343*35238bceSAndroid Build Coastguard Worker     dst[6 + sRow] = sSign * topRight.x();
1344*35238bceSAndroid Build Coastguard Worker     dst[9 + sRow] = sSign * topRight.x();
1345*35238bceSAndroid Build Coastguard Worker 
1346*35238bceSAndroid Build Coastguard Worker     dst[0 + tRow] = tSign * bottomLeft.y();
1347*35238bceSAndroid Build Coastguard Worker     dst[3 + tRow] = tSign * topRight.y();
1348*35238bceSAndroid Build Coastguard Worker     dst[6 + tRow] = tSign * bottomLeft.y();
1349*35238bceSAndroid Build Coastguard Worker     dst[9 + tRow] = tSign * topRight.y();
1350*35238bceSAndroid Build Coastguard Worker }
1351*35238bceSAndroid Build Coastguard Worker 
computeQuadTexCoordCubeArray(std::vector<float> & dst,tcu::CubeFace face,const tcu::Vec2 & bottomLeft,const tcu::Vec2 & topRight,const tcu::Vec2 & layerRange)1352*35238bceSAndroid Build Coastguard Worker void computeQuadTexCoordCubeArray(std::vector<float> &dst, tcu::CubeFace face, const tcu::Vec2 &bottomLeft,
1353*35238bceSAndroid Build Coastguard Worker                                   const tcu::Vec2 &topRight, const tcu::Vec2 &layerRange)
1354*35238bceSAndroid Build Coastguard Worker {
1355*35238bceSAndroid Build Coastguard Worker     int sRow       = 0;
1356*35238bceSAndroid Build Coastguard Worker     int tRow       = 0;
1357*35238bceSAndroid Build Coastguard Worker     int mRow       = 0;
1358*35238bceSAndroid Build Coastguard Worker     const int qRow = 3;
1359*35238bceSAndroid Build Coastguard Worker     float sSign    = 1.0f;
1360*35238bceSAndroid Build Coastguard Worker     float tSign    = 1.0f;
1361*35238bceSAndroid Build Coastguard Worker     float mSign    = 1.0f;
1362*35238bceSAndroid Build Coastguard Worker     const float l0 = layerRange.x();
1363*35238bceSAndroid Build Coastguard Worker     const float l1 = layerRange.y();
1364*35238bceSAndroid Build Coastguard Worker 
1365*35238bceSAndroid Build Coastguard Worker     switch (face)
1366*35238bceSAndroid Build Coastguard Worker     {
1367*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_NEGATIVE_X:
1368*35238bceSAndroid Build Coastguard Worker         mRow  = 0;
1369*35238bceSAndroid Build Coastguard Worker         sRow  = 2;
1370*35238bceSAndroid Build Coastguard Worker         tRow  = 1;
1371*35238bceSAndroid Build Coastguard Worker         mSign = -1.0f;
1372*35238bceSAndroid Build Coastguard Worker         tSign = -1.0f;
1373*35238bceSAndroid Build Coastguard Worker         break;
1374*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_POSITIVE_X:
1375*35238bceSAndroid Build Coastguard Worker         mRow  = 0;
1376*35238bceSAndroid Build Coastguard Worker         sRow  = 2;
1377*35238bceSAndroid Build Coastguard Worker         tRow  = 1;
1378*35238bceSAndroid Build Coastguard Worker         sSign = -1.0f;
1379*35238bceSAndroid Build Coastguard Worker         tSign = -1.0f;
1380*35238bceSAndroid Build Coastguard Worker         break;
1381*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_NEGATIVE_Y:
1382*35238bceSAndroid Build Coastguard Worker         mRow  = 1;
1383*35238bceSAndroid Build Coastguard Worker         sRow  = 0;
1384*35238bceSAndroid Build Coastguard Worker         tRow  = 2;
1385*35238bceSAndroid Build Coastguard Worker         mSign = -1.0f;
1386*35238bceSAndroid Build Coastguard Worker         tSign = -1.0f;
1387*35238bceSAndroid Build Coastguard Worker         break;
1388*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_POSITIVE_Y:
1389*35238bceSAndroid Build Coastguard Worker         mRow = 1;
1390*35238bceSAndroid Build Coastguard Worker         sRow = 0;
1391*35238bceSAndroid Build Coastguard Worker         tRow = 2;
1392*35238bceSAndroid Build Coastguard Worker         break;
1393*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_NEGATIVE_Z:
1394*35238bceSAndroid Build Coastguard Worker         mRow  = 2;
1395*35238bceSAndroid Build Coastguard Worker         sRow  = 0;
1396*35238bceSAndroid Build Coastguard Worker         tRow  = 1;
1397*35238bceSAndroid Build Coastguard Worker         mSign = -1.0f;
1398*35238bceSAndroid Build Coastguard Worker         sSign = -1.0f;
1399*35238bceSAndroid Build Coastguard Worker         tSign = -1.0f;
1400*35238bceSAndroid Build Coastguard Worker         break;
1401*35238bceSAndroid Build Coastguard Worker     case tcu::CUBEFACE_POSITIVE_Z:
1402*35238bceSAndroid Build Coastguard Worker         mRow  = 2;
1403*35238bceSAndroid Build Coastguard Worker         sRow  = 0;
1404*35238bceSAndroid Build Coastguard Worker         tRow  = 1;
1405*35238bceSAndroid Build Coastguard Worker         tSign = -1.0f;
1406*35238bceSAndroid Build Coastguard Worker         break;
1407*35238bceSAndroid Build Coastguard Worker     default:
1408*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
1409*35238bceSAndroid Build Coastguard Worker         return;
1410*35238bceSAndroid Build Coastguard Worker     }
1411*35238bceSAndroid Build Coastguard Worker 
1412*35238bceSAndroid Build Coastguard Worker     dst.resize(4 * 4);
1413*35238bceSAndroid Build Coastguard Worker 
1414*35238bceSAndroid Build Coastguard Worker     dst[0 + mRow]  = mSign;
1415*35238bceSAndroid Build Coastguard Worker     dst[4 + mRow]  = mSign;
1416*35238bceSAndroid Build Coastguard Worker     dst[8 + mRow]  = mSign;
1417*35238bceSAndroid Build Coastguard Worker     dst[12 + mRow] = mSign;
1418*35238bceSAndroid Build Coastguard Worker 
1419*35238bceSAndroid Build Coastguard Worker     dst[0 + sRow]  = sSign * bottomLeft.x();
1420*35238bceSAndroid Build Coastguard Worker     dst[4 + sRow]  = sSign * bottomLeft.x();
1421*35238bceSAndroid Build Coastguard Worker     dst[8 + sRow]  = sSign * topRight.x();
1422*35238bceSAndroid Build Coastguard Worker     dst[12 + sRow] = sSign * topRight.x();
1423*35238bceSAndroid Build Coastguard Worker 
1424*35238bceSAndroid Build Coastguard Worker     dst[0 + tRow]  = tSign * bottomLeft.y();
1425*35238bceSAndroid Build Coastguard Worker     dst[4 + tRow]  = tSign * topRight.y();
1426*35238bceSAndroid Build Coastguard Worker     dst[8 + tRow]  = tSign * bottomLeft.y();
1427*35238bceSAndroid Build Coastguard Worker     dst[12 + tRow] = tSign * topRight.y();
1428*35238bceSAndroid Build Coastguard Worker 
1429*35238bceSAndroid Build Coastguard Worker     if (l0 != l1)
1430*35238bceSAndroid Build Coastguard Worker     {
1431*35238bceSAndroid Build Coastguard Worker         dst[0 + qRow]  = l0;
1432*35238bceSAndroid Build Coastguard Worker         dst[4 + qRow]  = l0 * 0.5f + l1 * 0.5f;
1433*35238bceSAndroid Build Coastguard Worker         dst[8 + qRow]  = l0 * 0.5f + l1 * 0.5f;
1434*35238bceSAndroid Build Coastguard Worker         dst[12 + qRow] = l1;
1435*35238bceSAndroid Build Coastguard Worker     }
1436*35238bceSAndroid Build Coastguard Worker     else
1437*35238bceSAndroid Build Coastguard Worker     {
1438*35238bceSAndroid Build Coastguard Worker         dst[0 + qRow]  = l0;
1439*35238bceSAndroid Build Coastguard Worker         dst[4 + qRow]  = l0;
1440*35238bceSAndroid Build Coastguard Worker         dst[8 + qRow]  = l0;
1441*35238bceSAndroid Build Coastguard Worker         dst[12 + qRow] = l0;
1442*35238bceSAndroid Build Coastguard Worker     }
1443*35238bceSAndroid Build Coastguard Worker }
1444*35238bceSAndroid Build Coastguard Worker 
1445*35238bceSAndroid Build Coastguard Worker // Texture result verification
1446*35238bceSAndroid Build Coastguard Worker 
1447*35238bceSAndroid Build Coastguard Worker //! Verifies texture lookup results and returns number of failed pixels.
computeTextureLookupDiff(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & reference,const tcu::PixelBufferAccess & errorMask,const tcu::Texture1DView & baseView,const float * texCoord,const ReferenceParams & sampleParams,const tcu::LookupPrecision & lookupPrec,const tcu::LodPrecision & lodPrec,qpWatchDog * watchDog)1448*35238bceSAndroid Build Coastguard Worker int computeTextureLookupDiff(const tcu::ConstPixelBufferAccess &result, const tcu::ConstPixelBufferAccess &reference,
1449*35238bceSAndroid Build Coastguard Worker                              const tcu::PixelBufferAccess &errorMask, const tcu::Texture1DView &baseView,
1450*35238bceSAndroid Build Coastguard Worker                              const float *texCoord, const ReferenceParams &sampleParams,
1451*35238bceSAndroid Build Coastguard Worker                              const tcu::LookupPrecision &lookupPrec, const tcu::LodPrecision &lodPrec,
1452*35238bceSAndroid Build Coastguard Worker                              qpWatchDog *watchDog)
1453*35238bceSAndroid Build Coastguard Worker {
1454*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
1455*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
1456*35238bceSAndroid Build Coastguard Worker 
1457*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
1458*35238bceSAndroid Build Coastguard Worker     const tcu::Texture1DView src =
1459*35238bceSAndroid Build Coastguard Worker         getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel, DE_NULL),
1460*35238bceSAndroid Build Coastguard Worker                                 srcLevelStorage, sampleParams.sampler);
1461*35238bceSAndroid Build Coastguard Worker 
1462*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0], texCoord[1], texCoord[2], texCoord[3]);
1463*35238bceSAndroid Build Coastguard Worker 
1464*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight());
1465*35238bceSAndroid Build Coastguard Worker     const float dstW         = float(dstSize.x());
1466*35238bceSAndroid Build Coastguard Worker     const float dstH         = float(dstSize.y());
1467*35238bceSAndroid Build Coastguard Worker     const int srcSize        = src.getWidth();
1468*35238bceSAndroid Build Coastguard Worker 
1469*35238bceSAndroid Build Coastguard Worker     // Coordinates and lod per triangle.
1470*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
1471*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triW[2] = {sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1)};
1472*35238bceSAndroid Build Coastguard Worker 
1473*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodBias((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);
1474*35238bceSAndroid Build Coastguard Worker 
1475*35238bceSAndroid Build Coastguard Worker     int numFailed = 0;
1476*35238bceSAndroid Build Coastguard Worker 
1477*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodOffsets[] = {
1478*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, 0),
1479*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, 0),
1480*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, -1),
1481*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, +1),
1482*35238bceSAndroid Build Coastguard Worker     };
1483*35238bceSAndroid Build Coastguard Worker 
1484*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask, tcu::RGBA::green().toVec());
1485*35238bceSAndroid Build Coastguard Worker 
1486*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < result.getHeight(); py++)
1487*35238bceSAndroid Build Coastguard Worker     {
1488*35238bceSAndroid Build Coastguard Worker         // Ugly hack, validation can take way too long at the moment.
1489*35238bceSAndroid Build Coastguard Worker         if (watchDog)
1490*35238bceSAndroid Build Coastguard Worker             qpWatchDog_touch(watchDog);
1491*35238bceSAndroid Build Coastguard Worker 
1492*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < result.getWidth(); px++)
1493*35238bceSAndroid Build Coastguard Worker         {
1494*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale;
1495*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale;
1496*35238bceSAndroid Build Coastguard Worker 
1497*35238bceSAndroid Build Coastguard Worker             // Try comparison to ideal reference first, and if that fails use slower verificator.
1498*35238bceSAndroid Build Coastguard Worker             if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold)))
1499*35238bceSAndroid Build Coastguard Worker             {
1500*35238bceSAndroid Build Coastguard Worker                 const float wx = (float)px + 0.5f;
1501*35238bceSAndroid Build Coastguard Worker                 const float wy = (float)py + 0.5f;
1502*35238bceSAndroid Build Coastguard Worker                 const float nx = wx / dstW;
1503*35238bceSAndroid Build Coastguard Worker                 const float ny = wy / dstH;
1504*35238bceSAndroid Build Coastguard Worker 
1505*35238bceSAndroid Build Coastguard Worker                 const int triNdx  = nx + ny >= 1.0f ? 1 : 0;
1506*35238bceSAndroid Build Coastguard Worker                 const float triWx = triNdx ? dstW - wx : wx;
1507*35238bceSAndroid Build Coastguard Worker                 const float triWy = triNdx ? dstH - wy : wy;
1508*35238bceSAndroid Build Coastguard Worker                 const float triNx = triNdx ? 1.0f - nx : nx;
1509*35238bceSAndroid Build Coastguard Worker                 const float triNy = triNdx ? 1.0f - ny : ny;
1510*35238bceSAndroid Build Coastguard Worker 
1511*35238bceSAndroid Build Coastguard Worker                 const float coord   = projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy);
1512*35238bceSAndroid Build Coastguard Worker                 const float coordDx = triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy) * float(srcSize);
1513*35238bceSAndroid Build Coastguard Worker                 const float coordDy = triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx) * float(srcSize);
1514*35238bceSAndroid Build Coastguard Worker 
1515*35238bceSAndroid Build Coastguard Worker                 tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx, coordDy, lodPrec);
1516*35238bceSAndroid Build Coastguard Worker 
1517*35238bceSAndroid Build Coastguard Worker                 // Compute lod bounds across lodOffsets range.
1518*35238bceSAndroid Build Coastguard Worker                 for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
1519*35238bceSAndroid Build Coastguard Worker                 {
1520*35238bceSAndroid Build Coastguard Worker                     const float wxo = triWx + lodOffsets[lodOffsNdx].x();
1521*35238bceSAndroid Build Coastguard Worker                     const float wyo = triWy + lodOffsets[lodOffsNdx].y();
1522*35238bceSAndroid Build Coastguard Worker                     const float nxo = wxo / dstW;
1523*35238bceSAndroid Build Coastguard Worker                     const float nyo = wyo / dstH;
1524*35238bceSAndroid Build Coastguard Worker 
1525*35238bceSAndroid Build Coastguard Worker                     const float coordDxo = triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo) * float(srcSize);
1526*35238bceSAndroid Build Coastguard Worker                     const float coordDyo = triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo) * float(srcSize);
1527*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo, coordDyo, lodPrec);
1528*35238bceSAndroid Build Coastguard Worker 
1529*35238bceSAndroid Build Coastguard Worker                     lodBounds.x() = de::min(lodBounds.x(), lodO.x());
1530*35238bceSAndroid Build Coastguard Worker                     lodBounds.y() = de::max(lodBounds.y(), lodO.y());
1531*35238bceSAndroid Build Coastguard Worker                 }
1532*35238bceSAndroid Build Coastguard Worker 
1533*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 clampedLod = tcu::clampLodBounds(
1534*35238bceSAndroid Build Coastguard Worker                     lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
1535*35238bceSAndroid Build Coastguard Worker                 const bool isOk =
1536*35238bceSAndroid Build Coastguard Worker                     tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix);
1537*35238bceSAndroid Build Coastguard Worker 
1538*35238bceSAndroid Build Coastguard Worker                 if (!isOk)
1539*35238bceSAndroid Build Coastguard Worker                 {
1540*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
1541*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
1542*35238bceSAndroid Build Coastguard Worker                 }
1543*35238bceSAndroid Build Coastguard Worker             }
1544*35238bceSAndroid Build Coastguard Worker         }
1545*35238bceSAndroid Build Coastguard Worker     }
1546*35238bceSAndroid Build Coastguard Worker 
1547*35238bceSAndroid Build Coastguard Worker     return numFailed;
1548*35238bceSAndroid Build Coastguard Worker }
1549*35238bceSAndroid Build Coastguard Worker 
computeTextureLookupDiff(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & reference,const tcu::PixelBufferAccess & errorMask,const tcu::Texture2DView & baseView,const float * texCoord,const ReferenceParams & sampleParams,const tcu::LookupPrecision & lookupPrec,const tcu::LodPrecision & lodPrec,qpWatchDog * watchDog)1550*35238bceSAndroid Build Coastguard Worker int computeTextureLookupDiff(const tcu::ConstPixelBufferAccess &result, const tcu::ConstPixelBufferAccess &reference,
1551*35238bceSAndroid Build Coastguard Worker                              const tcu::PixelBufferAccess &errorMask, const tcu::Texture2DView &baseView,
1552*35238bceSAndroid Build Coastguard Worker                              const float *texCoord, const ReferenceParams &sampleParams,
1553*35238bceSAndroid Build Coastguard Worker                              const tcu::LookupPrecision &lookupPrec, const tcu::LodPrecision &lodPrec,
1554*35238bceSAndroid Build Coastguard Worker                              qpWatchDog *watchDog)
1555*35238bceSAndroid Build Coastguard Worker {
1556*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
1557*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
1558*35238bceSAndroid Build Coastguard Worker 
1559*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
1560*35238bceSAndroid Build Coastguard Worker     tcu::ImageViewMinLodParams minLodParams = {
1561*35238bceSAndroid Build Coastguard Worker         sampleParams.baseLevel, // int baseLevel;
1562*35238bceSAndroid Build Coastguard Worker         {
1563*35238bceSAndroid Build Coastguard Worker             sampleParams.imageViewMinLod,     // float minLod;
1564*35238bceSAndroid Build Coastguard Worker             sampleParams.imageViewMinLodMode, // ImageViewMinLodMode
1565*35238bceSAndroid Build Coastguard Worker         },
1566*35238bceSAndroid Build Coastguard Worker         sampleParams.samplerType == SAMPLERTYPE_FETCH_FLOAT // bool intTexCoord;
1567*35238bceSAndroid Build Coastguard Worker     };
1568*35238bceSAndroid Build Coastguard Worker 
1569*35238bceSAndroid Build Coastguard Worker     const tcu::Texture2DView view = getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel,
1570*35238bceSAndroid Build Coastguard Worker                                                sampleParams.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL);
1571*35238bceSAndroid Build Coastguard Worker 
1572*35238bceSAndroid Build Coastguard Worker     const tcu::Texture2DView src = getEffectiveTextureView(view, srcLevelStorage, sampleParams.sampler);
1573*35238bceSAndroid Build Coastguard Worker 
1574*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[2 + 0], texCoord[4 + 0], texCoord[6 + 0]);
1575*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[2 + 1], texCoord[4 + 1], texCoord[6 + 1]);
1576*35238bceSAndroid Build Coastguard Worker 
1577*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight());
1578*35238bceSAndroid Build Coastguard Worker     const float dstW         = float(dstSize.x());
1579*35238bceSAndroid Build Coastguard Worker     const float dstH         = float(dstSize.y());
1580*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 srcSize = tcu::IVec2(src.getWidth(), src.getHeight());
1581*35238bceSAndroid Build Coastguard Worker 
1582*35238bceSAndroid Build Coastguard Worker     // Coordinates and lod per triangle.
1583*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
1584*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
1585*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triW[2] = {sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1)};
1586*35238bceSAndroid Build Coastguard Worker 
1587*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodBias((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);
1588*35238bceSAndroid Build Coastguard Worker 
1589*35238bceSAndroid Build Coastguard Worker     // imageViewMinLodRel is used to calculate the image level to sample from, when VK_EXT_image_view_min_lod extension is enabled.
1590*35238bceSAndroid Build Coastguard Worker     // The value is relative to baseLevel as the Texture*View 'src' was created as the baseLevel being level[0].
1591*35238bceSAndroid Build Coastguard Worker     const float imageViewMinLodRel = sampleParams.imageViewMinLod - (float)sampleParams.baseLevel;
1592*35238bceSAndroid Build Coastguard Worker     // We need to adapt ImageView's minLod value to the mipmap mdoe (i.e. nearest or linear) so we clamp with the right minLod value later.
1593*35238bceSAndroid Build Coastguard Worker     const float imageViewMinLodRelMode = tcu::isSamplerMipmapModeLinear(sampleParams.sampler.minFilter) ?
1594*35238bceSAndroid Build Coastguard Worker                                              deFloatFloor(imageViewMinLodRel) :
1595*35238bceSAndroid Build Coastguard Worker                                              (float)deClamp32((int)deFloatCeil(imageViewMinLodRel + 0.5f) - 1,
1596*35238bceSAndroid Build Coastguard Worker                                                               sampleParams.baseLevel, sampleParams.maxLevel);
1597*35238bceSAndroid Build Coastguard Worker     const float minLod = (sampleParams.imageViewMinLod != 0.0f) ? de::max(imageViewMinLodRelMode, sampleParams.minLod) :
1598*35238bceSAndroid Build Coastguard Worker                                                                   sampleParams.minLod;
1599*35238bceSAndroid Build Coastguard Worker 
1600*35238bceSAndroid Build Coastguard Worker     const float posEps = 1.0f / float(1 << MIN_SUBPIXEL_BITS);
1601*35238bceSAndroid Build Coastguard Worker 
1602*35238bceSAndroid Build Coastguard Worker     int numFailed = 0;
1603*35238bceSAndroid Build Coastguard Worker 
1604*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodOffsets[] = {
1605*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, 0),
1606*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, 0),
1607*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, -1),
1608*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, +1),
1609*35238bceSAndroid Build Coastguard Worker     };
1610*35238bceSAndroid Build Coastguard Worker 
1611*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask, tcu::RGBA::green().toVec());
1612*35238bceSAndroid Build Coastguard Worker 
1613*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < result.getHeight(); py++)
1614*35238bceSAndroid Build Coastguard Worker     {
1615*35238bceSAndroid Build Coastguard Worker         // Ugly hack, validation can take way too long at the moment.
1616*35238bceSAndroid Build Coastguard Worker         if (watchDog)
1617*35238bceSAndroid Build Coastguard Worker             qpWatchDog_touch(watchDog);
1618*35238bceSAndroid Build Coastguard Worker 
1619*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < result.getWidth(); px++)
1620*35238bceSAndroid Build Coastguard Worker         {
1621*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale;
1622*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale;
1623*35238bceSAndroid Build Coastguard Worker 
1624*35238bceSAndroid Build Coastguard Worker             // Try comparison to ideal reference first, and if that fails use slower verificator.
1625*35238bceSAndroid Build Coastguard Worker             if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold)))
1626*35238bceSAndroid Build Coastguard Worker             {
1627*35238bceSAndroid Build Coastguard Worker                 const float wx = (float)px + 0.5f;
1628*35238bceSAndroid Build Coastguard Worker                 const float wy = (float)py + 0.5f;
1629*35238bceSAndroid Build Coastguard Worker                 const float nx = wx / dstW;
1630*35238bceSAndroid Build Coastguard Worker                 const float ny = wy / dstH;
1631*35238bceSAndroid Build Coastguard Worker 
1632*35238bceSAndroid Build Coastguard Worker                 const bool tri0 = (wx - posEps) / dstW + (wy - posEps) / dstH <= 1.0f;
1633*35238bceSAndroid Build Coastguard Worker                 const bool tri1 = (wx + posEps) / dstW + (wy + posEps) / dstH >= 1.0f;
1634*35238bceSAndroid Build Coastguard Worker 
1635*35238bceSAndroid Build Coastguard Worker                 bool isOk = false;
1636*35238bceSAndroid Build Coastguard Worker 
1637*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(tri0 || tri1);
1638*35238bceSAndroid Build Coastguard Worker 
1639*35238bceSAndroid Build Coastguard Worker                 // Pixel can belong to either of the triangles if it lies close enough to the edge.
1640*35238bceSAndroid Build Coastguard Worker                 for (int triNdx = (tri0 ? 0 : 1); triNdx <= (tri1 ? 1 : 0); triNdx++)
1641*35238bceSAndroid Build Coastguard Worker                 {
1642*35238bceSAndroid Build Coastguard Worker                     const float triWx = triNdx ? dstW - wx : wx;
1643*35238bceSAndroid Build Coastguard Worker                     const float triWy = triNdx ? dstH - wy : wy;
1644*35238bceSAndroid Build Coastguard Worker                     const float triNx = triNdx ? 1.0f - nx : nx;
1645*35238bceSAndroid Build Coastguard Worker                     const float triNy = triNdx ? 1.0f - ny : ny;
1646*35238bceSAndroid Build Coastguard Worker 
1647*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 coord(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
1648*35238bceSAndroid Build Coastguard Worker                                           projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy));
1649*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 coordDx = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
1650*35238bceSAndroid Build Coastguard Worker                                                         triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) *
1651*35238bceSAndroid Build Coastguard Worker                                               srcSize.asFloat();
1652*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 coordDy = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
1653*35238bceSAndroid Build Coastguard Worker                                                         triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) *
1654*35238bceSAndroid Build Coastguard Worker                                               srcSize.asFloat();
1655*35238bceSAndroid Build Coastguard Worker 
1656*35238bceSAndroid Build Coastguard Worker                     tcu::Vec2 lodBounds =
1657*35238bceSAndroid Build Coastguard Worker                         tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec);
1658*35238bceSAndroid Build Coastguard Worker 
1659*35238bceSAndroid Build Coastguard Worker                     // Compute lod bounds across lodOffsets range.
1660*35238bceSAndroid Build Coastguard Worker                     for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
1661*35238bceSAndroid Build Coastguard Worker                     {
1662*35238bceSAndroid Build Coastguard Worker                         const float wxo = triWx + lodOffsets[lodOffsNdx].x();
1663*35238bceSAndroid Build Coastguard Worker                         const float wyo = triWy + lodOffsets[lodOffsNdx].y();
1664*35238bceSAndroid Build Coastguard Worker                         const float nxo = wxo / dstW;
1665*35238bceSAndroid Build Coastguard Worker                         const float nyo = wyo / dstH;
1666*35238bceSAndroid Build Coastguard Worker 
1667*35238bceSAndroid Build Coastguard Worker                         const tcu::Vec2 coordDxo = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
1668*35238bceSAndroid Build Coastguard Worker                                                              triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) *
1669*35238bceSAndroid Build Coastguard Worker                                                    srcSize.asFloat();
1670*35238bceSAndroid Build Coastguard Worker                         const tcu::Vec2 coordDyo = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
1671*35238bceSAndroid Build Coastguard Worker                                                              triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) *
1672*35238bceSAndroid Build Coastguard Worker                                                    srcSize.asFloat();
1673*35238bceSAndroid Build Coastguard Worker                         const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(),
1674*35238bceSAndroid Build Coastguard Worker                                                                                   coordDyo.x(), coordDyo.y(), lodPrec);
1675*35238bceSAndroid Build Coastguard Worker 
1676*35238bceSAndroid Build Coastguard Worker                         lodBounds.x() = de::min(lodBounds.x(), lodO.x());
1677*35238bceSAndroid Build Coastguard Worker                         lodBounds.y() = de::max(lodBounds.y(), lodO.y());
1678*35238bceSAndroid Build Coastguard Worker                     }
1679*35238bceSAndroid Build Coastguard Worker 
1680*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 clampedLod =
1681*35238bceSAndroid Build Coastguard Worker                         tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(minLod, sampleParams.maxLod), lodPrec);
1682*35238bceSAndroid Build Coastguard Worker                     if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix))
1683*35238bceSAndroid Build Coastguard Worker                     {
1684*35238bceSAndroid Build Coastguard Worker                         isOk = true;
1685*35238bceSAndroid Build Coastguard Worker                         break;
1686*35238bceSAndroid Build Coastguard Worker                     }
1687*35238bceSAndroid Build Coastguard Worker                 }
1688*35238bceSAndroid Build Coastguard Worker 
1689*35238bceSAndroid Build Coastguard Worker                 if (!isOk)
1690*35238bceSAndroid Build Coastguard Worker                 {
1691*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
1692*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
1693*35238bceSAndroid Build Coastguard Worker                 }
1694*35238bceSAndroid Build Coastguard Worker             }
1695*35238bceSAndroid Build Coastguard Worker         }
1696*35238bceSAndroid Build Coastguard Worker     }
1697*35238bceSAndroid Build Coastguard Worker 
1698*35238bceSAndroid Build Coastguard Worker     return numFailed;
1699*35238bceSAndroid Build Coastguard Worker }
1700*35238bceSAndroid Build Coastguard Worker 
verifyTextureResult(tcu::TestContext & testCtx,const tcu::ConstPixelBufferAccess & result,const tcu::Texture1DView & src,const float * texCoord,const ReferenceParams & sampleParams,const tcu::LookupPrecision & lookupPrec,const tcu::LodPrecision & lodPrec,const tcu::PixelFormat & pixelFormat)1701*35238bceSAndroid Build Coastguard Worker bool verifyTextureResult(tcu::TestContext &testCtx, const tcu::ConstPixelBufferAccess &result,
1702*35238bceSAndroid Build Coastguard Worker                          const tcu::Texture1DView &src, const float *texCoord, const ReferenceParams &sampleParams,
1703*35238bceSAndroid Build Coastguard Worker                          const tcu::LookupPrecision &lookupPrec, const tcu::LodPrecision &lodPrec,
1704*35238bceSAndroid Build Coastguard Worker                          const tcu::PixelFormat &pixelFormat)
1705*35238bceSAndroid Build Coastguard Worker {
1706*35238bceSAndroid Build Coastguard Worker     tcu::TestLog &log = testCtx.getLog();
1707*35238bceSAndroid Build Coastguard Worker     tcu::Surface reference(result.getWidth(), result.getHeight());
1708*35238bceSAndroid Build Coastguard Worker     tcu::Surface errorMask(result.getWidth(), result.getHeight());
1709*35238bceSAndroid Build Coastguard Worker     int numFailedPixels;
1710*35238bceSAndroid Build Coastguard Worker 
1711*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask);
1712*35238bceSAndroid Build Coastguard Worker 
1713*35238bceSAndroid Build Coastguard Worker     sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
1714*35238bceSAndroid Build Coastguard Worker     numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord,
1715*35238bceSAndroid Build Coastguard Worker                                                sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog());
1716*35238bceSAndroid Build Coastguard Worker 
1717*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
1718*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels
1719*35238bceSAndroid Build Coastguard Worker             << " invalid pixels!" << tcu::TestLog::EndMessage;
1720*35238bceSAndroid Build Coastguard Worker 
1721*35238bceSAndroid Build Coastguard Worker     log << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
1722*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::Image("Rendered", "Rendered image", result);
1723*35238bceSAndroid Build Coastguard Worker 
1724*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
1725*35238bceSAndroid Build Coastguard Worker     {
1726*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
1727*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
1728*35238bceSAndroid Build Coastguard Worker     }
1729*35238bceSAndroid Build Coastguard Worker 
1730*35238bceSAndroid Build Coastguard Worker     log << tcu::TestLog::EndImageSet;
1731*35238bceSAndroid Build Coastguard Worker 
1732*35238bceSAndroid Build Coastguard Worker     return numFailedPixels == 0;
1733*35238bceSAndroid Build Coastguard Worker }
1734*35238bceSAndroid Build Coastguard Worker 
verifyTextureResult(tcu::TestContext & testCtx,const tcu::ConstPixelBufferAccess & result,const tcu::Texture2DView & src,const float * texCoord,const ReferenceParams & sampleParams,const tcu::LookupPrecision & lookupPrec,const tcu::LodPrecision & lodPrec,const tcu::PixelFormat & pixelFormat)1735*35238bceSAndroid Build Coastguard Worker bool verifyTextureResult(tcu::TestContext &testCtx, const tcu::ConstPixelBufferAccess &result,
1736*35238bceSAndroid Build Coastguard Worker                          const tcu::Texture2DView &src, const float *texCoord, const ReferenceParams &sampleParams,
1737*35238bceSAndroid Build Coastguard Worker                          const tcu::LookupPrecision &lookupPrec, const tcu::LodPrecision &lodPrec,
1738*35238bceSAndroid Build Coastguard Worker                          const tcu::PixelFormat &pixelFormat)
1739*35238bceSAndroid Build Coastguard Worker {
1740*35238bceSAndroid Build Coastguard Worker     tcu::TestLog &log = testCtx.getLog();
1741*35238bceSAndroid Build Coastguard Worker     tcu::Surface reference(result.getWidth(), result.getHeight());
1742*35238bceSAndroid Build Coastguard Worker     tcu::Surface errorMask(result.getWidth(), result.getHeight());
1743*35238bceSAndroid Build Coastguard Worker     int numFailedPixels;
1744*35238bceSAndroid Build Coastguard Worker 
1745*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask);
1746*35238bceSAndroid Build Coastguard Worker 
1747*35238bceSAndroid Build Coastguard Worker     sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
1748*35238bceSAndroid Build Coastguard Worker     numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord,
1749*35238bceSAndroid Build Coastguard Worker                                                sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog());
1750*35238bceSAndroid Build Coastguard Worker 
1751*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
1752*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels
1753*35238bceSAndroid Build Coastguard Worker             << " invalid pixels!" << tcu::TestLog::EndMessage;
1754*35238bceSAndroid Build Coastguard Worker 
1755*35238bceSAndroid Build Coastguard Worker     log << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
1756*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::Image("Rendered", "Rendered image", result);
1757*35238bceSAndroid Build Coastguard Worker 
1758*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
1759*35238bceSAndroid Build Coastguard Worker     {
1760*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
1761*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
1762*35238bceSAndroid Build Coastguard Worker     }
1763*35238bceSAndroid Build Coastguard Worker 
1764*35238bceSAndroid Build Coastguard Worker     log << tcu::TestLog::EndImageSet;
1765*35238bceSAndroid Build Coastguard Worker 
1766*35238bceSAndroid Build Coastguard Worker     return numFailedPixels == 0;
1767*35238bceSAndroid Build Coastguard Worker }
1768*35238bceSAndroid Build Coastguard Worker 
1769*35238bceSAndroid Build Coastguard Worker //! Verifies texture lookup results and returns number of failed pixels.
computeTextureLookupDiff(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & reference,const tcu::PixelBufferAccess & errorMask,const tcu::TextureCubeView & baseView,const float * texCoord,const ReferenceParams & sampleParams,const tcu::LookupPrecision & lookupPrec,const tcu::LodPrecision & lodPrec,qpWatchDog * watchDog)1770*35238bceSAndroid Build Coastguard Worker int computeTextureLookupDiff(const tcu::ConstPixelBufferAccess &result, const tcu::ConstPixelBufferAccess &reference,
1771*35238bceSAndroid Build Coastguard Worker                              const tcu::PixelBufferAccess &errorMask, const tcu::TextureCubeView &baseView,
1772*35238bceSAndroid Build Coastguard Worker                              const float *texCoord, const ReferenceParams &sampleParams,
1773*35238bceSAndroid Build Coastguard Worker                              const tcu::LookupPrecision &lookupPrec, const tcu::LodPrecision &lodPrec,
1774*35238bceSAndroid Build Coastguard Worker                              qpWatchDog *watchDog)
1775*35238bceSAndroid Build Coastguard Worker {
1776*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
1777*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
1778*35238bceSAndroid Build Coastguard Worker 
1779*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
1780*35238bceSAndroid Build Coastguard Worker     tcu::ImageViewMinLodParams minLodParams = {
1781*35238bceSAndroid Build Coastguard Worker         sampleParams.baseLevel, // int baseLevel;
1782*35238bceSAndroid Build Coastguard Worker         {
1783*35238bceSAndroid Build Coastguard Worker             sampleParams.imageViewMinLod,     // float minLod;
1784*35238bceSAndroid Build Coastguard Worker             sampleParams.imageViewMinLodMode, // ImageViewMinLodMode
1785*35238bceSAndroid Build Coastguard Worker         },
1786*35238bceSAndroid Build Coastguard Worker         sampleParams.samplerType == SAMPLERTYPE_FETCH_FLOAT // bool intTexCoord;
1787*35238bceSAndroid Build Coastguard Worker     };
1788*35238bceSAndroid Build Coastguard Worker 
1789*35238bceSAndroid Build Coastguard Worker     const tcu::TextureCubeView src =
1790*35238bceSAndroid Build Coastguard Worker         getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel,
1791*35238bceSAndroid Build Coastguard Worker                                            sampleParams.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL),
1792*35238bceSAndroid Build Coastguard Worker                                 srcLevelStorage, sampleParams.sampler);
1793*35238bceSAndroid Build Coastguard Worker 
1794*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]);
1795*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]);
1796*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 rq = tcu::Vec4(texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]);
1797*35238bceSAndroid Build Coastguard Worker 
1798*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight());
1799*35238bceSAndroid Build Coastguard Worker     const float dstW         = float(dstSize.x());
1800*35238bceSAndroid Build Coastguard Worker     const float dstH         = float(dstSize.y());
1801*35238bceSAndroid Build Coastguard Worker     const int srcSize        = src.getSize();
1802*35238bceSAndroid Build Coastguard Worker 
1803*35238bceSAndroid Build Coastguard Worker     // Coordinates per triangle.
1804*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
1805*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
1806*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triR[2] = {rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1)};
1807*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triW[2] = {sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1)};
1808*35238bceSAndroid Build Coastguard Worker 
1809*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodBias((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);
1810*35238bceSAndroid Build Coastguard Worker 
1811*35238bceSAndroid Build Coastguard Worker     const float posEps = 1.0f / float(1 << MIN_SUBPIXEL_BITS);
1812*35238bceSAndroid Build Coastguard Worker 
1813*35238bceSAndroid Build Coastguard Worker     // imageViewMinLodRel is used to calculate the image level to sample from, when VK_EXT_image_view_min_lod extension is enabled.
1814*35238bceSAndroid Build Coastguard Worker     // The value is relative to baseLevel as the Texture*View 'src' was created as the baseLevel being level[0].
1815*35238bceSAndroid Build Coastguard Worker     const float imageViewMinLodRel = sampleParams.imageViewMinLod - (float)sampleParams.baseLevel;
1816*35238bceSAndroid Build Coastguard Worker     // We need to adapt ImageView's minLod value to the mipmap mdoe (i.e. nearest or linear) so we clamp with the right minLod value later.
1817*35238bceSAndroid Build Coastguard Worker     const float imageViewMinLodRelMode = tcu::isSamplerMipmapModeLinear(sampleParams.sampler.minFilter) ?
1818*35238bceSAndroid Build Coastguard Worker                                              deFloatFloor(imageViewMinLodRel) :
1819*35238bceSAndroid Build Coastguard Worker                                              (float)deClamp32((int)deFloatCeil(imageViewMinLodRel + 0.5f) - 1,
1820*35238bceSAndroid Build Coastguard Worker                                                               sampleParams.baseLevel, sampleParams.maxLevel);
1821*35238bceSAndroid Build Coastguard Worker     const float minLod = (sampleParams.imageViewMinLod != 0.0f) ? de::max(imageViewMinLodRelMode, sampleParams.minLod) :
1822*35238bceSAndroid Build Coastguard Worker                                                                   sampleParams.minLod;
1823*35238bceSAndroid Build Coastguard Worker 
1824*35238bceSAndroid Build Coastguard Worker     int numFailed = 0;
1825*35238bceSAndroid Build Coastguard Worker 
1826*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodOffsets[] = {
1827*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, 0),
1828*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, 0),
1829*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, -1),
1830*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, +1),
1831*35238bceSAndroid Build Coastguard Worker 
1832*35238bceSAndroid Build Coastguard Worker         // \note Not strictly allowed by spec, but implementations do this in practice.
1833*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, -1),
1834*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, +1),
1835*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, -1),
1836*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, +1),
1837*35238bceSAndroid Build Coastguard Worker     };
1838*35238bceSAndroid Build Coastguard Worker 
1839*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask, tcu::RGBA::green().toVec());
1840*35238bceSAndroid Build Coastguard Worker 
1841*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < result.getHeight(); py++)
1842*35238bceSAndroid Build Coastguard Worker     {
1843*35238bceSAndroid Build Coastguard Worker         // Ugly hack, validation can take way too long at the moment.
1844*35238bceSAndroid Build Coastguard Worker         if (watchDog)
1845*35238bceSAndroid Build Coastguard Worker             qpWatchDog_touch(watchDog);
1846*35238bceSAndroid Build Coastguard Worker 
1847*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < result.getWidth(); px++)
1848*35238bceSAndroid Build Coastguard Worker         {
1849*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale;
1850*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale;
1851*35238bceSAndroid Build Coastguard Worker 
1852*35238bceSAndroid Build Coastguard Worker             // Try comparison to ideal reference first, and if that fails use slower verificator.
1853*35238bceSAndroid Build Coastguard Worker             if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold)))
1854*35238bceSAndroid Build Coastguard Worker             {
1855*35238bceSAndroid Build Coastguard Worker                 const float wx = (float)px + 0.5f;
1856*35238bceSAndroid Build Coastguard Worker                 const float wy = (float)py + 0.5f;
1857*35238bceSAndroid Build Coastguard Worker                 const float nx = wx / dstW;
1858*35238bceSAndroid Build Coastguard Worker                 const float ny = wy / dstH;
1859*35238bceSAndroid Build Coastguard Worker 
1860*35238bceSAndroid Build Coastguard Worker                 const bool tri0 = (wx - posEps) / dstW + (wy - posEps) / dstH <= 1.0f;
1861*35238bceSAndroid Build Coastguard Worker                 const bool tri1 = (wx + posEps) / dstW + (wy + posEps) / dstH >= 1.0f;
1862*35238bceSAndroid Build Coastguard Worker 
1863*35238bceSAndroid Build Coastguard Worker                 bool isOk = false;
1864*35238bceSAndroid Build Coastguard Worker 
1865*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(tri0 || tri1);
1866*35238bceSAndroid Build Coastguard Worker 
1867*35238bceSAndroid Build Coastguard Worker                 // Pixel can belong to either of the triangles if it lies close enough to the edge.
1868*35238bceSAndroid Build Coastguard Worker                 for (int triNdx = (tri0 ? 0 : 1); triNdx <= (tri1 ? 1 : 0); triNdx++)
1869*35238bceSAndroid Build Coastguard Worker                 {
1870*35238bceSAndroid Build Coastguard Worker                     const float triWx = triNdx ? dstW - wx : wx;
1871*35238bceSAndroid Build Coastguard Worker                     const float triWy = triNdx ? dstH - wy : wy;
1872*35238bceSAndroid Build Coastguard Worker                     const float triNx = triNdx ? 1.0f - nx : nx;
1873*35238bceSAndroid Build Coastguard Worker                     const float triNy = triNdx ? 1.0f - ny : ny;
1874*35238bceSAndroid Build Coastguard Worker 
1875*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec3 coord(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
1876*35238bceSAndroid Build Coastguard Worker                                           projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
1877*35238bceSAndroid Build Coastguard Worker                                           projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy));
1878*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec3 coordDx(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
1879*35238bceSAndroid Build Coastguard Worker                                             triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
1880*35238bceSAndroid Build Coastguard Worker                                             triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy));
1881*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec3 coordDy(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
1882*35238bceSAndroid Build Coastguard Worker                                             triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
1883*35238bceSAndroid Build Coastguard Worker                                             triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx));
1884*35238bceSAndroid Build Coastguard Worker 
1885*35238bceSAndroid Build Coastguard Worker                     tcu::Vec2 lodBounds =
1886*35238bceSAndroid Build Coastguard Worker                         tcu::computeCubeLodBoundsFromDerivates(coord, coordDx, coordDy, srcSize, lodPrec);
1887*35238bceSAndroid Build Coastguard Worker 
1888*35238bceSAndroid Build Coastguard Worker                     // Compute lod bounds across lodOffsets range.
1889*35238bceSAndroid Build Coastguard Worker                     for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
1890*35238bceSAndroid Build Coastguard Worker                     {
1891*35238bceSAndroid Build Coastguard Worker                         const float wxo = triWx + lodOffsets[lodOffsNdx].x();
1892*35238bceSAndroid Build Coastguard Worker                         const float wyo = triWy + lodOffsets[lodOffsNdx].y();
1893*35238bceSAndroid Build Coastguard Worker                         const float nxo = wxo / dstW;
1894*35238bceSAndroid Build Coastguard Worker                         const float nyo = wyo / dstH;
1895*35238bceSAndroid Build Coastguard Worker 
1896*35238bceSAndroid Build Coastguard Worker                         const tcu::Vec3 coordO(projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo),
1897*35238bceSAndroid Build Coastguard Worker                                                projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo),
1898*35238bceSAndroid Build Coastguard Worker                                                projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo));
1899*35238bceSAndroid Build Coastguard Worker                         const tcu::Vec3 coordDxo(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
1900*35238bceSAndroid Build Coastguard Worker                                                  triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo),
1901*35238bceSAndroid Build Coastguard Worker                                                  triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo));
1902*35238bceSAndroid Build Coastguard Worker                         const tcu::Vec3 coordDyo(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
1903*35238bceSAndroid Build Coastguard Worker                                                  triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo),
1904*35238bceSAndroid Build Coastguard Worker                                                  triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo));
1905*35238bceSAndroid Build Coastguard Worker                         const tcu::Vec2 lodO =
1906*35238bceSAndroid Build Coastguard Worker                             tcu::computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec);
1907*35238bceSAndroid Build Coastguard Worker 
1908*35238bceSAndroid Build Coastguard Worker                         lodBounds.x() = de::min(lodBounds.x(), lodO.x());
1909*35238bceSAndroid Build Coastguard Worker                         lodBounds.y() = de::max(lodBounds.y(), lodO.y());
1910*35238bceSAndroid Build Coastguard Worker                     }
1911*35238bceSAndroid Build Coastguard Worker 
1912*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 clampedLod =
1913*35238bceSAndroid Build Coastguard Worker                         tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(minLod, sampleParams.maxLod), lodPrec);
1914*35238bceSAndroid Build Coastguard Worker 
1915*35238bceSAndroid Build Coastguard Worker                     if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix))
1916*35238bceSAndroid Build Coastguard Worker                     {
1917*35238bceSAndroid Build Coastguard Worker                         isOk = true;
1918*35238bceSAndroid Build Coastguard Worker                         break;
1919*35238bceSAndroid Build Coastguard Worker                     }
1920*35238bceSAndroid Build Coastguard Worker                 }
1921*35238bceSAndroid Build Coastguard Worker 
1922*35238bceSAndroid Build Coastguard Worker                 if (!isOk)
1923*35238bceSAndroid Build Coastguard Worker                 {
1924*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
1925*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
1926*35238bceSAndroid Build Coastguard Worker                 }
1927*35238bceSAndroid Build Coastguard Worker             }
1928*35238bceSAndroid Build Coastguard Worker         }
1929*35238bceSAndroid Build Coastguard Worker     }
1930*35238bceSAndroid Build Coastguard Worker 
1931*35238bceSAndroid Build Coastguard Worker     return numFailed;
1932*35238bceSAndroid Build Coastguard Worker }
1933*35238bceSAndroid Build Coastguard Worker 
verifyTextureResult(tcu::TestContext & testCtx,const tcu::ConstPixelBufferAccess & result,const tcu::TextureCubeView & src,const float * texCoord,const ReferenceParams & sampleParams,const tcu::LookupPrecision & lookupPrec,const tcu::LodPrecision & lodPrec,const tcu::PixelFormat & pixelFormat)1934*35238bceSAndroid Build Coastguard Worker bool verifyTextureResult(tcu::TestContext &testCtx, const tcu::ConstPixelBufferAccess &result,
1935*35238bceSAndroid Build Coastguard Worker                          const tcu::TextureCubeView &src, const float *texCoord, const ReferenceParams &sampleParams,
1936*35238bceSAndroid Build Coastguard Worker                          const tcu::LookupPrecision &lookupPrec, const tcu::LodPrecision &lodPrec,
1937*35238bceSAndroid Build Coastguard Worker                          const tcu::PixelFormat &pixelFormat)
1938*35238bceSAndroid Build Coastguard Worker {
1939*35238bceSAndroid Build Coastguard Worker     tcu::TestLog &log = testCtx.getLog();
1940*35238bceSAndroid Build Coastguard Worker     tcu::Surface reference(result.getWidth(), result.getHeight());
1941*35238bceSAndroid Build Coastguard Worker     tcu::Surface errorMask(result.getWidth(), result.getHeight());
1942*35238bceSAndroid Build Coastguard Worker     int numFailedPixels;
1943*35238bceSAndroid Build Coastguard Worker 
1944*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask);
1945*35238bceSAndroid Build Coastguard Worker 
1946*35238bceSAndroid Build Coastguard Worker     sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
1947*35238bceSAndroid Build Coastguard Worker     numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord,
1948*35238bceSAndroid Build Coastguard Worker                                                sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog());
1949*35238bceSAndroid Build Coastguard Worker 
1950*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
1951*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels
1952*35238bceSAndroid Build Coastguard Worker             << " invalid pixels!" << tcu::TestLog::EndMessage;
1953*35238bceSAndroid Build Coastguard Worker 
1954*35238bceSAndroid Build Coastguard Worker     log << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
1955*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::Image("Rendered", "Rendered image", result);
1956*35238bceSAndroid Build Coastguard Worker 
1957*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
1958*35238bceSAndroid Build Coastguard Worker     {
1959*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
1960*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
1961*35238bceSAndroid Build Coastguard Worker     }
1962*35238bceSAndroid Build Coastguard Worker 
1963*35238bceSAndroid Build Coastguard Worker     log << tcu::TestLog::EndImageSet;
1964*35238bceSAndroid Build Coastguard Worker 
1965*35238bceSAndroid Build Coastguard Worker     return numFailedPixels == 0;
1966*35238bceSAndroid Build Coastguard Worker }
1967*35238bceSAndroid Build Coastguard Worker 
1968*35238bceSAndroid Build Coastguard Worker //! Verifies texture lookup results and returns number of failed pixels.
computeTextureLookupDiff(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & reference,const tcu::PixelBufferAccess & errorMask,const tcu::Texture3DView & baseView,const float * texCoord,const ReferenceParams & sampleParams,const tcu::LookupPrecision & lookupPrec,const tcu::LodPrecision & lodPrec,qpWatchDog * watchDog)1969*35238bceSAndroid Build Coastguard Worker int computeTextureLookupDiff(const tcu::ConstPixelBufferAccess &result, const tcu::ConstPixelBufferAccess &reference,
1970*35238bceSAndroid Build Coastguard Worker                              const tcu::PixelBufferAccess &errorMask, const tcu::Texture3DView &baseView,
1971*35238bceSAndroid Build Coastguard Worker                              const float *texCoord, const ReferenceParams &sampleParams,
1972*35238bceSAndroid Build Coastguard Worker                              const tcu::LookupPrecision &lookupPrec, const tcu::LodPrecision &lodPrec,
1973*35238bceSAndroid Build Coastguard Worker                              qpWatchDog *watchDog)
1974*35238bceSAndroid Build Coastguard Worker {
1975*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
1976*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
1977*35238bceSAndroid Build Coastguard Worker 
1978*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
1979*35238bceSAndroid Build Coastguard Worker     tcu::ImageViewMinLodParams minLodParams = {
1980*35238bceSAndroid Build Coastguard Worker         sampleParams.baseLevel, // int baseLevel;
1981*35238bceSAndroid Build Coastguard Worker         {
1982*35238bceSAndroid Build Coastguard Worker             sampleParams.imageViewMinLod,     // float minLod;
1983*35238bceSAndroid Build Coastguard Worker             sampleParams.imageViewMinLodMode, // ImageViewMinLodMode
1984*35238bceSAndroid Build Coastguard Worker         },
1985*35238bceSAndroid Build Coastguard Worker         sampleParams.samplerType == SAMPLERTYPE_FETCH_FLOAT // bool intTexCoord;
1986*35238bceSAndroid Build Coastguard Worker     };
1987*35238bceSAndroid Build Coastguard Worker 
1988*35238bceSAndroid Build Coastguard Worker     const tcu::Texture3DView src =
1989*35238bceSAndroid Build Coastguard Worker         getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel,
1990*35238bceSAndroid Build Coastguard Worker                                            sampleParams.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL),
1991*35238bceSAndroid Build Coastguard Worker                                 srcLevelStorage, sampleParams.sampler);
1992*35238bceSAndroid Build Coastguard Worker 
1993*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]);
1994*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]);
1995*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 rq = tcu::Vec4(texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]);
1996*35238bceSAndroid Build Coastguard Worker 
1997*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight());
1998*35238bceSAndroid Build Coastguard Worker     const float dstW         = float(dstSize.x());
1999*35238bceSAndroid Build Coastguard Worker     const float dstH         = float(dstSize.y());
2000*35238bceSAndroid Build Coastguard Worker     const tcu::IVec3 srcSize = tcu::IVec3(src.getWidth(), src.getHeight(), src.getDepth());
2001*35238bceSAndroid Build Coastguard Worker 
2002*35238bceSAndroid Build Coastguard Worker     // Coordinates and lod per triangle.
2003*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
2004*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
2005*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triR[2] = {rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1)};
2006*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triW[2] = {sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1)};
2007*35238bceSAndroid Build Coastguard Worker 
2008*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodBias((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);
2009*35238bceSAndroid Build Coastguard Worker 
2010*35238bceSAndroid Build Coastguard Worker     // imageViewMinLodRel is used to calculate the image level to sample from, when VK_EXT_image_view_min_lod extension is enabled.
2011*35238bceSAndroid Build Coastguard Worker     // The value is relative to baseLevel as the Texture*View 'src' was created as the baseLevel being level[0].
2012*35238bceSAndroid Build Coastguard Worker     const float imageViewMinLodRel = sampleParams.imageViewMinLod - (float)sampleParams.baseLevel;
2013*35238bceSAndroid Build Coastguard Worker     // We need to adapt ImageView's minLod value to the mipmap mdoe (i.e. nearest or linear) so we clamp with the right minLod value later.
2014*35238bceSAndroid Build Coastguard Worker     const float imageViewMinLodRelMode = tcu::isSamplerMipmapModeLinear(sampleParams.sampler.minFilter) ?
2015*35238bceSAndroid Build Coastguard Worker                                              deFloatFloor(imageViewMinLodRel) :
2016*35238bceSAndroid Build Coastguard Worker                                              (float)deClamp32((int)deFloatCeil(imageViewMinLodRel + 0.5f) - 1,
2017*35238bceSAndroid Build Coastguard Worker                                                               sampleParams.baseLevel, sampleParams.maxLevel);
2018*35238bceSAndroid Build Coastguard Worker     const float minLod = (sampleParams.imageViewMinLod != 0.0f) ? de::max(imageViewMinLodRelMode, sampleParams.minLod) :
2019*35238bceSAndroid Build Coastguard Worker                                                                   sampleParams.minLod;
2020*35238bceSAndroid Build Coastguard Worker 
2021*35238bceSAndroid Build Coastguard Worker     const float posEps = 1.0f / float(1 << MIN_SUBPIXEL_BITS);
2022*35238bceSAndroid Build Coastguard Worker 
2023*35238bceSAndroid Build Coastguard Worker     int numFailed = 0;
2024*35238bceSAndroid Build Coastguard Worker 
2025*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodOffsets[] = {
2026*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, 0),
2027*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, 0),
2028*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, -1),
2029*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, +1),
2030*35238bceSAndroid Build Coastguard Worker     };
2031*35238bceSAndroid Build Coastguard Worker 
2032*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask, tcu::RGBA::green().toVec());
2033*35238bceSAndroid Build Coastguard Worker 
2034*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < result.getHeight(); py++)
2035*35238bceSAndroid Build Coastguard Worker     {
2036*35238bceSAndroid Build Coastguard Worker         // Ugly hack, validation can take way too long at the moment.
2037*35238bceSAndroid Build Coastguard Worker         if (watchDog)
2038*35238bceSAndroid Build Coastguard Worker             qpWatchDog_touch(watchDog);
2039*35238bceSAndroid Build Coastguard Worker 
2040*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < result.getWidth(); px++)
2041*35238bceSAndroid Build Coastguard Worker         {
2042*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale;
2043*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale;
2044*35238bceSAndroid Build Coastguard Worker 
2045*35238bceSAndroid Build Coastguard Worker             // Try comparison to ideal reference first, and if that fails use slower verificator.
2046*35238bceSAndroid Build Coastguard Worker             if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold)))
2047*35238bceSAndroid Build Coastguard Worker             {
2048*35238bceSAndroid Build Coastguard Worker                 const float wx = (float)px + 0.5f;
2049*35238bceSAndroid Build Coastguard Worker                 const float wy = (float)py + 0.5f;
2050*35238bceSAndroid Build Coastguard Worker                 const float nx = wx / dstW;
2051*35238bceSAndroid Build Coastguard Worker                 const float ny = wy / dstH;
2052*35238bceSAndroid Build Coastguard Worker 
2053*35238bceSAndroid Build Coastguard Worker                 const bool tri0 = (wx - posEps) / dstW + (wy - posEps) / dstH <= 1.0f;
2054*35238bceSAndroid Build Coastguard Worker                 const bool tri1 = (wx + posEps) / dstW + (wy + posEps) / dstH >= 1.0f;
2055*35238bceSAndroid Build Coastguard Worker 
2056*35238bceSAndroid Build Coastguard Worker                 bool isOk = false;
2057*35238bceSAndroid Build Coastguard Worker 
2058*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(tri0 || tri1);
2059*35238bceSAndroid Build Coastguard Worker 
2060*35238bceSAndroid Build Coastguard Worker                 // Pixel can belong to either of the triangles if it lies close enough to the edge.
2061*35238bceSAndroid Build Coastguard Worker                 for (int triNdx = (tri0 ? 0 : 1); triNdx <= (tri1 ? 1 : 0); triNdx++)
2062*35238bceSAndroid Build Coastguard Worker                 {
2063*35238bceSAndroid Build Coastguard Worker                     const float triWx = triNdx ? dstW - wx : wx;
2064*35238bceSAndroid Build Coastguard Worker                     const float triWy = triNdx ? dstH - wy : wy;
2065*35238bceSAndroid Build Coastguard Worker                     const float triNx = triNdx ? 1.0f - nx : nx;
2066*35238bceSAndroid Build Coastguard Worker                     const float triNy = triNdx ? 1.0f - ny : ny;
2067*35238bceSAndroid Build Coastguard Worker 
2068*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec3 coord(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
2069*35238bceSAndroid Build Coastguard Worker                                           projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
2070*35238bceSAndroid Build Coastguard Worker                                           projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy));
2071*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec3 coordDx = tcu::Vec3(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
2072*35238bceSAndroid Build Coastguard Worker                                                         triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
2073*35238bceSAndroid Build Coastguard Worker                                                         triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy)) *
2074*35238bceSAndroid Build Coastguard Worker                                               srcSize.asFloat();
2075*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec3 coordDy = tcu::Vec3(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
2076*35238bceSAndroid Build Coastguard Worker                                                         triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
2077*35238bceSAndroid Build Coastguard Worker                                                         triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx)) *
2078*35238bceSAndroid Build Coastguard Worker                                               srcSize.asFloat();
2079*35238bceSAndroid Build Coastguard Worker 
2080*35238bceSAndroid Build Coastguard Worker                     tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(
2081*35238bceSAndroid Build Coastguard Worker                         coordDx.x(), coordDx.y(), coordDx.z(), coordDy.x(), coordDy.y(), coordDy.z(), lodPrec);
2082*35238bceSAndroid Build Coastguard Worker 
2083*35238bceSAndroid Build Coastguard Worker                     // Compute lod bounds across lodOffsets range.
2084*35238bceSAndroid Build Coastguard Worker                     for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
2085*35238bceSAndroid Build Coastguard Worker                     {
2086*35238bceSAndroid Build Coastguard Worker                         const float wxo = triWx + lodOffsets[lodOffsNdx].x();
2087*35238bceSAndroid Build Coastguard Worker                         const float wyo = triWy + lodOffsets[lodOffsNdx].y();
2088*35238bceSAndroid Build Coastguard Worker                         const float nxo = wxo / dstW;
2089*35238bceSAndroid Build Coastguard Worker                         const float nyo = wyo / dstH;
2090*35238bceSAndroid Build Coastguard Worker 
2091*35238bceSAndroid Build Coastguard Worker                         const tcu::Vec3 coordDxo = tcu::Vec3(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
2092*35238bceSAndroid Build Coastguard Worker                                                              triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo),
2093*35238bceSAndroid Build Coastguard Worker                                                              triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo)) *
2094*35238bceSAndroid Build Coastguard Worker                                                    srcSize.asFloat();
2095*35238bceSAndroid Build Coastguard Worker                         const tcu::Vec3 coordDyo = tcu::Vec3(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
2096*35238bceSAndroid Build Coastguard Worker                                                              triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo),
2097*35238bceSAndroid Build Coastguard Worker                                                              triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo)) *
2098*35238bceSAndroid Build Coastguard Worker                                                    srcSize.asFloat();
2099*35238bceSAndroid Build Coastguard Worker                         const tcu::Vec2 lodO =
2100*35238bceSAndroid Build Coastguard Worker                             tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDxo.z(), coordDyo.x(),
2101*35238bceSAndroid Build Coastguard Worker                                                                coordDyo.y(), coordDyo.z(), lodPrec);
2102*35238bceSAndroid Build Coastguard Worker 
2103*35238bceSAndroid Build Coastguard Worker                         lodBounds.x() = de::min(lodBounds.x(), lodO.x());
2104*35238bceSAndroid Build Coastguard Worker                         lodBounds.y() = de::max(lodBounds.y(), lodO.y());
2105*35238bceSAndroid Build Coastguard Worker                     }
2106*35238bceSAndroid Build Coastguard Worker 
2107*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 clampedLod =
2108*35238bceSAndroid Build Coastguard Worker                         tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(minLod, sampleParams.maxLod), lodPrec);
2109*35238bceSAndroid Build Coastguard Worker 
2110*35238bceSAndroid Build Coastguard Worker                     if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix))
2111*35238bceSAndroid Build Coastguard Worker                     {
2112*35238bceSAndroid Build Coastguard Worker                         isOk = true;
2113*35238bceSAndroid Build Coastguard Worker                         break;
2114*35238bceSAndroid Build Coastguard Worker                     }
2115*35238bceSAndroid Build Coastguard Worker                 }
2116*35238bceSAndroid Build Coastguard Worker 
2117*35238bceSAndroid Build Coastguard Worker                 if (!isOk)
2118*35238bceSAndroid Build Coastguard Worker                 {
2119*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
2120*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
2121*35238bceSAndroid Build Coastguard Worker                 }
2122*35238bceSAndroid Build Coastguard Worker             }
2123*35238bceSAndroid Build Coastguard Worker         }
2124*35238bceSAndroid Build Coastguard Worker     }
2125*35238bceSAndroid Build Coastguard Worker 
2126*35238bceSAndroid Build Coastguard Worker     return numFailed;
2127*35238bceSAndroid Build Coastguard Worker }
2128*35238bceSAndroid Build Coastguard Worker 
verifyTextureResult(tcu::TestContext & testCtx,const tcu::ConstPixelBufferAccess & result,const tcu::Texture3DView & src,const float * texCoord,const ReferenceParams & sampleParams,const tcu::LookupPrecision & lookupPrec,const tcu::LodPrecision & lodPrec,const tcu::PixelFormat & pixelFormat)2129*35238bceSAndroid Build Coastguard Worker bool verifyTextureResult(tcu::TestContext &testCtx, const tcu::ConstPixelBufferAccess &result,
2130*35238bceSAndroid Build Coastguard Worker                          const tcu::Texture3DView &src, const float *texCoord, const ReferenceParams &sampleParams,
2131*35238bceSAndroid Build Coastguard Worker                          const tcu::LookupPrecision &lookupPrec, const tcu::LodPrecision &lodPrec,
2132*35238bceSAndroid Build Coastguard Worker                          const tcu::PixelFormat &pixelFormat)
2133*35238bceSAndroid Build Coastguard Worker {
2134*35238bceSAndroid Build Coastguard Worker     tcu::TestLog &log = testCtx.getLog();
2135*35238bceSAndroid Build Coastguard Worker     tcu::Surface reference(result.getWidth(), result.getHeight());
2136*35238bceSAndroid Build Coastguard Worker     tcu::Surface errorMask(result.getWidth(), result.getHeight());
2137*35238bceSAndroid Build Coastguard Worker     int numFailedPixels;
2138*35238bceSAndroid Build Coastguard Worker 
2139*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask);
2140*35238bceSAndroid Build Coastguard Worker 
2141*35238bceSAndroid Build Coastguard Worker     sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
2142*35238bceSAndroid Build Coastguard Worker     numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord,
2143*35238bceSAndroid Build Coastguard Worker                                                sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog());
2144*35238bceSAndroid Build Coastguard Worker 
2145*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
2146*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels
2147*35238bceSAndroid Build Coastguard Worker             << " invalid pixels!" << tcu::TestLog::EndMessage;
2148*35238bceSAndroid Build Coastguard Worker 
2149*35238bceSAndroid Build Coastguard Worker     log << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
2150*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::Image("Rendered", "Rendered image", result);
2151*35238bceSAndroid Build Coastguard Worker 
2152*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
2153*35238bceSAndroid Build Coastguard Worker     {
2154*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
2155*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
2156*35238bceSAndroid Build Coastguard Worker     }
2157*35238bceSAndroid Build Coastguard Worker 
2158*35238bceSAndroid Build Coastguard Worker     log << tcu::TestLog::EndImageSet;
2159*35238bceSAndroid Build Coastguard Worker 
2160*35238bceSAndroid Build Coastguard Worker     return numFailedPixels == 0;
2161*35238bceSAndroid Build Coastguard Worker }
2162*35238bceSAndroid Build Coastguard Worker 
2163*35238bceSAndroid Build Coastguard Worker //! Verifies texture lookup results and returns number of failed pixels.
computeTextureLookupDiff(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & reference,const tcu::PixelBufferAccess & errorMask,const tcu::Texture1DArrayView & baseView,const float * texCoord,const ReferenceParams & sampleParams,const tcu::LookupPrecision & lookupPrec,const tcu::LodPrecision & lodPrec,qpWatchDog * watchDog)2164*35238bceSAndroid Build Coastguard Worker int computeTextureLookupDiff(const tcu::ConstPixelBufferAccess &result, const tcu::ConstPixelBufferAccess &reference,
2165*35238bceSAndroid Build Coastguard Worker                              const tcu::PixelBufferAccess &errorMask, const tcu::Texture1DArrayView &baseView,
2166*35238bceSAndroid Build Coastguard Worker                              const float *texCoord, const ReferenceParams &sampleParams,
2167*35238bceSAndroid Build Coastguard Worker                              const tcu::LookupPrecision &lookupPrec, const tcu::LodPrecision &lodPrec,
2168*35238bceSAndroid Build Coastguard Worker                              qpWatchDog *watchDog)
2169*35238bceSAndroid Build Coastguard Worker {
2170*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
2171*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
2172*35238bceSAndroid Build Coastguard Worker 
2173*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
2174*35238bceSAndroid Build Coastguard Worker     const tcu::Texture1DArrayView src = getEffectiveTextureView(baseView, srcLevelStorage, sampleParams.sampler);
2175*35238bceSAndroid Build Coastguard Worker 
2176*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[2 + 0], texCoord[4 + 0], texCoord[6 + 0]);
2177*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[2 + 1], texCoord[4 + 1], texCoord[6 + 1]);
2178*35238bceSAndroid Build Coastguard Worker 
2179*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight());
2180*35238bceSAndroid Build Coastguard Worker     const float dstW         = float(dstSize.x());
2181*35238bceSAndroid Build Coastguard Worker     const float dstH         = float(dstSize.y());
2182*35238bceSAndroid Build Coastguard Worker     const float srcSize      = float(src.getWidth()); // For lod computation, thus #layers is ignored.
2183*35238bceSAndroid Build Coastguard Worker 
2184*35238bceSAndroid Build Coastguard Worker     // Coordinates and lod per triangle.
2185*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
2186*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
2187*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triW[2] = {sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1)};
2188*35238bceSAndroid Build Coastguard Worker 
2189*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodBias((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);
2190*35238bceSAndroid Build Coastguard Worker 
2191*35238bceSAndroid Build Coastguard Worker     int numFailed = 0;
2192*35238bceSAndroid Build Coastguard Worker 
2193*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodOffsets[] = {
2194*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, 0),
2195*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, 0),
2196*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, -1),
2197*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, +1),
2198*35238bceSAndroid Build Coastguard Worker     };
2199*35238bceSAndroid Build Coastguard Worker 
2200*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask, tcu::RGBA::green().toVec());
2201*35238bceSAndroid Build Coastguard Worker 
2202*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < result.getHeight(); py++)
2203*35238bceSAndroid Build Coastguard Worker     {
2204*35238bceSAndroid Build Coastguard Worker         // Ugly hack, validation can take way too long at the moment.
2205*35238bceSAndroid Build Coastguard Worker         if (watchDog)
2206*35238bceSAndroid Build Coastguard Worker             qpWatchDog_touch(watchDog);
2207*35238bceSAndroid Build Coastguard Worker 
2208*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < result.getWidth(); px++)
2209*35238bceSAndroid Build Coastguard Worker         {
2210*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale;
2211*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale;
2212*35238bceSAndroid Build Coastguard Worker 
2213*35238bceSAndroid Build Coastguard Worker             // Try comparison to ideal reference first, and if that fails use slower verificator.
2214*35238bceSAndroid Build Coastguard Worker             if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold)))
2215*35238bceSAndroid Build Coastguard Worker             {
2216*35238bceSAndroid Build Coastguard Worker                 const float wx = (float)px + 0.5f;
2217*35238bceSAndroid Build Coastguard Worker                 const float wy = (float)py + 0.5f;
2218*35238bceSAndroid Build Coastguard Worker                 const float nx = wx / dstW;
2219*35238bceSAndroid Build Coastguard Worker                 const float ny = wy / dstH;
2220*35238bceSAndroid Build Coastguard Worker 
2221*35238bceSAndroid Build Coastguard Worker                 const int triNdx  = nx + ny >= 1.0f ? 1 : 0;
2222*35238bceSAndroid Build Coastguard Worker                 const float triWx = triNdx ? dstW - wx : wx;
2223*35238bceSAndroid Build Coastguard Worker                 const float triWy = triNdx ? dstH - wy : wy;
2224*35238bceSAndroid Build Coastguard Worker                 const float triNx = triNdx ? 1.0f - nx : nx;
2225*35238bceSAndroid Build Coastguard Worker                 const float triNy = triNdx ? 1.0f - ny : ny;
2226*35238bceSAndroid Build Coastguard Worker 
2227*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 coord(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
2228*35238bceSAndroid Build Coastguard Worker                                       projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy));
2229*35238bceSAndroid Build Coastguard Worker                 const float coordDx = triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy) * srcSize;
2230*35238bceSAndroid Build Coastguard Worker                 const float coordDy = triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx) * srcSize;
2231*35238bceSAndroid Build Coastguard Worker 
2232*35238bceSAndroid Build Coastguard Worker                 tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx, coordDy, lodPrec);
2233*35238bceSAndroid Build Coastguard Worker 
2234*35238bceSAndroid Build Coastguard Worker                 // Compute lod bounds across lodOffsets range.
2235*35238bceSAndroid Build Coastguard Worker                 for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
2236*35238bceSAndroid Build Coastguard Worker                 {
2237*35238bceSAndroid Build Coastguard Worker                     const float wxo = triWx + lodOffsets[lodOffsNdx].x();
2238*35238bceSAndroid Build Coastguard Worker                     const float wyo = triWy + lodOffsets[lodOffsNdx].y();
2239*35238bceSAndroid Build Coastguard Worker                     const float nxo = wxo / dstW;
2240*35238bceSAndroid Build Coastguard Worker                     const float nyo = wyo / dstH;
2241*35238bceSAndroid Build Coastguard Worker 
2242*35238bceSAndroid Build Coastguard Worker                     const float coordDxo = triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo) * srcSize;
2243*35238bceSAndroid Build Coastguard Worker                     const float coordDyo = triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo) * srcSize;
2244*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo, coordDyo, lodPrec);
2245*35238bceSAndroid Build Coastguard Worker 
2246*35238bceSAndroid Build Coastguard Worker                     lodBounds.x() = de::min(lodBounds.x(), lodO.x());
2247*35238bceSAndroid Build Coastguard Worker                     lodBounds.y() = de::max(lodBounds.y(), lodO.y());
2248*35238bceSAndroid Build Coastguard Worker                 }
2249*35238bceSAndroid Build Coastguard Worker 
2250*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 clampedLod = tcu::clampLodBounds(
2251*35238bceSAndroid Build Coastguard Worker                     lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
2252*35238bceSAndroid Build Coastguard Worker                 const bool isOk =
2253*35238bceSAndroid Build Coastguard Worker                     tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix);
2254*35238bceSAndroid Build Coastguard Worker 
2255*35238bceSAndroid Build Coastguard Worker                 if (!isOk)
2256*35238bceSAndroid Build Coastguard Worker                 {
2257*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
2258*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
2259*35238bceSAndroid Build Coastguard Worker                 }
2260*35238bceSAndroid Build Coastguard Worker             }
2261*35238bceSAndroid Build Coastguard Worker         }
2262*35238bceSAndroid Build Coastguard Worker     }
2263*35238bceSAndroid Build Coastguard Worker 
2264*35238bceSAndroid Build Coastguard Worker     return numFailed;
2265*35238bceSAndroid Build Coastguard Worker }
2266*35238bceSAndroid Build Coastguard Worker 
2267*35238bceSAndroid Build Coastguard Worker //! Verifies texture lookup results and returns number of failed pixels.
computeTextureLookupDiff(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & reference,const tcu::PixelBufferAccess & errorMask,const tcu::Texture2DArrayView & baseView,const float * texCoord,const ReferenceParams & sampleParams,const tcu::LookupPrecision & lookupPrec,const tcu::LodPrecision & lodPrec,qpWatchDog * watchDog)2268*35238bceSAndroid Build Coastguard Worker int computeTextureLookupDiff(const tcu::ConstPixelBufferAccess &result, const tcu::ConstPixelBufferAccess &reference,
2269*35238bceSAndroid Build Coastguard Worker                              const tcu::PixelBufferAccess &errorMask, const tcu::Texture2DArrayView &baseView,
2270*35238bceSAndroid Build Coastguard Worker                              const float *texCoord, const ReferenceParams &sampleParams,
2271*35238bceSAndroid Build Coastguard Worker                              const tcu::LookupPrecision &lookupPrec, const tcu::LodPrecision &lodPrec,
2272*35238bceSAndroid Build Coastguard Worker                              qpWatchDog *watchDog)
2273*35238bceSAndroid Build Coastguard Worker {
2274*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
2275*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
2276*35238bceSAndroid Build Coastguard Worker 
2277*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
2278*35238bceSAndroid Build Coastguard Worker     const tcu::Texture2DArrayView src = getEffectiveTextureView(baseView, srcLevelStorage, sampleParams.sampler);
2279*35238bceSAndroid Build Coastguard Worker 
2280*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]);
2281*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]);
2282*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 rq = tcu::Vec4(texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]);
2283*35238bceSAndroid Build Coastguard Worker 
2284*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight());
2285*35238bceSAndroid Build Coastguard Worker     const float dstW         = float(dstSize.x());
2286*35238bceSAndroid Build Coastguard Worker     const float dstH         = float(dstSize.y());
2287*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 srcSize =
2288*35238bceSAndroid Build Coastguard Worker         tcu::IVec2(src.getWidth(), src.getHeight()).asFloat(); // For lod computation, thus #layers is ignored.
2289*35238bceSAndroid Build Coastguard Worker 
2290*35238bceSAndroid Build Coastguard Worker     // Coordinates and lod per triangle.
2291*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
2292*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
2293*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triR[2] = {rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1)};
2294*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triW[2] = {sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1)};
2295*35238bceSAndroid Build Coastguard Worker 
2296*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodBias((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);
2297*35238bceSAndroid Build Coastguard Worker 
2298*35238bceSAndroid Build Coastguard Worker     int numFailed = 0;
2299*35238bceSAndroid Build Coastguard Worker 
2300*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodOffsets[] = {
2301*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, 0),
2302*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, 0),
2303*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, -1),
2304*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, +1),
2305*35238bceSAndroid Build Coastguard Worker     };
2306*35238bceSAndroid Build Coastguard Worker 
2307*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask, tcu::RGBA::green().toVec());
2308*35238bceSAndroid Build Coastguard Worker 
2309*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < result.getHeight(); py++)
2310*35238bceSAndroid Build Coastguard Worker     {
2311*35238bceSAndroid Build Coastguard Worker         // Ugly hack, validation can take way too long at the moment.
2312*35238bceSAndroid Build Coastguard Worker         if (watchDog)
2313*35238bceSAndroid Build Coastguard Worker             qpWatchDog_touch(watchDog);
2314*35238bceSAndroid Build Coastguard Worker 
2315*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < result.getWidth(); px++)
2316*35238bceSAndroid Build Coastguard Worker         {
2317*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale;
2318*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale;
2319*35238bceSAndroid Build Coastguard Worker 
2320*35238bceSAndroid Build Coastguard Worker             // Try comparison to ideal reference first, and if that fails use slower verificator.
2321*35238bceSAndroid Build Coastguard Worker             if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold)))
2322*35238bceSAndroid Build Coastguard Worker             {
2323*35238bceSAndroid Build Coastguard Worker                 const float wx = (float)px + 0.5f;
2324*35238bceSAndroid Build Coastguard Worker                 const float wy = (float)py + 0.5f;
2325*35238bceSAndroid Build Coastguard Worker                 const float nx = wx / dstW;
2326*35238bceSAndroid Build Coastguard Worker                 const float ny = wy / dstH;
2327*35238bceSAndroid Build Coastguard Worker 
2328*35238bceSAndroid Build Coastguard Worker                 const int triNdx  = nx + ny >= 1.0f ? 1 : 0;
2329*35238bceSAndroid Build Coastguard Worker                 const float triWx = triNdx ? dstW - wx : wx;
2330*35238bceSAndroid Build Coastguard Worker                 const float triWy = triNdx ? dstH - wy : wy;
2331*35238bceSAndroid Build Coastguard Worker                 const float triNx = triNdx ? 1.0f - nx : nx;
2332*35238bceSAndroid Build Coastguard Worker                 const float triNy = triNdx ? 1.0f - ny : ny;
2333*35238bceSAndroid Build Coastguard Worker 
2334*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec3 coord(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
2335*35238bceSAndroid Build Coastguard Worker                                       projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
2336*35238bceSAndroid Build Coastguard Worker                                       projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy));
2337*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 coordDx = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
2338*35238bceSAndroid Build Coastguard Worker                                                     triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) *
2339*35238bceSAndroid Build Coastguard Worker                                           srcSize;
2340*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 coordDy = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
2341*35238bceSAndroid Build Coastguard Worker                                                     triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) *
2342*35238bceSAndroid Build Coastguard Worker                                           srcSize;
2343*35238bceSAndroid Build Coastguard Worker 
2344*35238bceSAndroid Build Coastguard Worker                 tcu::Vec2 lodBounds =
2345*35238bceSAndroid Build Coastguard Worker                     tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec);
2346*35238bceSAndroid Build Coastguard Worker 
2347*35238bceSAndroid Build Coastguard Worker                 // Compute lod bounds across lodOffsets range.
2348*35238bceSAndroid Build Coastguard Worker                 for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
2349*35238bceSAndroid Build Coastguard Worker                 {
2350*35238bceSAndroid Build Coastguard Worker                     const float wxo = triWx + lodOffsets[lodOffsNdx].x();
2351*35238bceSAndroid Build Coastguard Worker                     const float wyo = triWy + lodOffsets[lodOffsNdx].y();
2352*35238bceSAndroid Build Coastguard Worker                     const float nxo = wxo / dstW;
2353*35238bceSAndroid Build Coastguard Worker                     const float nyo = wyo / dstH;
2354*35238bceSAndroid Build Coastguard Worker 
2355*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 coordDxo = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
2356*35238bceSAndroid Build Coastguard Worker                                                          triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) *
2357*35238bceSAndroid Build Coastguard Worker                                                srcSize;
2358*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 coordDyo = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
2359*35238bceSAndroid Build Coastguard Worker                                                          triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) *
2360*35238bceSAndroid Build Coastguard Worker                                                srcSize;
2361*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(),
2362*35238bceSAndroid Build Coastguard Worker                                                                               coordDyo.y(), lodPrec);
2363*35238bceSAndroid Build Coastguard Worker 
2364*35238bceSAndroid Build Coastguard Worker                     lodBounds.x() = de::min(lodBounds.x(), lodO.x());
2365*35238bceSAndroid Build Coastguard Worker                     lodBounds.y() = de::max(lodBounds.y(), lodO.y());
2366*35238bceSAndroid Build Coastguard Worker                 }
2367*35238bceSAndroid Build Coastguard Worker 
2368*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 clampedLod = tcu::clampLodBounds(
2369*35238bceSAndroid Build Coastguard Worker                     lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
2370*35238bceSAndroid Build Coastguard Worker                 const bool isOk =
2371*35238bceSAndroid Build Coastguard Worker                     tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coord, clampedLod, resPix);
2372*35238bceSAndroid Build Coastguard Worker 
2373*35238bceSAndroid Build Coastguard Worker                 if (!isOk)
2374*35238bceSAndroid Build Coastguard Worker                 {
2375*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
2376*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
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     return numFailed;
2383*35238bceSAndroid Build Coastguard Worker }
2384*35238bceSAndroid Build Coastguard Worker 
verifyTextureResult(tcu::TestContext & testCtx,const tcu::ConstPixelBufferAccess & result,const tcu::Texture1DArrayView & src,const float * texCoord,const ReferenceParams & sampleParams,const tcu::LookupPrecision & lookupPrec,const tcu::LodPrecision & lodPrec,const tcu::PixelFormat & pixelFormat)2385*35238bceSAndroid Build Coastguard Worker bool verifyTextureResult(tcu::TestContext &testCtx, const tcu::ConstPixelBufferAccess &result,
2386*35238bceSAndroid Build Coastguard Worker                          const tcu::Texture1DArrayView &src, const float *texCoord, const ReferenceParams &sampleParams,
2387*35238bceSAndroid Build Coastguard Worker                          const tcu::LookupPrecision &lookupPrec, const tcu::LodPrecision &lodPrec,
2388*35238bceSAndroid Build Coastguard Worker                          const tcu::PixelFormat &pixelFormat)
2389*35238bceSAndroid Build Coastguard Worker {
2390*35238bceSAndroid Build Coastguard Worker     tcu::TestLog &log = testCtx.getLog();
2391*35238bceSAndroid Build Coastguard Worker     tcu::Surface reference(result.getWidth(), result.getHeight());
2392*35238bceSAndroid Build Coastguard Worker     tcu::Surface errorMask(result.getWidth(), result.getHeight());
2393*35238bceSAndroid Build Coastguard Worker     int numFailedPixels;
2394*35238bceSAndroid Build Coastguard Worker 
2395*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask);
2396*35238bceSAndroid Build Coastguard Worker 
2397*35238bceSAndroid Build Coastguard Worker     sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
2398*35238bceSAndroid Build Coastguard Worker     numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord,
2399*35238bceSAndroid Build Coastguard Worker                                                sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog());
2400*35238bceSAndroid Build Coastguard Worker 
2401*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
2402*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels
2403*35238bceSAndroid Build Coastguard Worker             << " invalid pixels!" << tcu::TestLog::EndMessage;
2404*35238bceSAndroid Build Coastguard Worker 
2405*35238bceSAndroid Build Coastguard Worker     log << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
2406*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::Image("Rendered", "Rendered image", result);
2407*35238bceSAndroid Build Coastguard Worker 
2408*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
2409*35238bceSAndroid Build Coastguard Worker     {
2410*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
2411*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
2412*35238bceSAndroid Build Coastguard Worker     }
2413*35238bceSAndroid Build Coastguard Worker 
2414*35238bceSAndroid Build Coastguard Worker     log << tcu::TestLog::EndImageSet;
2415*35238bceSAndroid Build Coastguard Worker 
2416*35238bceSAndroid Build Coastguard Worker     return numFailedPixels == 0;
2417*35238bceSAndroid Build Coastguard Worker }
2418*35238bceSAndroid Build Coastguard Worker 
verifyTextureResult(tcu::TestContext & testCtx,const tcu::ConstPixelBufferAccess & result,const tcu::Texture2DArrayView & src,const float * texCoord,const ReferenceParams & sampleParams,const tcu::LookupPrecision & lookupPrec,const tcu::LodPrecision & lodPrec,const tcu::PixelFormat & pixelFormat)2419*35238bceSAndroid Build Coastguard Worker bool verifyTextureResult(tcu::TestContext &testCtx, const tcu::ConstPixelBufferAccess &result,
2420*35238bceSAndroid Build Coastguard Worker                          const tcu::Texture2DArrayView &src, const float *texCoord, const ReferenceParams &sampleParams,
2421*35238bceSAndroid Build Coastguard Worker                          const tcu::LookupPrecision &lookupPrec, const tcu::LodPrecision &lodPrec,
2422*35238bceSAndroid Build Coastguard Worker                          const tcu::PixelFormat &pixelFormat)
2423*35238bceSAndroid Build Coastguard Worker {
2424*35238bceSAndroid Build Coastguard Worker     tcu::TestLog &log = testCtx.getLog();
2425*35238bceSAndroid Build Coastguard Worker     tcu::Surface reference(result.getWidth(), result.getHeight());
2426*35238bceSAndroid Build Coastguard Worker     tcu::Surface errorMask(result.getWidth(), result.getHeight());
2427*35238bceSAndroid Build Coastguard Worker     int numFailedPixels;
2428*35238bceSAndroid Build Coastguard Worker 
2429*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask);
2430*35238bceSAndroid Build Coastguard Worker 
2431*35238bceSAndroid Build Coastguard Worker     sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
2432*35238bceSAndroid Build Coastguard Worker     numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord,
2433*35238bceSAndroid Build Coastguard Worker                                                sampleParams, lookupPrec, lodPrec, testCtx.getWatchDog());
2434*35238bceSAndroid Build Coastguard Worker 
2435*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
2436*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels
2437*35238bceSAndroid Build Coastguard Worker             << " invalid pixels!" << tcu::TestLog::EndMessage;
2438*35238bceSAndroid Build Coastguard Worker 
2439*35238bceSAndroid Build Coastguard Worker     log << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
2440*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::Image("Rendered", "Rendered image", result);
2441*35238bceSAndroid Build Coastguard Worker 
2442*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
2443*35238bceSAndroid Build Coastguard Worker     {
2444*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
2445*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
2446*35238bceSAndroid Build Coastguard Worker     }
2447*35238bceSAndroid Build Coastguard Worker 
2448*35238bceSAndroid Build Coastguard Worker     log << tcu::TestLog::EndImageSet;
2449*35238bceSAndroid Build Coastguard Worker 
2450*35238bceSAndroid Build Coastguard Worker     return numFailedPixels == 0;
2451*35238bceSAndroid Build Coastguard Worker }
2452*35238bceSAndroid Build Coastguard Worker 
2453*35238bceSAndroid Build Coastguard Worker //! Verifies texture lookup results and returns number of failed pixels.
computeTextureLookupDiff(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & reference,const tcu::PixelBufferAccess & errorMask,const tcu::TextureCubeArrayView & baseView,const float * texCoord,const ReferenceParams & sampleParams,const tcu::LookupPrecision & lookupPrec,const tcu::IVec4 & coordBits,const tcu::LodPrecision & lodPrec,qpWatchDog * watchDog)2454*35238bceSAndroid Build Coastguard Worker int computeTextureLookupDiff(const tcu::ConstPixelBufferAccess &result, const tcu::ConstPixelBufferAccess &reference,
2455*35238bceSAndroid Build Coastguard Worker                              const tcu::PixelBufferAccess &errorMask, const tcu::TextureCubeArrayView &baseView,
2456*35238bceSAndroid Build Coastguard Worker                              const float *texCoord, const ReferenceParams &sampleParams,
2457*35238bceSAndroid Build Coastguard Worker                              const tcu::LookupPrecision &lookupPrec, const tcu::IVec4 &coordBits,
2458*35238bceSAndroid Build Coastguard Worker                              const tcu::LodPrecision &lodPrec, qpWatchDog *watchDog)
2459*35238bceSAndroid Build Coastguard Worker {
2460*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
2461*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
2462*35238bceSAndroid Build Coastguard Worker 
2463*35238bceSAndroid Build Coastguard Worker     std::vector<tcu::ConstPixelBufferAccess> srcLevelStorage;
2464*35238bceSAndroid Build Coastguard Worker     tcu::ImageViewMinLodParams minLodParams = {
2465*35238bceSAndroid Build Coastguard Worker         sampleParams.baseLevel, // int baseLevel;
2466*35238bceSAndroid Build Coastguard Worker         {
2467*35238bceSAndroid Build Coastguard Worker             sampleParams.imageViewMinLod,     // float minLod;
2468*35238bceSAndroid Build Coastguard Worker             sampleParams.imageViewMinLodMode, // ImageViewMinLodMode
2469*35238bceSAndroid Build Coastguard Worker         },
2470*35238bceSAndroid Build Coastguard Worker         sampleParams.samplerType == SAMPLERTYPE_FETCH_FLOAT // bool intTexCoord;
2471*35238bceSAndroid Build Coastguard Worker     };
2472*35238bceSAndroid Build Coastguard Worker 
2473*35238bceSAndroid Build Coastguard Worker     const tcu::TextureCubeArrayView src =
2474*35238bceSAndroid Build Coastguard Worker         getEffectiveTextureView(getSubView(baseView, sampleParams.baseLevel, sampleParams.maxLevel,
2475*35238bceSAndroid Build Coastguard Worker                                            sampleParams.imageViewMinLod != 0.0f ? &minLodParams : DE_NULL),
2476*35238bceSAndroid Build Coastguard Worker                                 srcLevelStorage, sampleParams.sampler);
2477*35238bceSAndroid Build Coastguard Worker 
2478*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[4 + 0], texCoord[8 + 0], texCoord[12 + 0]);
2479*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[4 + 1], texCoord[8 + 1], texCoord[12 + 1]);
2480*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 rq = tcu::Vec4(texCoord[0 + 2], texCoord[4 + 2], texCoord[8 + 2], texCoord[12 + 2]);
2481*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 qq = tcu::Vec4(texCoord[0 + 3], texCoord[4 + 3], texCoord[8 + 3], texCoord[12 + 3]);
2482*35238bceSAndroid Build Coastguard Worker 
2483*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight());
2484*35238bceSAndroid Build Coastguard Worker     const float dstW         = float(dstSize.x());
2485*35238bceSAndroid Build Coastguard Worker     const float dstH         = float(dstSize.y());
2486*35238bceSAndroid Build Coastguard Worker     const int srcSize        = src.getSize();
2487*35238bceSAndroid Build Coastguard Worker 
2488*35238bceSAndroid Build Coastguard Worker     // Coordinates per triangle.
2489*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
2490*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
2491*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triR[2] = {rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1)};
2492*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triQ[2] = {qq.swizzle(0, 1, 2), qq.swizzle(3, 2, 1)};
2493*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triW[2] = {sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1)};
2494*35238bceSAndroid Build Coastguard Worker 
2495*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodBias((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);
2496*35238bceSAndroid Build Coastguard Worker 
2497*35238bceSAndroid Build Coastguard Worker     const float posEps = 1.0f / float((1 << 4) + 1); // ES3 requires at least 4 subpixel bits.
2498*35238bceSAndroid Build Coastguard Worker 
2499*35238bceSAndroid Build Coastguard Worker     int numFailed = 0;
2500*35238bceSAndroid Build Coastguard Worker 
2501*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodOffsets[] = {
2502*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, 0),
2503*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, 0),
2504*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, -1),
2505*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, +1),
2506*35238bceSAndroid Build Coastguard Worker 
2507*35238bceSAndroid Build Coastguard Worker         // \note Not strictly allowed by spec, but implementations do this in practice.
2508*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, -1),
2509*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, +1),
2510*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, -1),
2511*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, +1),
2512*35238bceSAndroid Build Coastguard Worker     };
2513*35238bceSAndroid Build Coastguard Worker 
2514*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask, tcu::RGBA::green().toVec());
2515*35238bceSAndroid Build Coastguard Worker 
2516*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < result.getHeight(); py++)
2517*35238bceSAndroid Build Coastguard Worker     {
2518*35238bceSAndroid Build Coastguard Worker         // Ugly hack, validation can take way too long at the moment.
2519*35238bceSAndroid Build Coastguard Worker         if (watchDog)
2520*35238bceSAndroid Build Coastguard Worker             qpWatchDog_touch(watchDog);
2521*35238bceSAndroid Build Coastguard Worker 
2522*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < result.getWidth(); px++)
2523*35238bceSAndroid Build Coastguard Worker         {
2524*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 resPix = (result.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale;
2525*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 refPix = (reference.getPixel(px, py) - sampleParams.colorBias) / sampleParams.colorScale;
2526*35238bceSAndroid Build Coastguard Worker 
2527*35238bceSAndroid Build Coastguard Worker             // Try comparison to ideal reference first, and if that fails use slower verificator.
2528*35238bceSAndroid Build Coastguard Worker             if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(resPix - refPix), lookupPrec.colorThreshold)))
2529*35238bceSAndroid Build Coastguard Worker             {
2530*35238bceSAndroid Build Coastguard Worker                 const float wx = (float)px + 0.5f;
2531*35238bceSAndroid Build Coastguard Worker                 const float wy = (float)py + 0.5f;
2532*35238bceSAndroid Build Coastguard Worker                 const float nx = wx / dstW;
2533*35238bceSAndroid Build Coastguard Worker                 const float ny = wy / dstH;
2534*35238bceSAndroid Build Coastguard Worker 
2535*35238bceSAndroid Build Coastguard Worker                 const bool tri0 = nx + ny - posEps <= 1.0f;
2536*35238bceSAndroid Build Coastguard Worker                 const bool tri1 = nx + ny + posEps >= 1.0f;
2537*35238bceSAndroid Build Coastguard Worker 
2538*35238bceSAndroid Build Coastguard Worker                 bool isOk = false;
2539*35238bceSAndroid Build Coastguard Worker 
2540*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(tri0 || tri1);
2541*35238bceSAndroid Build Coastguard Worker 
2542*35238bceSAndroid Build Coastguard Worker                 // Pixel can belong to either of the triangles if it lies close enough to the edge.
2543*35238bceSAndroid Build Coastguard Worker                 for (int triNdx = (tri0 ? 0 : 1); triNdx <= (tri1 ? 1 : 0); triNdx++)
2544*35238bceSAndroid Build Coastguard Worker                 {
2545*35238bceSAndroid Build Coastguard Worker                     const float triWx = triNdx ? dstW - wx : wx;
2546*35238bceSAndroid Build Coastguard Worker                     const float triWy = triNdx ? dstH - wy : wy;
2547*35238bceSAndroid Build Coastguard Worker                     const float triNx = triNdx ? 1.0f - nx : nx;
2548*35238bceSAndroid Build Coastguard Worker                     const float triNy = triNdx ? 1.0f - ny : ny;
2549*35238bceSAndroid Build Coastguard Worker 
2550*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec4 coord(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
2551*35238bceSAndroid Build Coastguard Worker                                           projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
2552*35238bceSAndroid Build Coastguard Worker                                           projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy),
2553*35238bceSAndroid Build Coastguard Worker                                           projectedTriInterpolate(triQ[triNdx], triW[triNdx], triNx, triNy));
2554*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec3 coordDx(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
2555*35238bceSAndroid Build Coastguard Worker                                             triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
2556*35238bceSAndroid Build Coastguard Worker                                             triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy));
2557*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec3 coordDy(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
2558*35238bceSAndroid Build Coastguard Worker                                             triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
2559*35238bceSAndroid Build Coastguard Worker                                             triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx));
2560*35238bceSAndroid Build Coastguard Worker 
2561*35238bceSAndroid Build Coastguard Worker                     tcu::Vec2 lodBounds =
2562*35238bceSAndroid Build Coastguard Worker                         tcu::computeCubeLodBoundsFromDerivates(coord.toWidth<3>(), coordDx, coordDy, srcSize, lodPrec);
2563*35238bceSAndroid Build Coastguard Worker 
2564*35238bceSAndroid Build Coastguard Worker                     // Compute lod bounds across lodOffsets range.
2565*35238bceSAndroid Build Coastguard Worker                     for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
2566*35238bceSAndroid Build Coastguard Worker                     {
2567*35238bceSAndroid Build Coastguard Worker                         const float wxo = triWx + lodOffsets[lodOffsNdx].x();
2568*35238bceSAndroid Build Coastguard Worker                         const float wyo = triWy + lodOffsets[lodOffsNdx].y();
2569*35238bceSAndroid Build Coastguard Worker                         const float nxo = wxo / dstW;
2570*35238bceSAndroid Build Coastguard Worker                         const float nyo = wyo / dstH;
2571*35238bceSAndroid Build Coastguard Worker 
2572*35238bceSAndroid Build Coastguard Worker                         const tcu::Vec3 coordO(projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo),
2573*35238bceSAndroid Build Coastguard Worker                                                projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo),
2574*35238bceSAndroid Build Coastguard Worker                                                projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo));
2575*35238bceSAndroid Build Coastguard Worker                         const tcu::Vec3 coordDxo(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
2576*35238bceSAndroid Build Coastguard Worker                                                  triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo),
2577*35238bceSAndroid Build Coastguard Worker                                                  triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo));
2578*35238bceSAndroid Build Coastguard Worker                         const tcu::Vec3 coordDyo(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
2579*35238bceSAndroid Build Coastguard Worker                                                  triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo),
2580*35238bceSAndroid Build Coastguard Worker                                                  triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo));
2581*35238bceSAndroid Build Coastguard Worker                         const tcu::Vec2 lodO =
2582*35238bceSAndroid Build Coastguard Worker                             tcu::computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec);
2583*35238bceSAndroid Build Coastguard Worker 
2584*35238bceSAndroid Build Coastguard Worker                         lodBounds.x() = de::min(lodBounds.x(), lodO.x());
2585*35238bceSAndroid Build Coastguard Worker                         lodBounds.y() = de::max(lodBounds.y(), lodO.y());
2586*35238bceSAndroid Build Coastguard Worker                     }
2587*35238bceSAndroid Build Coastguard Worker 
2588*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 clampedLod = tcu::clampLodBounds(
2589*35238bceSAndroid Build Coastguard Worker                         lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
2590*35238bceSAndroid Build Coastguard Worker 
2591*35238bceSAndroid Build Coastguard Worker                     if (tcu::isLookupResultValid(src, sampleParams.sampler, lookupPrec, coordBits, coord, clampedLod,
2592*35238bceSAndroid Build Coastguard Worker                                                  resPix))
2593*35238bceSAndroid Build Coastguard Worker                     {
2594*35238bceSAndroid Build Coastguard Worker                         isOk = true;
2595*35238bceSAndroid Build Coastguard Worker                         break;
2596*35238bceSAndroid Build Coastguard Worker                     }
2597*35238bceSAndroid Build Coastguard Worker                 }
2598*35238bceSAndroid Build Coastguard Worker 
2599*35238bceSAndroid Build Coastguard Worker                 if (!isOk)
2600*35238bceSAndroid Build Coastguard Worker                 {
2601*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
2602*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
2603*35238bceSAndroid Build Coastguard Worker                 }
2604*35238bceSAndroid Build Coastguard Worker             }
2605*35238bceSAndroid Build Coastguard Worker         }
2606*35238bceSAndroid Build Coastguard Worker     }
2607*35238bceSAndroid Build Coastguard Worker 
2608*35238bceSAndroid Build Coastguard Worker     return numFailed;
2609*35238bceSAndroid Build Coastguard Worker }
2610*35238bceSAndroid Build Coastguard Worker 
verifyTextureResult(tcu::TestContext & testCtx,const tcu::ConstPixelBufferAccess & result,const tcu::TextureCubeArrayView & src,const float * texCoord,const ReferenceParams & sampleParams,const tcu::LookupPrecision & lookupPrec,const tcu::IVec4 & coordBits,const tcu::LodPrecision & lodPrec,const tcu::PixelFormat & pixelFormat)2611*35238bceSAndroid Build Coastguard Worker bool verifyTextureResult(tcu::TestContext &testCtx, const tcu::ConstPixelBufferAccess &result,
2612*35238bceSAndroid Build Coastguard Worker                          const tcu::TextureCubeArrayView &src, const float *texCoord,
2613*35238bceSAndroid Build Coastguard Worker                          const ReferenceParams &sampleParams, const tcu::LookupPrecision &lookupPrec,
2614*35238bceSAndroid Build Coastguard Worker                          const tcu::IVec4 &coordBits, const tcu::LodPrecision &lodPrec,
2615*35238bceSAndroid Build Coastguard Worker                          const tcu::PixelFormat &pixelFormat)
2616*35238bceSAndroid Build Coastguard Worker {
2617*35238bceSAndroid Build Coastguard Worker     tcu::TestLog &log = testCtx.getLog();
2618*35238bceSAndroid Build Coastguard Worker     tcu::Surface reference(result.getWidth(), result.getHeight());
2619*35238bceSAndroid Build Coastguard Worker     tcu::Surface errorMask(result.getWidth(), result.getHeight());
2620*35238bceSAndroid Build Coastguard Worker     int numFailedPixels;
2621*35238bceSAndroid Build Coastguard Worker 
2622*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(getCompareMask(pixelFormat) == lookupPrec.colorMask);
2623*35238bceSAndroid Build Coastguard Worker 
2624*35238bceSAndroid Build Coastguard Worker     sampleTexture(tcu::SurfaceAccess(reference, pixelFormat), src, texCoord, sampleParams);
2625*35238bceSAndroid Build Coastguard Worker     numFailedPixels = computeTextureLookupDiff(result, reference.getAccess(), errorMask.getAccess(), src, texCoord,
2626*35238bceSAndroid Build Coastguard Worker                                                sampleParams, lookupPrec, coordBits, lodPrec, testCtx.getWatchDog());
2627*35238bceSAndroid Build Coastguard Worker 
2628*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
2629*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Message << "ERROR: Result verification failed, got " << numFailedPixels
2630*35238bceSAndroid Build Coastguard Worker             << " invalid pixels!" << tcu::TestLog::EndMessage;
2631*35238bceSAndroid Build Coastguard Worker 
2632*35238bceSAndroid Build Coastguard Worker     log << tcu::TestLog::ImageSet("VerifyResult", "Verification result")
2633*35238bceSAndroid Build Coastguard Worker         << tcu::TestLog::Image("Rendered", "Rendered image", result);
2634*35238bceSAndroid Build Coastguard Worker 
2635*35238bceSAndroid Build Coastguard Worker     if (numFailedPixels > 0)
2636*35238bceSAndroid Build Coastguard Worker     {
2637*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::Image("Reference", "Ideal reference image", reference)
2638*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
2639*35238bceSAndroid Build Coastguard Worker     }
2640*35238bceSAndroid Build Coastguard Worker 
2641*35238bceSAndroid Build Coastguard Worker     log << tcu::TestLog::EndImageSet;
2642*35238bceSAndroid Build Coastguard Worker 
2643*35238bceSAndroid Build Coastguard Worker     return numFailedPixels == 0;
2644*35238bceSAndroid Build Coastguard Worker }
2645*35238bceSAndroid Build Coastguard Worker 
2646*35238bceSAndroid Build Coastguard Worker // Shadow lookup verification
2647*35238bceSAndroid Build Coastguard Worker 
computeTextureCompareDiff(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & reference,const tcu::PixelBufferAccess & errorMask,const tcu::Texture2DView & src,const float * texCoord,const ReferenceParams & sampleParams,const tcu::TexComparePrecision & comparePrec,const tcu::LodPrecision & lodPrec,const tcu::Vec3 & nonShadowThreshold)2648*35238bceSAndroid Build Coastguard Worker int computeTextureCompareDiff(const tcu::ConstPixelBufferAccess &result, const tcu::ConstPixelBufferAccess &reference,
2649*35238bceSAndroid Build Coastguard Worker                               const tcu::PixelBufferAccess &errorMask, const tcu::Texture2DView &src,
2650*35238bceSAndroid Build Coastguard Worker                               const float *texCoord, const ReferenceParams &sampleParams,
2651*35238bceSAndroid Build Coastguard Worker                               const tcu::TexComparePrecision &comparePrec, const tcu::LodPrecision &lodPrec,
2652*35238bceSAndroid Build Coastguard Worker                               const tcu::Vec3 &nonShadowThreshold)
2653*35238bceSAndroid Build Coastguard Worker {
2654*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
2655*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
2656*35238bceSAndroid Build Coastguard Worker 
2657*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[2 + 0], texCoord[4 + 0], texCoord[6 + 0]);
2658*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[2 + 1], texCoord[4 + 1], texCoord[6 + 1]);
2659*35238bceSAndroid Build Coastguard Worker 
2660*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight());
2661*35238bceSAndroid Build Coastguard Worker     const float dstW         = float(dstSize.x());
2662*35238bceSAndroid Build Coastguard Worker     const float dstH         = float(dstSize.y());
2663*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 srcSize = tcu::IVec2(src.getWidth(), src.getHeight());
2664*35238bceSAndroid Build Coastguard Worker 
2665*35238bceSAndroid Build Coastguard Worker     // Coordinates and lod per triangle.
2666*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
2667*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
2668*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triW[2] = {sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1)};
2669*35238bceSAndroid Build Coastguard Worker 
2670*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodBias((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);
2671*35238bceSAndroid Build Coastguard Worker 
2672*35238bceSAndroid Build Coastguard Worker     const float minLod = (sampleParams.imageViewMinLod != 0.0f) ?
2673*35238bceSAndroid Build Coastguard Worker                              de::max(deFloatFloor(sampleParams.imageViewMinLod), sampleParams.minLod) :
2674*35238bceSAndroid Build Coastguard Worker                              sampleParams.minLod;
2675*35238bceSAndroid Build Coastguard Worker 
2676*35238bceSAndroid Build Coastguard Worker     int numFailed = 0;
2677*35238bceSAndroid Build Coastguard Worker 
2678*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodOffsets[] = {
2679*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, 0),
2680*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, 0),
2681*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, -1),
2682*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, +1),
2683*35238bceSAndroid Build Coastguard Worker     };
2684*35238bceSAndroid Build Coastguard Worker 
2685*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask, tcu::RGBA::green().toVec());
2686*35238bceSAndroid Build Coastguard Worker 
2687*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < result.getHeight(); py++)
2688*35238bceSAndroid Build Coastguard Worker     {
2689*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < result.getWidth(); px++)
2690*35238bceSAndroid Build Coastguard Worker         {
2691*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 resPix = result.getPixel(px, py);
2692*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 refPix = reference.getPixel(px, py);
2693*35238bceSAndroid Build Coastguard Worker 
2694*35238bceSAndroid Build Coastguard Worker             // Other channels should trivially match to reference.
2695*35238bceSAndroid Build Coastguard Worker             if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1, 2, 3) - resPix.swizzle(1, 2, 3)),
2696*35238bceSAndroid Build Coastguard Worker                                                  nonShadowThreshold)))
2697*35238bceSAndroid Build Coastguard Worker             {
2698*35238bceSAndroid Build Coastguard Worker                 errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
2699*35238bceSAndroid Build Coastguard Worker                 numFailed += 1;
2700*35238bceSAndroid Build Coastguard Worker                 continue;
2701*35238bceSAndroid Build Coastguard Worker             }
2702*35238bceSAndroid Build Coastguard Worker 
2703*35238bceSAndroid Build Coastguard Worker             // Reference result is known to be a valid result, we can
2704*35238bceSAndroid Build Coastguard Worker             // skip verification if thes results are equal
2705*35238bceSAndroid Build Coastguard Worker             if (resPix.x() != refPix.x())
2706*35238bceSAndroid Build Coastguard Worker             {
2707*35238bceSAndroid Build Coastguard Worker                 const float wx = (float)px + 0.5f;
2708*35238bceSAndroid Build Coastguard Worker                 const float wy = (float)py + 0.5f;
2709*35238bceSAndroid Build Coastguard Worker                 const float nx = wx / dstW;
2710*35238bceSAndroid Build Coastguard Worker                 const float ny = wy / dstH;
2711*35238bceSAndroid Build Coastguard Worker 
2712*35238bceSAndroid Build Coastguard Worker                 const int triNdx  = nx + ny >= 1.0f ? 1 : 0;
2713*35238bceSAndroid Build Coastguard Worker                 const float triWx = triNdx ? dstW - wx : wx;
2714*35238bceSAndroid Build Coastguard Worker                 const float triWy = triNdx ? dstH - wy : wy;
2715*35238bceSAndroid Build Coastguard Worker                 const float triNx = triNdx ? 1.0f - nx : nx;
2716*35238bceSAndroid Build Coastguard Worker                 const float triNy = triNdx ? 1.0f - ny : ny;
2717*35238bceSAndroid Build Coastguard Worker 
2718*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 coord(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
2719*35238bceSAndroid Build Coastguard Worker                                       projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy));
2720*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 coordDx = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
2721*35238bceSAndroid Build Coastguard Worker                                                     triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) *
2722*35238bceSAndroid Build Coastguard Worker                                           srcSize.asFloat();
2723*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 coordDy = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
2724*35238bceSAndroid Build Coastguard Worker                                                     triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) *
2725*35238bceSAndroid Build Coastguard Worker                                           srcSize.asFloat();
2726*35238bceSAndroid Build Coastguard Worker 
2727*35238bceSAndroid Build Coastguard Worker                 tcu::Vec2 lodBounds =
2728*35238bceSAndroid Build Coastguard Worker                     tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec);
2729*35238bceSAndroid Build Coastguard Worker 
2730*35238bceSAndroid Build Coastguard Worker                 // Compute lod bounds across lodOffsets range.
2731*35238bceSAndroid Build Coastguard Worker                 for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
2732*35238bceSAndroid Build Coastguard Worker                 {
2733*35238bceSAndroid Build Coastguard Worker                     const float wxo = triWx + lodOffsets[lodOffsNdx].x();
2734*35238bceSAndroid Build Coastguard Worker                     const float wyo = triWy + lodOffsets[lodOffsNdx].y();
2735*35238bceSAndroid Build Coastguard Worker                     const float nxo = wxo / dstW;
2736*35238bceSAndroid Build Coastguard Worker                     const float nyo = wyo / dstH;
2737*35238bceSAndroid Build Coastguard Worker 
2738*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 coordDxo = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
2739*35238bceSAndroid Build Coastguard Worker                                                          triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) *
2740*35238bceSAndroid Build Coastguard Worker                                                srcSize.asFloat();
2741*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 coordDyo = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
2742*35238bceSAndroid Build Coastguard Worker                                                          triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) *
2743*35238bceSAndroid Build Coastguard Worker                                                srcSize.asFloat();
2744*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(),
2745*35238bceSAndroid Build Coastguard Worker                                                                               coordDyo.y(), lodPrec);
2746*35238bceSAndroid Build Coastguard Worker 
2747*35238bceSAndroid Build Coastguard Worker                     lodBounds.x() = de::min(lodBounds.x(), lodO.x());
2748*35238bceSAndroid Build Coastguard Worker                     lodBounds.y() = de::max(lodBounds.y(), lodO.y());
2749*35238bceSAndroid Build Coastguard Worker                 }
2750*35238bceSAndroid Build Coastguard Worker 
2751*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 clampedLod =
2752*35238bceSAndroid Build Coastguard Worker                     tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(minLod, sampleParams.maxLod), lodPrec);
2753*35238bceSAndroid Build Coastguard Worker                 const bool isOk = tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord,
2754*35238bceSAndroid Build Coastguard Worker                                                                clampedLod, sampleParams.ref, resPix.x());
2755*35238bceSAndroid Build Coastguard Worker 
2756*35238bceSAndroid Build Coastguard Worker                 if (!isOk)
2757*35238bceSAndroid Build Coastguard Worker                 {
2758*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
2759*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
2760*35238bceSAndroid Build Coastguard Worker                 }
2761*35238bceSAndroid Build Coastguard Worker             }
2762*35238bceSAndroid Build Coastguard Worker         }
2763*35238bceSAndroid Build Coastguard Worker     }
2764*35238bceSAndroid Build Coastguard Worker 
2765*35238bceSAndroid Build Coastguard Worker     return numFailed;
2766*35238bceSAndroid Build Coastguard Worker }
2767*35238bceSAndroid Build Coastguard Worker 
computeTextureCompareDiff(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & reference,const tcu::PixelBufferAccess & errorMask,const tcu::TextureCubeView & src,const float * texCoord,const ReferenceParams & sampleParams,const tcu::TexComparePrecision & comparePrec,const tcu::LodPrecision & lodPrec,const tcu::Vec3 & nonShadowThreshold)2768*35238bceSAndroid Build Coastguard Worker int computeTextureCompareDiff(const tcu::ConstPixelBufferAccess &result, const tcu::ConstPixelBufferAccess &reference,
2769*35238bceSAndroid Build Coastguard Worker                               const tcu::PixelBufferAccess &errorMask, const tcu::TextureCubeView &src,
2770*35238bceSAndroid Build Coastguard Worker                               const float *texCoord, const ReferenceParams &sampleParams,
2771*35238bceSAndroid Build Coastguard Worker                               const tcu::TexComparePrecision &comparePrec, const tcu::LodPrecision &lodPrec,
2772*35238bceSAndroid Build Coastguard Worker                               const tcu::Vec3 &nonShadowThreshold)
2773*35238bceSAndroid Build Coastguard Worker {
2774*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
2775*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
2776*35238bceSAndroid Build Coastguard Worker 
2777*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]);
2778*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]);
2779*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 rq = tcu::Vec4(texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]);
2780*35238bceSAndroid Build Coastguard Worker 
2781*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight());
2782*35238bceSAndroid Build Coastguard Worker     const float dstW         = float(dstSize.x());
2783*35238bceSAndroid Build Coastguard Worker     const float dstH         = float(dstSize.y());
2784*35238bceSAndroid Build Coastguard Worker     const int srcSize        = src.getSize();
2785*35238bceSAndroid Build Coastguard Worker 
2786*35238bceSAndroid Build Coastguard Worker     // Coordinates per triangle.
2787*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
2788*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
2789*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triR[2] = {rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1)};
2790*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triW[2] = {sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1)};
2791*35238bceSAndroid Build Coastguard Worker 
2792*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodBias((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);
2793*35238bceSAndroid Build Coastguard Worker 
2794*35238bceSAndroid Build Coastguard Worker     const float minLod = (sampleParams.imageViewMinLod != 0.0f) ?
2795*35238bceSAndroid Build Coastguard Worker                              de::max(deFloatFloor(sampleParams.imageViewMinLod), sampleParams.minLod) :
2796*35238bceSAndroid Build Coastguard Worker                              sampleParams.minLod;
2797*35238bceSAndroid Build Coastguard Worker 
2798*35238bceSAndroid Build Coastguard Worker     int numFailed = 0;
2799*35238bceSAndroid Build Coastguard Worker 
2800*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodOffsets[] = {
2801*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, 0),
2802*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, 0),
2803*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, -1),
2804*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, +1),
2805*35238bceSAndroid Build Coastguard Worker     };
2806*35238bceSAndroid Build Coastguard Worker 
2807*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask, tcu::RGBA::green().toVec());
2808*35238bceSAndroid Build Coastguard Worker 
2809*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < result.getHeight(); py++)
2810*35238bceSAndroid Build Coastguard Worker     {
2811*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < result.getWidth(); px++)
2812*35238bceSAndroid Build Coastguard Worker         {
2813*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 resPix = result.getPixel(px, py);
2814*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 refPix = reference.getPixel(px, py);
2815*35238bceSAndroid Build Coastguard Worker 
2816*35238bceSAndroid Build Coastguard Worker             // Other channels should trivially match to reference.
2817*35238bceSAndroid Build Coastguard Worker             if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1, 2, 3) - resPix.swizzle(1, 2, 3)),
2818*35238bceSAndroid Build Coastguard Worker                                                  nonShadowThreshold)))
2819*35238bceSAndroid Build Coastguard Worker             {
2820*35238bceSAndroid Build Coastguard Worker                 errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
2821*35238bceSAndroid Build Coastguard Worker                 numFailed += 1;
2822*35238bceSAndroid Build Coastguard Worker                 continue;
2823*35238bceSAndroid Build Coastguard Worker             }
2824*35238bceSAndroid Build Coastguard Worker 
2825*35238bceSAndroid Build Coastguard Worker             // Reference result is known to be a valid result, we can
2826*35238bceSAndroid Build Coastguard Worker             // skip verification if thes results are equal
2827*35238bceSAndroid Build Coastguard Worker             if (resPix.x() != refPix.x())
2828*35238bceSAndroid Build Coastguard Worker             {
2829*35238bceSAndroid Build Coastguard Worker                 const float wx = (float)px + 0.5f;
2830*35238bceSAndroid Build Coastguard Worker                 const float wy = (float)py + 0.5f;
2831*35238bceSAndroid Build Coastguard Worker                 const float nx = wx / dstW;
2832*35238bceSAndroid Build Coastguard Worker                 const float ny = wy / dstH;
2833*35238bceSAndroid Build Coastguard Worker 
2834*35238bceSAndroid Build Coastguard Worker                 const int triNdx  = nx + ny >= 1.0f ? 1 : 0;
2835*35238bceSAndroid Build Coastguard Worker                 const float triWx = triNdx ? dstW - wx : wx;
2836*35238bceSAndroid Build Coastguard Worker                 const float triWy = triNdx ? dstH - wy : wy;
2837*35238bceSAndroid Build Coastguard Worker                 const float triNx = triNdx ? 1.0f - nx : nx;
2838*35238bceSAndroid Build Coastguard Worker                 const float triNy = triNdx ? 1.0f - ny : ny;
2839*35238bceSAndroid Build Coastguard Worker 
2840*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec3 coord(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
2841*35238bceSAndroid Build Coastguard Worker                                       projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
2842*35238bceSAndroid Build Coastguard Worker                                       projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy));
2843*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec3 coordDx(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
2844*35238bceSAndroid Build Coastguard Worker                                         triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
2845*35238bceSAndroid Build Coastguard Worker                                         triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy));
2846*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec3 coordDy(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
2847*35238bceSAndroid Build Coastguard Worker                                         triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
2848*35238bceSAndroid Build Coastguard Worker                                         triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx));
2849*35238bceSAndroid Build Coastguard Worker 
2850*35238bceSAndroid Build Coastguard Worker                 tcu::Vec2 lodBounds = tcu::computeCubeLodBoundsFromDerivates(coord, coordDx, coordDy, srcSize, lodPrec);
2851*35238bceSAndroid Build Coastguard Worker 
2852*35238bceSAndroid Build Coastguard Worker                 // Compute lod bounds across lodOffsets range.
2853*35238bceSAndroid Build Coastguard Worker                 for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
2854*35238bceSAndroid Build Coastguard Worker                 {
2855*35238bceSAndroid Build Coastguard Worker                     const float wxo = triWx + lodOffsets[lodOffsNdx].x();
2856*35238bceSAndroid Build Coastguard Worker                     const float wyo = triWy + lodOffsets[lodOffsNdx].y();
2857*35238bceSAndroid Build Coastguard Worker                     const float nxo = wxo / dstW;
2858*35238bceSAndroid Build Coastguard Worker                     const float nyo = wyo / dstH;
2859*35238bceSAndroid Build Coastguard Worker 
2860*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec3 coordO(projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo),
2861*35238bceSAndroid Build Coastguard Worker                                            projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo),
2862*35238bceSAndroid Build Coastguard Worker                                            projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo));
2863*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec3 coordDxo(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
2864*35238bceSAndroid Build Coastguard Worker                                              triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo),
2865*35238bceSAndroid Build Coastguard Worker                                              triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo));
2866*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec3 coordDyo(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
2867*35238bceSAndroid Build Coastguard Worker                                              triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo),
2868*35238bceSAndroid Build Coastguard Worker                                              triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo));
2869*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 lodO =
2870*35238bceSAndroid Build Coastguard Worker                         tcu::computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec);
2871*35238bceSAndroid Build Coastguard Worker 
2872*35238bceSAndroid Build Coastguard Worker                     lodBounds.x() = de::min(lodBounds.x(), lodO.x());
2873*35238bceSAndroid Build Coastguard Worker                     lodBounds.y() = de::max(lodBounds.y(), lodO.y());
2874*35238bceSAndroid Build Coastguard Worker                 }
2875*35238bceSAndroid Build Coastguard Worker 
2876*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 clampedLod =
2877*35238bceSAndroid Build Coastguard Worker                     tcu::clampLodBounds(lodBounds + lodBias, tcu::Vec2(minLod, sampleParams.maxLod), lodPrec);
2878*35238bceSAndroid Build Coastguard Worker                 const bool isOk = tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord,
2879*35238bceSAndroid Build Coastguard Worker                                                                clampedLod, sampleParams.ref, resPix.x());
2880*35238bceSAndroid Build Coastguard Worker 
2881*35238bceSAndroid Build Coastguard Worker                 if (!isOk)
2882*35238bceSAndroid Build Coastguard Worker                 {
2883*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
2884*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
2885*35238bceSAndroid Build Coastguard Worker                 }
2886*35238bceSAndroid Build Coastguard Worker             }
2887*35238bceSAndroid Build Coastguard Worker         }
2888*35238bceSAndroid Build Coastguard Worker     }
2889*35238bceSAndroid Build Coastguard Worker 
2890*35238bceSAndroid Build Coastguard Worker     return numFailed;
2891*35238bceSAndroid Build Coastguard Worker }
2892*35238bceSAndroid Build Coastguard Worker 
computeTextureCompareDiff(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & reference,const tcu::PixelBufferAccess & errorMask,const tcu::Texture2DArrayView & src,const float * texCoord,const ReferenceParams & sampleParams,const tcu::TexComparePrecision & comparePrec,const tcu::LodPrecision & lodPrec,const tcu::Vec3 & nonShadowThreshold)2893*35238bceSAndroid Build Coastguard Worker int computeTextureCompareDiff(const tcu::ConstPixelBufferAccess &result, const tcu::ConstPixelBufferAccess &reference,
2894*35238bceSAndroid Build Coastguard Worker                               const tcu::PixelBufferAccess &errorMask, const tcu::Texture2DArrayView &src,
2895*35238bceSAndroid Build Coastguard Worker                               const float *texCoord, const ReferenceParams &sampleParams,
2896*35238bceSAndroid Build Coastguard Worker                               const tcu::TexComparePrecision &comparePrec, const tcu::LodPrecision &lodPrec,
2897*35238bceSAndroid Build Coastguard Worker                               const tcu::Vec3 &nonShadowThreshold)
2898*35238bceSAndroid Build Coastguard Worker {
2899*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
2900*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
2901*35238bceSAndroid Build Coastguard Worker 
2902*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[3 + 0], texCoord[6 + 0], texCoord[9 + 0]);
2903*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[3 + 1], texCoord[6 + 1], texCoord[9 + 1]);
2904*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 rq = tcu::Vec4(texCoord[0 + 2], texCoord[3 + 2], texCoord[6 + 2], texCoord[9 + 2]);
2905*35238bceSAndroid Build Coastguard Worker 
2906*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight());
2907*35238bceSAndroid Build Coastguard Worker     const float dstW         = float(dstSize.x());
2908*35238bceSAndroid Build Coastguard Worker     const float dstH         = float(dstSize.y());
2909*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 srcSize = tcu::IVec2(src.getWidth(), src.getHeight());
2910*35238bceSAndroid Build Coastguard Worker 
2911*35238bceSAndroid Build Coastguard Worker     // Coordinates and lod per triangle.
2912*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
2913*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
2914*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triR[2] = {rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1)};
2915*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triW[2] = {sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1)};
2916*35238bceSAndroid Build Coastguard Worker 
2917*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodBias((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);
2918*35238bceSAndroid Build Coastguard Worker 
2919*35238bceSAndroid Build Coastguard Worker     int numFailed = 0;
2920*35238bceSAndroid Build Coastguard Worker 
2921*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodOffsets[] = {
2922*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, 0),
2923*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, 0),
2924*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, -1),
2925*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, +1),
2926*35238bceSAndroid Build Coastguard Worker     };
2927*35238bceSAndroid Build Coastguard Worker 
2928*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask, tcu::RGBA::green().toVec());
2929*35238bceSAndroid Build Coastguard Worker 
2930*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < result.getHeight(); py++)
2931*35238bceSAndroid Build Coastguard Worker     {
2932*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < result.getWidth(); px++)
2933*35238bceSAndroid Build Coastguard Worker         {
2934*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 resPix = result.getPixel(px, py);
2935*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 refPix = reference.getPixel(px, py);
2936*35238bceSAndroid Build Coastguard Worker 
2937*35238bceSAndroid Build Coastguard Worker             // Other channels should trivially match to reference.
2938*35238bceSAndroid Build Coastguard Worker             if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1, 2, 3) - resPix.swizzle(1, 2, 3)),
2939*35238bceSAndroid Build Coastguard Worker                                                  nonShadowThreshold)))
2940*35238bceSAndroid Build Coastguard Worker             {
2941*35238bceSAndroid Build Coastguard Worker                 errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
2942*35238bceSAndroid Build Coastguard Worker                 numFailed += 1;
2943*35238bceSAndroid Build Coastguard Worker                 continue;
2944*35238bceSAndroid Build Coastguard Worker             }
2945*35238bceSAndroid Build Coastguard Worker 
2946*35238bceSAndroid Build Coastguard Worker             // Reference result is known to be a valid result, we can
2947*35238bceSAndroid Build Coastguard Worker             // skip verification if thes results are equal
2948*35238bceSAndroid Build Coastguard Worker             if (resPix.x() != refPix.x())
2949*35238bceSAndroid Build Coastguard Worker             {
2950*35238bceSAndroid Build Coastguard Worker                 const float wx = (float)px + 0.5f;
2951*35238bceSAndroid Build Coastguard Worker                 const float wy = (float)py + 0.5f;
2952*35238bceSAndroid Build Coastguard Worker                 const float nx = wx / dstW;
2953*35238bceSAndroid Build Coastguard Worker                 const float ny = wy / dstH;
2954*35238bceSAndroid Build Coastguard Worker 
2955*35238bceSAndroid Build Coastguard Worker                 const int triNdx  = nx + ny >= 1.0f ? 1 : 0;
2956*35238bceSAndroid Build Coastguard Worker                 const float triWx = triNdx ? dstW - wx : wx;
2957*35238bceSAndroid Build Coastguard Worker                 const float triWy = triNdx ? dstH - wy : wy;
2958*35238bceSAndroid Build Coastguard Worker                 const float triNx = triNdx ? 1.0f - nx : nx;
2959*35238bceSAndroid Build Coastguard Worker                 const float triNy = triNdx ? 1.0f - ny : ny;
2960*35238bceSAndroid Build Coastguard Worker 
2961*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec3 coord(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
2962*35238bceSAndroid Build Coastguard Worker                                       projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
2963*35238bceSAndroid Build Coastguard Worker                                       projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy));
2964*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 coordDx = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
2965*35238bceSAndroid Build Coastguard Worker                                                     triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy)) *
2966*35238bceSAndroid Build Coastguard Worker                                           srcSize.asFloat();
2967*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 coordDy = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
2968*35238bceSAndroid Build Coastguard Worker                                                     triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx)) *
2969*35238bceSAndroid Build Coastguard Worker                                           srcSize.asFloat();
2970*35238bceSAndroid Build Coastguard Worker 
2971*35238bceSAndroid Build Coastguard Worker                 tcu::Vec2 lodBounds =
2972*35238bceSAndroid Build Coastguard Worker                     tcu::computeLodBoundsFromDerivates(coordDx.x(), coordDx.y(), coordDy.x(), coordDy.y(), lodPrec);
2973*35238bceSAndroid Build Coastguard Worker 
2974*35238bceSAndroid Build Coastguard Worker                 // Compute lod bounds across lodOffsets range.
2975*35238bceSAndroid Build Coastguard Worker                 for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
2976*35238bceSAndroid Build Coastguard Worker                 {
2977*35238bceSAndroid Build Coastguard Worker                     const float wxo = triWx + lodOffsets[lodOffsNdx].x();
2978*35238bceSAndroid Build Coastguard Worker                     const float wyo = triWy + lodOffsets[lodOffsNdx].y();
2979*35238bceSAndroid Build Coastguard Worker                     const float nxo = wxo / dstW;
2980*35238bceSAndroid Build Coastguard Worker                     const float nyo = wyo / dstH;
2981*35238bceSAndroid Build Coastguard Worker 
2982*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 coordDxo = tcu::Vec2(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
2983*35238bceSAndroid Build Coastguard Worker                                                          triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo)) *
2984*35238bceSAndroid Build Coastguard Worker                                                srcSize.asFloat();
2985*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 coordDyo = tcu::Vec2(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
2986*35238bceSAndroid Build Coastguard Worker                                                          triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo)) *
2987*35238bceSAndroid Build Coastguard Worker                                                srcSize.asFloat();
2988*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo.x(), coordDxo.y(), coordDyo.x(),
2989*35238bceSAndroid Build Coastguard Worker                                                                               coordDyo.y(), lodPrec);
2990*35238bceSAndroid Build Coastguard Worker 
2991*35238bceSAndroid Build Coastguard Worker                     lodBounds.x() = de::min(lodBounds.x(), lodO.x());
2992*35238bceSAndroid Build Coastguard Worker                     lodBounds.y() = de::max(lodBounds.y(), lodO.y());
2993*35238bceSAndroid Build Coastguard Worker                 }
2994*35238bceSAndroid Build Coastguard Worker 
2995*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 clampedLod = tcu::clampLodBounds(
2996*35238bceSAndroid Build Coastguard Worker                     lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
2997*35238bceSAndroid Build Coastguard Worker                 const bool isOk = tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord,
2998*35238bceSAndroid Build Coastguard Worker                                                                clampedLod, sampleParams.ref, resPix.x());
2999*35238bceSAndroid Build Coastguard Worker 
3000*35238bceSAndroid Build Coastguard Worker                 if (!isOk)
3001*35238bceSAndroid Build Coastguard Worker                 {
3002*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
3003*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
3004*35238bceSAndroid Build Coastguard Worker                 }
3005*35238bceSAndroid Build Coastguard Worker             }
3006*35238bceSAndroid Build Coastguard Worker         }
3007*35238bceSAndroid Build Coastguard Worker     }
3008*35238bceSAndroid Build Coastguard Worker 
3009*35238bceSAndroid Build Coastguard Worker     return numFailed;
3010*35238bceSAndroid Build Coastguard Worker }
3011*35238bceSAndroid Build Coastguard Worker 
computeTextureCompareDiff(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & reference,const tcu::PixelBufferAccess & errorMask,const tcu::Texture1DView & src,const float * texCoord,const ReferenceParams & sampleParams,const tcu::TexComparePrecision & comparePrec,const tcu::LodPrecision & lodPrec,const tcu::Vec3 & nonShadowThreshold)3012*35238bceSAndroid Build Coastguard Worker int computeTextureCompareDiff(const tcu::ConstPixelBufferAccess &result, const tcu::ConstPixelBufferAccess &reference,
3013*35238bceSAndroid Build Coastguard Worker                               const tcu::PixelBufferAccess &errorMask, const tcu::Texture1DView &src,
3014*35238bceSAndroid Build Coastguard Worker                               const float *texCoord, const ReferenceParams &sampleParams,
3015*35238bceSAndroid Build Coastguard Worker                               const tcu::TexComparePrecision &comparePrec, const tcu::LodPrecision &lodPrec,
3016*35238bceSAndroid Build Coastguard Worker                               const tcu::Vec3 &nonShadowThreshold)
3017*35238bceSAndroid Build Coastguard Worker {
3018*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
3019*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
3020*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getHeight() == 1);
3021*35238bceSAndroid Build Coastguard Worker 
3022*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0], texCoord[1], texCoord[2], texCoord[3]);
3023*35238bceSAndroid Build Coastguard Worker 
3024*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), 1);
3025*35238bceSAndroid Build Coastguard Worker     const float dstW         = float(dstSize.x());
3026*35238bceSAndroid Build Coastguard Worker     const float dstH         = float(dstSize.y());
3027*35238bceSAndroid Build Coastguard Worker     const float srcSize      = float(src.getWidth());
3028*35238bceSAndroid Build Coastguard Worker 
3029*35238bceSAndroid Build Coastguard Worker     // Coordinates and lod per triangle.
3030*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
3031*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triW[2] = {sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1)};
3032*35238bceSAndroid Build Coastguard Worker 
3033*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodBias((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);
3034*35238bceSAndroid Build Coastguard Worker 
3035*35238bceSAndroid Build Coastguard Worker     int numFailed = 0;
3036*35238bceSAndroid Build Coastguard Worker 
3037*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodOffsets[] = {
3038*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, 0),
3039*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, 0),
3040*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, -1),
3041*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, +1),
3042*35238bceSAndroid Build Coastguard Worker     };
3043*35238bceSAndroid Build Coastguard Worker 
3044*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask, tcu::RGBA::green().toVec());
3045*35238bceSAndroid Build Coastguard Worker 
3046*35238bceSAndroid Build Coastguard Worker     const int py = 0;
3047*35238bceSAndroid Build Coastguard Worker     {
3048*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < result.getWidth(); px++)
3049*35238bceSAndroid Build Coastguard Worker         {
3050*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 resPix = result.getPixel(px, py);
3051*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 refPix = reference.getPixel(px, py);
3052*35238bceSAndroid Build Coastguard Worker 
3053*35238bceSAndroid Build Coastguard Worker             // Other channels should trivially match to reference.
3054*35238bceSAndroid Build Coastguard Worker             if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1, 2, 3) - resPix.swizzle(1, 2, 3)),
3055*35238bceSAndroid Build Coastguard Worker                                                  nonShadowThreshold)))
3056*35238bceSAndroid Build Coastguard Worker             {
3057*35238bceSAndroid Build Coastguard Worker                 errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
3058*35238bceSAndroid Build Coastguard Worker                 numFailed += 1;
3059*35238bceSAndroid Build Coastguard Worker                 continue;
3060*35238bceSAndroid Build Coastguard Worker             }
3061*35238bceSAndroid Build Coastguard Worker 
3062*35238bceSAndroid Build Coastguard Worker             // Reference result is known to be a valid result, we can
3063*35238bceSAndroid Build Coastguard Worker             // skip verification if thes results are equal
3064*35238bceSAndroid Build Coastguard Worker             if (resPix.x() != refPix.x())
3065*35238bceSAndroid Build Coastguard Worker             {
3066*35238bceSAndroid Build Coastguard Worker                 const float wx = (float)px + 0.5f;
3067*35238bceSAndroid Build Coastguard Worker                 const float wy = (float)py + 0.5f;
3068*35238bceSAndroid Build Coastguard Worker                 const float nx = wx / dstW;
3069*35238bceSAndroid Build Coastguard Worker                 const float ny = wy / dstH;
3070*35238bceSAndroid Build Coastguard Worker 
3071*35238bceSAndroid Build Coastguard Worker                 const int triNdx  = nx + ny >= 1.0f ? 1 : 0;
3072*35238bceSAndroid Build Coastguard Worker                 const float triWx = triNdx ? dstW - wx : wx;
3073*35238bceSAndroid Build Coastguard Worker                 const float triWy = triNdx ? dstH - wy : wy;
3074*35238bceSAndroid Build Coastguard Worker                 const float triNx = triNdx ? 1.0f - nx : nx;
3075*35238bceSAndroid Build Coastguard Worker                 const float triNy = triNdx ? 1.0f - ny : ny;
3076*35238bceSAndroid Build Coastguard Worker 
3077*35238bceSAndroid Build Coastguard Worker                 const float coord(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy));
3078*35238bceSAndroid Build Coastguard Worker                 const float coordDx = triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy) * srcSize;
3079*35238bceSAndroid Build Coastguard Worker 
3080*35238bceSAndroid Build Coastguard Worker                 tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx, coordDx, lodPrec);
3081*35238bceSAndroid Build Coastguard Worker 
3082*35238bceSAndroid Build Coastguard Worker                 // Compute lod bounds across lodOffsets range.
3083*35238bceSAndroid Build Coastguard Worker                 for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
3084*35238bceSAndroid Build Coastguard Worker                 {
3085*35238bceSAndroid Build Coastguard Worker                     const float wxo = triWx + lodOffsets[lodOffsNdx].x();
3086*35238bceSAndroid Build Coastguard Worker                     const float wyo = triWy + lodOffsets[lodOffsNdx].y();
3087*35238bceSAndroid Build Coastguard Worker                     const float nxo = wxo / dstW;
3088*35238bceSAndroid Build Coastguard Worker                     const float nyo = wyo / dstH;
3089*35238bceSAndroid Build Coastguard Worker 
3090*35238bceSAndroid Build Coastguard Worker                     const float coordDxo = triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo) * srcSize;
3091*35238bceSAndroid Build Coastguard Worker                     const float coordDyo = triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo) * srcSize;
3092*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo, coordDyo, lodPrec);
3093*35238bceSAndroid Build Coastguard Worker 
3094*35238bceSAndroid Build Coastguard Worker                     lodBounds.x() = de::min(lodBounds.x(), lodO.x());
3095*35238bceSAndroid Build Coastguard Worker                     lodBounds.y() = de::max(lodBounds.y(), lodO.y());
3096*35238bceSAndroid Build Coastguard Worker                 }
3097*35238bceSAndroid Build Coastguard Worker 
3098*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 clampedLod = tcu::clampLodBounds(
3099*35238bceSAndroid Build Coastguard Worker                     lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
3100*35238bceSAndroid Build Coastguard Worker                 const bool isOk = tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, tcu::Vec1(coord),
3101*35238bceSAndroid Build Coastguard Worker                                                                clampedLod, sampleParams.ref, resPix.x());
3102*35238bceSAndroid Build Coastguard Worker 
3103*35238bceSAndroid Build Coastguard Worker                 if (!isOk)
3104*35238bceSAndroid Build Coastguard Worker                 {
3105*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
3106*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
3107*35238bceSAndroid Build Coastguard Worker                 }
3108*35238bceSAndroid Build Coastguard Worker             }
3109*35238bceSAndroid Build Coastguard Worker         }
3110*35238bceSAndroid Build Coastguard Worker     }
3111*35238bceSAndroid Build Coastguard Worker 
3112*35238bceSAndroid Build Coastguard Worker     return numFailed;
3113*35238bceSAndroid Build Coastguard Worker }
3114*35238bceSAndroid Build Coastguard Worker 
computeTextureCompareDiff(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & reference,const tcu::PixelBufferAccess & errorMask,const tcu::Texture1DArrayView & src,const float * texCoord,const ReferenceParams & sampleParams,const tcu::TexComparePrecision & comparePrec,const tcu::LodPrecision & lodPrec,const tcu::Vec3 & nonShadowThreshold)3115*35238bceSAndroid Build Coastguard Worker int computeTextureCompareDiff(const tcu::ConstPixelBufferAccess &result, const tcu::ConstPixelBufferAccess &reference,
3116*35238bceSAndroid Build Coastguard Worker                               const tcu::PixelBufferAccess &errorMask, const tcu::Texture1DArrayView &src,
3117*35238bceSAndroid Build Coastguard Worker                               const float *texCoord, const ReferenceParams &sampleParams,
3118*35238bceSAndroid Build Coastguard Worker                               const tcu::TexComparePrecision &comparePrec, const tcu::LodPrecision &lodPrec,
3119*35238bceSAndroid Build Coastguard Worker                               const tcu::Vec3 &nonShadowThreshold)
3120*35238bceSAndroid Build Coastguard Worker {
3121*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
3122*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
3123*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getHeight() == 1);
3124*35238bceSAndroid Build Coastguard Worker 
3125*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[2 + 0], texCoord[4 + 0], texCoord[6 + 0]);
3126*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[2 + 1], texCoord[4 + 1], texCoord[6 + 1]);
3127*35238bceSAndroid Build Coastguard Worker 
3128*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), 1);
3129*35238bceSAndroid Build Coastguard Worker     const float dstW         = float(dstSize.x());
3130*35238bceSAndroid Build Coastguard Worker     const float dstH         = float(dstSize.y());
3131*35238bceSAndroid Build Coastguard Worker     const float srcSize      = float(src.getWidth());
3132*35238bceSAndroid Build Coastguard Worker 
3133*35238bceSAndroid Build Coastguard Worker     // Coordinates and lod per triangle.
3134*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
3135*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
3136*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triW[2] = {sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1)};
3137*35238bceSAndroid Build Coastguard Worker 
3138*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodBias((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);
3139*35238bceSAndroid Build Coastguard Worker 
3140*35238bceSAndroid Build Coastguard Worker     int numFailed = 0;
3141*35238bceSAndroid Build Coastguard Worker 
3142*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodOffsets[] = {
3143*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, 0),
3144*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, 0),
3145*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, -1),
3146*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, +1),
3147*35238bceSAndroid Build Coastguard Worker     };
3148*35238bceSAndroid Build Coastguard Worker 
3149*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask, tcu::RGBA::green().toVec());
3150*35238bceSAndroid Build Coastguard Worker 
3151*35238bceSAndroid Build Coastguard Worker     const int py = 0;
3152*35238bceSAndroid Build Coastguard Worker     {
3153*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < result.getWidth(); px++)
3154*35238bceSAndroid Build Coastguard Worker         {
3155*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 resPix = result.getPixel(px, py);
3156*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 refPix = reference.getPixel(px, py);
3157*35238bceSAndroid Build Coastguard Worker 
3158*35238bceSAndroid Build Coastguard Worker             // Other channels should trivially match to reference.
3159*35238bceSAndroid Build Coastguard Worker             if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1, 2, 3) - resPix.swizzle(1, 2, 3)),
3160*35238bceSAndroid Build Coastguard Worker                                                  nonShadowThreshold)))
3161*35238bceSAndroid Build Coastguard Worker             {
3162*35238bceSAndroid Build Coastguard Worker                 errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
3163*35238bceSAndroid Build Coastguard Worker                 numFailed += 1;
3164*35238bceSAndroid Build Coastguard Worker                 continue;
3165*35238bceSAndroid Build Coastguard Worker             }
3166*35238bceSAndroid Build Coastguard Worker 
3167*35238bceSAndroid Build Coastguard Worker             // Reference result is known to be a valid result, we can
3168*35238bceSAndroid Build Coastguard Worker             // skip verification if these results are equal
3169*35238bceSAndroid Build Coastguard Worker             if (resPix.x() != refPix.x())
3170*35238bceSAndroid Build Coastguard Worker             {
3171*35238bceSAndroid Build Coastguard Worker                 const float wx = (float)px + 0.5f;
3172*35238bceSAndroid Build Coastguard Worker                 const float wy = (float)py + 0.5f;
3173*35238bceSAndroid Build Coastguard Worker                 const float nx = wx / dstW;
3174*35238bceSAndroid Build Coastguard Worker                 const float ny = wy / dstH;
3175*35238bceSAndroid Build Coastguard Worker 
3176*35238bceSAndroid Build Coastguard Worker                 const int triNdx  = nx + ny >= 1.0f ? 1 : 0;
3177*35238bceSAndroid Build Coastguard Worker                 const float triWx = triNdx ? dstW - wx : wx;
3178*35238bceSAndroid Build Coastguard Worker                 const float triWy = triNdx ? dstH - wy : wy;
3179*35238bceSAndroid Build Coastguard Worker                 const float triNx = triNdx ? 1.0f - nx : nx;
3180*35238bceSAndroid Build Coastguard Worker                 const float triNy = triNdx ? 1.0f - ny : ny;
3181*35238bceSAndroid Build Coastguard Worker 
3182*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 coord(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
3183*35238bceSAndroid Build Coastguard Worker                                       projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy));
3184*35238bceSAndroid Build Coastguard Worker                 const float coordDx = triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy) * srcSize;
3185*35238bceSAndroid Build Coastguard Worker 
3186*35238bceSAndroid Build Coastguard Worker                 tcu::Vec2 lodBounds = tcu::computeLodBoundsFromDerivates(coordDx, coordDx, lodPrec);
3187*35238bceSAndroid Build Coastguard Worker 
3188*35238bceSAndroid Build Coastguard Worker                 // Compute lod bounds across lodOffsets range.
3189*35238bceSAndroid Build Coastguard Worker                 for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
3190*35238bceSAndroid Build Coastguard Worker                 {
3191*35238bceSAndroid Build Coastguard Worker                     const float wxo = triWx + lodOffsets[lodOffsNdx].x();
3192*35238bceSAndroid Build Coastguard Worker                     const float wyo = triWy + lodOffsets[lodOffsNdx].y();
3193*35238bceSAndroid Build Coastguard Worker                     const float nxo = wxo / dstW;
3194*35238bceSAndroid Build Coastguard Worker                     const float nyo = wyo / dstH;
3195*35238bceSAndroid Build Coastguard Worker 
3196*35238bceSAndroid Build Coastguard Worker                     const float coordDxo = triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo) * srcSize;
3197*35238bceSAndroid Build Coastguard Worker                     const float coordDyo = triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo) * srcSize;
3198*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 lodO = tcu::computeLodBoundsFromDerivates(coordDxo, coordDyo, lodPrec);
3199*35238bceSAndroid Build Coastguard Worker 
3200*35238bceSAndroid Build Coastguard Worker                     lodBounds.x() = de::min(lodBounds.x(), lodO.x());
3201*35238bceSAndroid Build Coastguard Worker                     lodBounds.y() = de::max(lodBounds.y(), lodO.y());
3202*35238bceSAndroid Build Coastguard Worker                 }
3203*35238bceSAndroid Build Coastguard Worker 
3204*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 clampedLod = tcu::clampLodBounds(
3205*35238bceSAndroid Build Coastguard Worker                     lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
3206*35238bceSAndroid Build Coastguard Worker                 const bool isOk = tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord,
3207*35238bceSAndroid Build Coastguard Worker                                                                clampedLod, sampleParams.ref, resPix.x());
3208*35238bceSAndroid Build Coastguard Worker 
3209*35238bceSAndroid Build Coastguard Worker                 if (!isOk)
3210*35238bceSAndroid Build Coastguard Worker                 {
3211*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
3212*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
3213*35238bceSAndroid Build Coastguard Worker                 }
3214*35238bceSAndroid Build Coastguard Worker             }
3215*35238bceSAndroid Build Coastguard Worker         }
3216*35238bceSAndroid Build Coastguard Worker     }
3217*35238bceSAndroid Build Coastguard Worker 
3218*35238bceSAndroid Build Coastguard Worker     return numFailed;
3219*35238bceSAndroid Build Coastguard Worker }
3220*35238bceSAndroid Build Coastguard Worker 
computeTextureCompareDiff(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & reference,const tcu::PixelBufferAccess & errorMask,const tcu::TextureCubeArrayView & src,const float * texCoord,const ReferenceParams & sampleParams,const tcu::TexComparePrecision & comparePrec,const tcu::LodPrecision & lodPrec,const tcu::Vec3 & nonShadowThreshold)3221*35238bceSAndroid Build Coastguard Worker int computeTextureCompareDiff(const tcu::ConstPixelBufferAccess &result, const tcu::ConstPixelBufferAccess &reference,
3222*35238bceSAndroid Build Coastguard Worker                               const tcu::PixelBufferAccess &errorMask, const tcu::TextureCubeArrayView &src,
3223*35238bceSAndroid Build Coastguard Worker                               const float *texCoord, const ReferenceParams &sampleParams,
3224*35238bceSAndroid Build Coastguard Worker                               const tcu::TexComparePrecision &comparePrec, const tcu::LodPrecision &lodPrec,
3225*35238bceSAndroid Build Coastguard Worker                               const tcu::Vec3 &nonShadowThreshold)
3226*35238bceSAndroid Build Coastguard Worker {
3227*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight());
3228*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(result.getWidth() == errorMask.getWidth() && result.getHeight() == errorMask.getHeight());
3229*35238bceSAndroid Build Coastguard Worker 
3230*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 sq = tcu::Vec4(texCoord[0 + 0], texCoord[4 + 0], texCoord[8 + 0], texCoord[12 + 0]);
3231*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 tq = tcu::Vec4(texCoord[0 + 1], texCoord[4 + 1], texCoord[8 + 1], texCoord[12 + 1]);
3232*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 rq = tcu::Vec4(texCoord[0 + 2], texCoord[4 + 2], texCoord[8 + 2], texCoord[12 + 2]);
3233*35238bceSAndroid Build Coastguard Worker     const tcu::Vec4 qq = tcu::Vec4(texCoord[0 + 3], texCoord[4 + 3], texCoord[8 + 3], texCoord[12 + 3]);
3234*35238bceSAndroid Build Coastguard Worker 
3235*35238bceSAndroid Build Coastguard Worker     const tcu::IVec2 dstSize = tcu::IVec2(result.getWidth(), result.getHeight());
3236*35238bceSAndroid Build Coastguard Worker     const float dstW         = float(dstSize.x());
3237*35238bceSAndroid Build Coastguard Worker     const float dstH         = float(dstSize.y());
3238*35238bceSAndroid Build Coastguard Worker     const int srcSize        = src.getSize();
3239*35238bceSAndroid Build Coastguard Worker 
3240*35238bceSAndroid Build Coastguard Worker     // Coordinates per triangle.
3241*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triS[2] = {sq.swizzle(0, 1, 2), sq.swizzle(3, 2, 1)};
3242*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triT[2] = {tq.swizzle(0, 1, 2), tq.swizzle(3, 2, 1)};
3243*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triR[2] = {rq.swizzle(0, 1, 2), rq.swizzle(3, 2, 1)};
3244*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triQ[2] = {qq.swizzle(0, 1, 2), qq.swizzle(3, 2, 1)};
3245*35238bceSAndroid Build Coastguard Worker     const tcu::Vec3 triW[2] = {sampleParams.w.swizzle(0, 1, 2), sampleParams.w.swizzle(3, 2, 1)};
3246*35238bceSAndroid Build Coastguard Worker 
3247*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodBias((sampleParams.flags & ReferenceParams::USE_BIAS) ? sampleParams.bias : 0.0f);
3248*35238bceSAndroid Build Coastguard Worker 
3249*35238bceSAndroid Build Coastguard Worker     int numFailed = 0;
3250*35238bceSAndroid Build Coastguard Worker 
3251*35238bceSAndroid Build Coastguard Worker     const tcu::Vec2 lodOffsets[] = {
3252*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(-1, 0),
3253*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(+1, 0),
3254*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, -1),
3255*35238bceSAndroid Build Coastguard Worker         tcu::Vec2(0, +1),
3256*35238bceSAndroid Build Coastguard Worker     };
3257*35238bceSAndroid Build Coastguard Worker 
3258*35238bceSAndroid Build Coastguard Worker     tcu::clear(errorMask, tcu::RGBA::green().toVec());
3259*35238bceSAndroid Build Coastguard Worker 
3260*35238bceSAndroid Build Coastguard Worker     for (int py = 0; py < result.getHeight(); py++)
3261*35238bceSAndroid Build Coastguard Worker     {
3262*35238bceSAndroid Build Coastguard Worker         for (int px = 0; px < result.getWidth(); px++)
3263*35238bceSAndroid Build Coastguard Worker         {
3264*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 resPix = result.getPixel(px, py);
3265*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 refPix = reference.getPixel(px, py);
3266*35238bceSAndroid Build Coastguard Worker 
3267*35238bceSAndroid Build Coastguard Worker             // Other channels should trivially match to reference.
3268*35238bceSAndroid Build Coastguard Worker             if (!tcu::boolAll(tcu::lessThanEqual(tcu::abs(refPix.swizzle(1, 2, 3) - resPix.swizzle(1, 2, 3)),
3269*35238bceSAndroid Build Coastguard Worker                                                  nonShadowThreshold)))
3270*35238bceSAndroid Build Coastguard Worker             {
3271*35238bceSAndroid Build Coastguard Worker                 errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
3272*35238bceSAndroid Build Coastguard Worker                 numFailed += 1;
3273*35238bceSAndroid Build Coastguard Worker                 continue;
3274*35238bceSAndroid Build Coastguard Worker             }
3275*35238bceSAndroid Build Coastguard Worker 
3276*35238bceSAndroid Build Coastguard Worker             // Reference result is known to be a valid result, we can
3277*35238bceSAndroid Build Coastguard Worker             // skip verification if thes results are equal
3278*35238bceSAndroid Build Coastguard Worker             if (resPix.x() != refPix.x())
3279*35238bceSAndroid Build Coastguard Worker             {
3280*35238bceSAndroid Build Coastguard Worker                 const float wx = (float)px + 0.5f;
3281*35238bceSAndroid Build Coastguard Worker                 const float wy = (float)py + 0.5f;
3282*35238bceSAndroid Build Coastguard Worker                 const float nx = wx / dstW;
3283*35238bceSAndroid Build Coastguard Worker                 const float ny = wy / dstH;
3284*35238bceSAndroid Build Coastguard Worker 
3285*35238bceSAndroid Build Coastguard Worker                 const int triNdx  = nx + ny >= 1.0f ? 1 : 0;
3286*35238bceSAndroid Build Coastguard Worker                 const float triWx = triNdx ? dstW - wx : wx;
3287*35238bceSAndroid Build Coastguard Worker                 const float triWy = triNdx ? dstH - wy : wy;
3288*35238bceSAndroid Build Coastguard Worker                 const float triNx = triNdx ? 1.0f - nx : nx;
3289*35238bceSAndroid Build Coastguard Worker                 const float triNy = triNdx ? 1.0f - ny : ny;
3290*35238bceSAndroid Build Coastguard Worker 
3291*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec4 coord(projectedTriInterpolate(triS[triNdx], triW[triNdx], triNx, triNy),
3292*35238bceSAndroid Build Coastguard Worker                                       projectedTriInterpolate(triT[triNdx], triW[triNdx], triNx, triNy),
3293*35238bceSAndroid Build Coastguard Worker                                       projectedTriInterpolate(triR[triNdx], triW[triNdx], triNx, triNy),
3294*35238bceSAndroid Build Coastguard Worker                                       projectedTriInterpolate(triQ[triNdx], triW[triNdx], triNx, triNy));
3295*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec3 coordDx(triDerivateX(triS[triNdx], triW[triNdx], wx, dstW, triNy),
3296*35238bceSAndroid Build Coastguard Worker                                         triDerivateX(triT[triNdx], triW[triNdx], wx, dstW, triNy),
3297*35238bceSAndroid Build Coastguard Worker                                         triDerivateX(triR[triNdx], triW[triNdx], wx, dstW, triNy));
3298*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec3 coordDy(triDerivateY(triS[triNdx], triW[triNdx], wy, dstH, triNx),
3299*35238bceSAndroid Build Coastguard Worker                                         triDerivateY(triT[triNdx], triW[triNdx], wy, dstH, triNx),
3300*35238bceSAndroid Build Coastguard Worker                                         triDerivateY(triR[triNdx], triW[triNdx], wy, dstH, triNx));
3301*35238bceSAndroid Build Coastguard Worker 
3302*35238bceSAndroid Build Coastguard Worker                 tcu::Vec2 lodBounds =
3303*35238bceSAndroid Build Coastguard Worker                     tcu::computeCubeLodBoundsFromDerivates(coord.swizzle(0, 1, 2), coordDx, coordDy, srcSize, lodPrec);
3304*35238bceSAndroid Build Coastguard Worker 
3305*35238bceSAndroid Build Coastguard Worker                 // Compute lod bounds across lodOffsets range.
3306*35238bceSAndroid Build Coastguard Worker                 for (int lodOffsNdx = 0; lodOffsNdx < DE_LENGTH_OF_ARRAY(lodOffsets); lodOffsNdx++)
3307*35238bceSAndroid Build Coastguard Worker                 {
3308*35238bceSAndroid Build Coastguard Worker                     const float wxo = triWx + lodOffsets[lodOffsNdx].x();
3309*35238bceSAndroid Build Coastguard Worker                     const float wyo = triWy + lodOffsets[lodOffsNdx].y();
3310*35238bceSAndroid Build Coastguard Worker                     const float nxo = wxo / dstW;
3311*35238bceSAndroid Build Coastguard Worker                     const float nyo = wyo / dstH;
3312*35238bceSAndroid Build Coastguard Worker 
3313*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec3 coordO(projectedTriInterpolate(triS[triNdx], triW[triNdx], nxo, nyo),
3314*35238bceSAndroid Build Coastguard Worker                                            projectedTriInterpolate(triT[triNdx], triW[triNdx], nxo, nyo),
3315*35238bceSAndroid Build Coastguard Worker                                            projectedTriInterpolate(triR[triNdx], triW[triNdx], nxo, nyo));
3316*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec3 coordDxo(triDerivateX(triS[triNdx], triW[triNdx], wxo, dstW, nyo),
3317*35238bceSAndroid Build Coastguard Worker                                              triDerivateX(triT[triNdx], triW[triNdx], wxo, dstW, nyo),
3318*35238bceSAndroid Build Coastguard Worker                                              triDerivateX(triR[triNdx], triW[triNdx], wxo, dstW, nyo));
3319*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec3 coordDyo(triDerivateY(triS[triNdx], triW[triNdx], wyo, dstH, nxo),
3320*35238bceSAndroid Build Coastguard Worker                                              triDerivateY(triT[triNdx], triW[triNdx], wyo, dstH, nxo),
3321*35238bceSAndroid Build Coastguard Worker                                              triDerivateY(triR[triNdx], triW[triNdx], wyo, dstH, nxo));
3322*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec2 lodO =
3323*35238bceSAndroid Build Coastguard Worker                         tcu::computeCubeLodBoundsFromDerivates(coordO, coordDxo, coordDyo, srcSize, lodPrec);
3324*35238bceSAndroid Build Coastguard Worker 
3325*35238bceSAndroid Build Coastguard Worker                     lodBounds.x() = de::min(lodBounds.x(), lodO.x());
3326*35238bceSAndroid Build Coastguard Worker                     lodBounds.y() = de::max(lodBounds.y(), lodO.y());
3327*35238bceSAndroid Build Coastguard Worker                 }
3328*35238bceSAndroid Build Coastguard Worker 
3329*35238bceSAndroid Build Coastguard Worker                 const tcu::Vec2 clampedLod = tcu::clampLodBounds(
3330*35238bceSAndroid Build Coastguard Worker                     lodBounds + lodBias, tcu::Vec2(sampleParams.minLod, sampleParams.maxLod), lodPrec);
3331*35238bceSAndroid Build Coastguard Worker                 const bool isOk = tcu::isTexCompareResultValid(src, sampleParams.sampler, comparePrec, coord,
3332*35238bceSAndroid Build Coastguard Worker                                                                clampedLod, sampleParams.ref, resPix.x());
3333*35238bceSAndroid Build Coastguard Worker 
3334*35238bceSAndroid Build Coastguard Worker                 if (!isOk)
3335*35238bceSAndroid Build Coastguard Worker                 {
3336*35238bceSAndroid Build Coastguard Worker                     errorMask.setPixel(tcu::RGBA::red().toVec(), px, py);
3337*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
3338*35238bceSAndroid Build Coastguard Worker                 }
3339*35238bceSAndroid Build Coastguard Worker             }
3340*35238bceSAndroid Build Coastguard Worker         }
3341*35238bceSAndroid Build Coastguard Worker     }
3342*35238bceSAndroid Build Coastguard Worker 
3343*35238bceSAndroid Build Coastguard Worker     return numFailed;
3344*35238bceSAndroid Build Coastguard Worker }
3345*35238bceSAndroid Build Coastguard Worker 
3346*35238bceSAndroid Build Coastguard Worker // Mipmap generation comparison.
3347*35238bceSAndroid Build Coastguard Worker 
compareGenMipmapBilinear(const tcu::ConstPixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const tcu::PixelBufferAccess & errorMask,const GenMipmapPrecision & precision)3348*35238bceSAndroid Build Coastguard Worker static int compareGenMipmapBilinear(const tcu::ConstPixelBufferAccess &dst, const tcu::ConstPixelBufferAccess &src,
3349*35238bceSAndroid Build Coastguard Worker                                     const tcu::PixelBufferAccess &errorMask, const GenMipmapPrecision &precision)
3350*35238bceSAndroid Build Coastguard Worker {
3351*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1); // \todo [2013-10-29 pyry] 3D textures.
3352*35238bceSAndroid Build Coastguard Worker 
3353*35238bceSAndroid Build Coastguard Worker     const float dstW = float(dst.getWidth());
3354*35238bceSAndroid Build Coastguard Worker     const float dstH = float(dst.getHeight());
3355*35238bceSAndroid Build Coastguard Worker     const float srcW = float(src.getWidth());
3356*35238bceSAndroid Build Coastguard Worker     const float srcH = float(src.getHeight());
3357*35238bceSAndroid Build Coastguard Worker     int numFailed    = 0;
3358*35238bceSAndroid Build Coastguard Worker 
3359*35238bceSAndroid Build Coastguard Worker     // Translation to lookup verification parameters.
3360*35238bceSAndroid Build Coastguard Worker     const tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
3361*35238bceSAndroid Build Coastguard Worker                                tcu::Sampler::LINEAR, tcu::Sampler::LINEAR, 0.0f, false /* non-normalized coords */);
3362*35238bceSAndroid Build Coastguard Worker     tcu::LookupPrecision lookupPrec;
3363*35238bceSAndroid Build Coastguard Worker 
3364*35238bceSAndroid Build Coastguard Worker     lookupPrec.colorThreshold = precision.colorThreshold;
3365*35238bceSAndroid Build Coastguard Worker     lookupPrec.colorMask      = precision.colorMask;
3366*35238bceSAndroid Build Coastguard Worker     lookupPrec.coordBits      = tcu::IVec3(22);
3367*35238bceSAndroid Build Coastguard Worker     lookupPrec.uvwBits        = precision.filterBits;
3368*35238bceSAndroid Build Coastguard Worker 
3369*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < dst.getHeight(); y++)
3370*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < dst.getWidth(); x++)
3371*35238bceSAndroid Build Coastguard Worker         {
3372*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 result = dst.getPixel(x, y);
3373*35238bceSAndroid Build Coastguard Worker             const float cx         = (float(x) + 0.5f) / dstW * srcW;
3374*35238bceSAndroid Build Coastguard Worker             const float cy         = (float(y) + 0.5f) / dstH * srcH;
3375*35238bceSAndroid Build Coastguard Worker             const bool isOk = tcu::isLinearSampleResultValid(src, sampler, lookupPrec, tcu::Vec2(cx, cy), 0, result);
3376*35238bceSAndroid Build Coastguard Worker 
3377*35238bceSAndroid Build Coastguard Worker             errorMask.setPixel(isOk ? tcu::RGBA::green().toVec() : tcu::RGBA::red().toVec(), x, y);
3378*35238bceSAndroid Build Coastguard Worker             if (!isOk)
3379*35238bceSAndroid Build Coastguard Worker                 numFailed += 1;
3380*35238bceSAndroid Build Coastguard Worker         }
3381*35238bceSAndroid Build Coastguard Worker 
3382*35238bceSAndroid Build Coastguard Worker     return numFailed;
3383*35238bceSAndroid Build Coastguard Worker }
3384*35238bceSAndroid Build Coastguard Worker 
compareGenMipmapBox(const tcu::ConstPixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const tcu::PixelBufferAccess & errorMask,const GenMipmapPrecision & precision)3385*35238bceSAndroid Build Coastguard Worker static int compareGenMipmapBox(const tcu::ConstPixelBufferAccess &dst, const tcu::ConstPixelBufferAccess &src,
3386*35238bceSAndroid Build Coastguard Worker                                const tcu::PixelBufferAccess &errorMask, const GenMipmapPrecision &precision)
3387*35238bceSAndroid Build Coastguard Worker {
3388*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1); // \todo [2013-10-29 pyry] 3D textures.
3389*35238bceSAndroid Build Coastguard Worker 
3390*35238bceSAndroid Build Coastguard Worker     const float dstW = float(dst.getWidth());
3391*35238bceSAndroid Build Coastguard Worker     const float dstH = float(dst.getHeight());
3392*35238bceSAndroid Build Coastguard Worker     const float srcW = float(src.getWidth());
3393*35238bceSAndroid Build Coastguard Worker     const float srcH = float(src.getHeight());
3394*35238bceSAndroid Build Coastguard Worker     int numFailed    = 0;
3395*35238bceSAndroid Build Coastguard Worker 
3396*35238bceSAndroid Build Coastguard Worker     // Translation to lookup verification parameters.
3397*35238bceSAndroid Build Coastguard Worker     const tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
3398*35238bceSAndroid Build Coastguard Worker                                tcu::Sampler::LINEAR, tcu::Sampler::LINEAR, 0.0f, false /* non-normalized coords */);
3399*35238bceSAndroid Build Coastguard Worker     tcu::LookupPrecision lookupPrec;
3400*35238bceSAndroid Build Coastguard Worker 
3401*35238bceSAndroid Build Coastguard Worker     lookupPrec.colorThreshold = precision.colorThreshold;
3402*35238bceSAndroid Build Coastguard Worker     lookupPrec.colorMask      = precision.colorMask;
3403*35238bceSAndroid Build Coastguard Worker     lookupPrec.coordBits      = tcu::IVec3(22);
3404*35238bceSAndroid Build Coastguard Worker     lookupPrec.uvwBits        = precision.filterBits;
3405*35238bceSAndroid Build Coastguard Worker 
3406*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < dst.getHeight(); y++)
3407*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < dst.getWidth(); x++)
3408*35238bceSAndroid Build Coastguard Worker         {
3409*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 result = dst.getPixel(x, y);
3410*35238bceSAndroid Build Coastguard Worker             const float cx         = deFloatFloor(float(x) / dstW * srcW) + 1.0f;
3411*35238bceSAndroid Build Coastguard Worker             const float cy         = deFloatFloor(float(y) / dstH * srcH) + 1.0f;
3412*35238bceSAndroid Build Coastguard Worker             const bool isOk = tcu::isLinearSampleResultValid(src, sampler, lookupPrec, tcu::Vec2(cx, cy), 0, result);
3413*35238bceSAndroid Build Coastguard Worker 
3414*35238bceSAndroid Build Coastguard Worker             errorMask.setPixel(isOk ? tcu::RGBA::green().toVec() : tcu::RGBA::red().toVec(), x, y);
3415*35238bceSAndroid Build Coastguard Worker             if (!isOk)
3416*35238bceSAndroid Build Coastguard Worker                 numFailed += 1;
3417*35238bceSAndroid Build Coastguard Worker         }
3418*35238bceSAndroid Build Coastguard Worker 
3419*35238bceSAndroid Build Coastguard Worker     return numFailed;
3420*35238bceSAndroid Build Coastguard Worker }
3421*35238bceSAndroid Build Coastguard Worker 
compareGenMipmapVeryLenient(const tcu::ConstPixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const tcu::PixelBufferAccess & errorMask,const GenMipmapPrecision & precision)3422*35238bceSAndroid Build Coastguard Worker static int compareGenMipmapVeryLenient(const tcu::ConstPixelBufferAccess &dst, const tcu::ConstPixelBufferAccess &src,
3423*35238bceSAndroid Build Coastguard Worker                                        const tcu::PixelBufferAccess &errorMask, const GenMipmapPrecision &precision)
3424*35238bceSAndroid Build Coastguard Worker {
3425*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(dst.getDepth() == 1 && src.getDepth() == 1); // \todo [2013-10-29 pyry] 3D textures.
3426*35238bceSAndroid Build Coastguard Worker     DE_UNREF(precision);
3427*35238bceSAndroid Build Coastguard Worker 
3428*35238bceSAndroid Build Coastguard Worker     const float dstW = float(dst.getWidth());
3429*35238bceSAndroid Build Coastguard Worker     const float dstH = float(dst.getHeight());
3430*35238bceSAndroid Build Coastguard Worker     const float srcW = float(src.getWidth());
3431*35238bceSAndroid Build Coastguard Worker     const float srcH = float(src.getHeight());
3432*35238bceSAndroid Build Coastguard Worker     int numFailed    = 0;
3433*35238bceSAndroid Build Coastguard Worker 
3434*35238bceSAndroid Build Coastguard Worker     for (int y = 0; y < dst.getHeight(); y++)
3435*35238bceSAndroid Build Coastguard Worker         for (int x = 0; x < dst.getWidth(); x++)
3436*35238bceSAndroid Build Coastguard Worker         {
3437*35238bceSAndroid Build Coastguard Worker             const tcu::Vec4 result = dst.getPixel(x, y);
3438*35238bceSAndroid Build Coastguard Worker             const int minX         = deFloorFloatToInt32(((float)x - 0.5f) / dstW * srcW);
3439*35238bceSAndroid Build Coastguard Worker             const int minY         = deFloorFloatToInt32(((float)y - 0.5f) / dstH * srcH);
3440*35238bceSAndroid Build Coastguard Worker             const int maxX         = deCeilFloatToInt32(((float)x + 1.5f) / dstW * srcW);
3441*35238bceSAndroid Build Coastguard Worker             const int maxY         = deCeilFloatToInt32(((float)y + 1.5f) / dstH * srcH);
3442*35238bceSAndroid Build Coastguard Worker             tcu::Vec4 minVal, maxVal;
3443*35238bceSAndroid Build Coastguard Worker             bool isOk;
3444*35238bceSAndroid Build Coastguard Worker 
3445*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(minX < maxX && minY < maxY);
3446*35238bceSAndroid Build Coastguard Worker 
3447*35238bceSAndroid Build Coastguard Worker             for (int ky = minY; ky <= maxY; ky++)
3448*35238bceSAndroid Build Coastguard Worker             {
3449*35238bceSAndroid Build Coastguard Worker                 for (int kx = minX; kx <= maxX; kx++)
3450*35238bceSAndroid Build Coastguard Worker                 {
3451*35238bceSAndroid Build Coastguard Worker                     const int sx           = de::clamp(kx, 0, src.getWidth() - 1);
3452*35238bceSAndroid Build Coastguard Worker                     const int sy           = de::clamp(ky, 0, src.getHeight() - 1);
3453*35238bceSAndroid Build Coastguard Worker                     const tcu::Vec4 sample = src.getPixel(sx, sy);
3454*35238bceSAndroid Build Coastguard Worker 
3455*35238bceSAndroid Build Coastguard Worker                     if (ky == minY && kx == minX)
3456*35238bceSAndroid Build Coastguard Worker                     {
3457*35238bceSAndroid Build Coastguard Worker                         minVal = sample;
3458*35238bceSAndroid Build Coastguard Worker                         maxVal = sample;
3459*35238bceSAndroid Build Coastguard Worker                     }
3460*35238bceSAndroid Build Coastguard Worker                     else
3461*35238bceSAndroid Build Coastguard Worker                     {
3462*35238bceSAndroid Build Coastguard Worker                         minVal = min(sample, minVal);
3463*35238bceSAndroid Build Coastguard Worker                         maxVal = max(sample, maxVal);
3464*35238bceSAndroid Build Coastguard Worker                     }
3465*35238bceSAndroid Build Coastguard Worker                 }
3466*35238bceSAndroid Build Coastguard Worker             }
3467*35238bceSAndroid Build Coastguard Worker 
3468*35238bceSAndroid Build Coastguard Worker             isOk = boolAll(logicalAnd(lessThanEqual(minVal, result), lessThanEqual(result, maxVal)));
3469*35238bceSAndroid Build Coastguard Worker 
3470*35238bceSAndroid Build Coastguard Worker             errorMask.setPixel(isOk ? tcu::RGBA::green().toVec() : tcu::RGBA::red().toVec(), x, y);
3471*35238bceSAndroid Build Coastguard Worker             if (!isOk)
3472*35238bceSAndroid Build Coastguard Worker                 numFailed += 1;
3473*35238bceSAndroid Build Coastguard Worker         }
3474*35238bceSAndroid Build Coastguard Worker 
3475*35238bceSAndroid Build Coastguard Worker     return numFailed;
3476*35238bceSAndroid Build Coastguard Worker }
3477*35238bceSAndroid Build Coastguard Worker 
compareGenMipmapResult(tcu::TestLog & log,const tcu::Texture2D & resultTexture,const tcu::Texture2D & level0Reference,const GenMipmapPrecision & precision)3478*35238bceSAndroid Build Coastguard Worker qpTestResult compareGenMipmapResult(tcu::TestLog &log, const tcu::Texture2D &resultTexture,
3479*35238bceSAndroid Build Coastguard Worker                                     const tcu::Texture2D &level0Reference, const GenMipmapPrecision &precision)
3480*35238bceSAndroid Build Coastguard Worker {
3481*35238bceSAndroid Build Coastguard Worker     qpTestResult result = QP_TEST_RESULT_PASS;
3482*35238bceSAndroid Build Coastguard Worker 
3483*35238bceSAndroid Build Coastguard Worker     // Special comparison for level 0.
3484*35238bceSAndroid Build Coastguard Worker     {
3485*35238bceSAndroid Build Coastguard Worker         const tcu::Vec4 threshold = select(precision.colorThreshold, tcu::Vec4(1.0f), precision.colorMask);
3486*35238bceSAndroid Build Coastguard Worker         const bool level0Ok       = tcu::floatThresholdCompare(log, "Level0", "Level 0", level0Reference.getLevel(0),
3487*35238bceSAndroid Build Coastguard Worker                                                                resultTexture.getLevel(0), threshold, tcu::COMPARE_LOG_RESULT);
3488*35238bceSAndroid Build Coastguard Worker 
3489*35238bceSAndroid Build Coastguard Worker         if (!level0Ok)
3490*35238bceSAndroid Build Coastguard Worker         {
3491*35238bceSAndroid Build Coastguard Worker             log << tcu::TestLog::Message << "ERROR: Level 0 comparison failed!" << tcu::TestLog::EndMessage;
3492*35238bceSAndroid Build Coastguard Worker             result = QP_TEST_RESULT_FAIL;
3493*35238bceSAndroid Build Coastguard Worker         }
3494*35238bceSAndroid Build Coastguard Worker     }
3495*35238bceSAndroid Build Coastguard Worker 
3496*35238bceSAndroid Build Coastguard Worker     for (int levelNdx = 1; levelNdx < resultTexture.getNumLevels(); levelNdx++)
3497*35238bceSAndroid Build Coastguard Worker     {
3498*35238bceSAndroid Build Coastguard Worker         const tcu::ConstPixelBufferAccess src = resultTexture.getLevel(levelNdx - 1);
3499*35238bceSAndroid Build Coastguard Worker         const tcu::ConstPixelBufferAccess dst = resultTexture.getLevel(levelNdx);
3500*35238bceSAndroid Build Coastguard Worker         tcu::Surface errorMask(dst.getWidth(), dst.getHeight());
3501*35238bceSAndroid Build Coastguard Worker         bool levelOk = false;
3502*35238bceSAndroid Build Coastguard Worker 
3503*35238bceSAndroid Build Coastguard Worker         // Try different comparisons in quality order.
3504*35238bceSAndroid Build Coastguard Worker 
3505*35238bceSAndroid Build Coastguard Worker         if (!levelOk)
3506*35238bceSAndroid Build Coastguard Worker         {
3507*35238bceSAndroid Build Coastguard Worker             const int numFailed = compareGenMipmapBilinear(dst, src, errorMask.getAccess(), precision);
3508*35238bceSAndroid Build Coastguard Worker             if (numFailed == 0)
3509*35238bceSAndroid Build Coastguard Worker                 levelOk = true;
3510*35238bceSAndroid Build Coastguard Worker             else
3511*35238bceSAndroid Build Coastguard Worker                 log << tcu::TestLog::Message << "WARNING: Level " << levelNdx
3512*35238bceSAndroid Build Coastguard Worker                     << " comparison to bilinear method failed, found " << numFailed << " invalid pixels."
3513*35238bceSAndroid Build Coastguard Worker                     << tcu::TestLog::EndMessage;
3514*35238bceSAndroid Build Coastguard Worker         }
3515*35238bceSAndroid Build Coastguard Worker 
3516*35238bceSAndroid Build Coastguard Worker         if (!levelOk)
3517*35238bceSAndroid Build Coastguard Worker         {
3518*35238bceSAndroid Build Coastguard Worker             const int numFailed = compareGenMipmapBox(dst, src, errorMask.getAccess(), precision);
3519*35238bceSAndroid Build Coastguard Worker             if (numFailed == 0)
3520*35238bceSAndroid Build Coastguard Worker                 levelOk = true;
3521*35238bceSAndroid Build Coastguard Worker             else
3522*35238bceSAndroid Build Coastguard Worker                 log << tcu::TestLog::Message << "WARNING: Level " << levelNdx
3523*35238bceSAndroid Build Coastguard Worker                     << " comparison to box method failed, found " << numFailed << " invalid pixels."
3524*35238bceSAndroid Build Coastguard Worker                     << tcu::TestLog::EndMessage;
3525*35238bceSAndroid Build Coastguard Worker         }
3526*35238bceSAndroid Build Coastguard Worker 
3527*35238bceSAndroid Build Coastguard Worker         // At this point all high-quality methods have been used.
3528*35238bceSAndroid Build Coastguard Worker         if (!levelOk && result == QP_TEST_RESULT_PASS)
3529*35238bceSAndroid Build Coastguard Worker             result = QP_TEST_RESULT_QUALITY_WARNING;
3530*35238bceSAndroid Build Coastguard Worker 
3531*35238bceSAndroid Build Coastguard Worker         if (!levelOk)
3532*35238bceSAndroid Build Coastguard Worker         {
3533*35238bceSAndroid Build Coastguard Worker             const int numFailed = compareGenMipmapVeryLenient(dst, src, errorMask.getAccess(), precision);
3534*35238bceSAndroid Build Coastguard Worker             if (numFailed == 0)
3535*35238bceSAndroid Build Coastguard Worker                 levelOk = true;
3536*35238bceSAndroid Build Coastguard Worker             else
3537*35238bceSAndroid Build Coastguard Worker                 log << tcu::TestLog::Message << "ERROR: Level " << levelNdx << " appears to contain " << numFailed
3538*35238bceSAndroid Build Coastguard Worker                     << " completely wrong pixels, failing case!" << tcu::TestLog::EndMessage;
3539*35238bceSAndroid Build Coastguard Worker         }
3540*35238bceSAndroid Build Coastguard Worker 
3541*35238bceSAndroid Build Coastguard Worker         if (!levelOk)
3542*35238bceSAndroid Build Coastguard Worker             result = QP_TEST_RESULT_FAIL;
3543*35238bceSAndroid Build Coastguard Worker 
3544*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::ImageSet(string("Level") + de::toString(levelNdx),
3545*35238bceSAndroid Build Coastguard Worker                                       string("Level ") + de::toString(levelNdx) + " result")
3546*35238bceSAndroid Build Coastguard Worker             << tcu::TestLog::Image("Result", "Result", dst);
3547*35238bceSAndroid Build Coastguard Worker 
3548*35238bceSAndroid Build Coastguard Worker         if (!levelOk)
3549*35238bceSAndroid Build Coastguard Worker             log << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
3550*35238bceSAndroid Build Coastguard Worker 
3551*35238bceSAndroid Build Coastguard Worker         log << tcu::TestLog::EndImageSet;
3552*35238bceSAndroid Build Coastguard Worker     }
3553*35238bceSAndroid Build Coastguard Worker 
3554*35238bceSAndroid Build Coastguard Worker     return result;
3555*35238bceSAndroid Build Coastguard Worker }
3556*35238bceSAndroid Build Coastguard Worker 
compareGenMipmapResult(tcu::TestLog & log,const tcu::TextureCube & resultTexture,const tcu::TextureCube & level0Reference,const GenMipmapPrecision & precision)3557*35238bceSAndroid Build Coastguard Worker qpTestResult compareGenMipmapResult(tcu::TestLog &log, const tcu::TextureCube &resultTexture,
3558*35238bceSAndroid Build Coastguard Worker                                     const tcu::TextureCube &level0Reference, const GenMipmapPrecision &precision)
3559*35238bceSAndroid Build Coastguard Worker {
3560*35238bceSAndroid Build Coastguard Worker     qpTestResult result = QP_TEST_RESULT_PASS;
3561*35238bceSAndroid Build Coastguard Worker 
3562*35238bceSAndroid Build Coastguard Worker     static const char *s_faceNames[] = {"-X", "+X", "-Y", "+Y", "-Z", "+Z"};
3563*35238bceSAndroid Build Coastguard Worker     DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_faceNames) == tcu::CUBEFACE_LAST);
3564*35238bceSAndroid Build Coastguard Worker 
3565*35238bceSAndroid Build Coastguard Worker     // Special comparison for level 0.
3566*35238bceSAndroid Build Coastguard Worker     for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
3567*35238bceSAndroid Build Coastguard Worker     {
3568*35238bceSAndroid Build Coastguard Worker         const tcu::CubeFace face  = tcu::CubeFace(faceNdx);
3569*35238bceSAndroid Build Coastguard Worker         const tcu::Vec4 threshold = select(precision.colorThreshold, tcu::Vec4(1.0f), precision.colorMask);
3570*35238bceSAndroid Build Coastguard Worker         const bool level0Ok       = tcu::floatThresholdCompare(
3571*35238bceSAndroid Build Coastguard Worker             log, ("Level0Face" + de::toString(faceNdx)).c_str(), (string("Level 0, face ") + s_faceNames[face]).c_str(),
3572*35238bceSAndroid Build Coastguard Worker             level0Reference.getLevelFace(0, face), resultTexture.getLevelFace(0, face), threshold,
3573*35238bceSAndroid Build Coastguard Worker             tcu::COMPARE_LOG_RESULT);
3574*35238bceSAndroid Build Coastguard Worker 
3575*35238bceSAndroid Build Coastguard Worker         if (!level0Ok)
3576*35238bceSAndroid Build Coastguard Worker         {
3577*35238bceSAndroid Build Coastguard Worker             log << tcu::TestLog::Message << "ERROR: Level 0, face " << s_faceNames[face] << " comparison failed!"
3578*35238bceSAndroid Build Coastguard Worker                 << tcu::TestLog::EndMessage;
3579*35238bceSAndroid Build Coastguard Worker             result = QP_TEST_RESULT_FAIL;
3580*35238bceSAndroid Build Coastguard Worker         }
3581*35238bceSAndroid Build Coastguard Worker     }
3582*35238bceSAndroid Build Coastguard Worker 
3583*35238bceSAndroid Build Coastguard Worker     for (int levelNdx = 1; levelNdx < resultTexture.getNumLevels(); levelNdx++)
3584*35238bceSAndroid Build Coastguard Worker     {
3585*35238bceSAndroid Build Coastguard Worker         for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
3586*35238bceSAndroid Build Coastguard Worker         {
3587*35238bceSAndroid Build Coastguard Worker             const tcu::CubeFace face              = tcu::CubeFace(faceNdx);
3588*35238bceSAndroid Build Coastguard Worker             const char *faceName                  = s_faceNames[face];
3589*35238bceSAndroid Build Coastguard Worker             const tcu::ConstPixelBufferAccess src = resultTexture.getLevelFace(levelNdx - 1, face);
3590*35238bceSAndroid Build Coastguard Worker             const tcu::ConstPixelBufferAccess dst = resultTexture.getLevelFace(levelNdx, face);
3591*35238bceSAndroid Build Coastguard Worker             tcu::Surface errorMask(dst.getWidth(), dst.getHeight());
3592*35238bceSAndroid Build Coastguard Worker             bool levelOk = false;
3593*35238bceSAndroid Build Coastguard Worker 
3594*35238bceSAndroid Build Coastguard Worker             // Try different comparisons in quality order.
3595*35238bceSAndroid Build Coastguard Worker 
3596*35238bceSAndroid Build Coastguard Worker             if (!levelOk)
3597*35238bceSAndroid Build Coastguard Worker             {
3598*35238bceSAndroid Build Coastguard Worker                 const int numFailed = compareGenMipmapBilinear(dst, src, errorMask.getAccess(), precision);
3599*35238bceSAndroid Build Coastguard Worker                 if (numFailed == 0)
3600*35238bceSAndroid Build Coastguard Worker                     levelOk = true;
3601*35238bceSAndroid Build Coastguard Worker                 else
3602*35238bceSAndroid Build Coastguard Worker                     log << tcu::TestLog::Message << "WARNING: Level " << levelNdx << ", face " << faceName
3603*35238bceSAndroid Build Coastguard Worker                         << " comparison to bilinear method failed, found " << numFailed << " invalid pixels."
3604*35238bceSAndroid Build Coastguard Worker                         << tcu::TestLog::EndMessage;
3605*35238bceSAndroid Build Coastguard Worker             }
3606*35238bceSAndroid Build Coastguard Worker 
3607*35238bceSAndroid Build Coastguard Worker             if (!levelOk)
3608*35238bceSAndroid Build Coastguard Worker             {
3609*35238bceSAndroid Build Coastguard Worker                 const int numFailed = compareGenMipmapBox(dst, src, errorMask.getAccess(), precision);
3610*35238bceSAndroid Build Coastguard Worker                 if (numFailed == 0)
3611*35238bceSAndroid Build Coastguard Worker                     levelOk = true;
3612*35238bceSAndroid Build Coastguard Worker                 else
3613*35238bceSAndroid Build Coastguard Worker                     log << tcu::TestLog::Message << "WARNING: Level " << levelNdx << ", face " << faceName
3614*35238bceSAndroid Build Coastguard Worker                         << " comparison to box method failed, found " << numFailed << " invalid pixels."
3615*35238bceSAndroid Build Coastguard Worker                         << tcu::TestLog::EndMessage;
3616*35238bceSAndroid Build Coastguard Worker             }
3617*35238bceSAndroid Build Coastguard Worker 
3618*35238bceSAndroid Build Coastguard Worker             // At this point all high-quality methods have been used.
3619*35238bceSAndroid Build Coastguard Worker             if (!levelOk && result == QP_TEST_RESULT_PASS)
3620*35238bceSAndroid Build Coastguard Worker                 result = QP_TEST_RESULT_QUALITY_WARNING;
3621*35238bceSAndroid Build Coastguard Worker 
3622*35238bceSAndroid Build Coastguard Worker             if (!levelOk)
3623*35238bceSAndroid Build Coastguard Worker             {
3624*35238bceSAndroid Build Coastguard Worker                 const int numFailed = compareGenMipmapVeryLenient(dst, src, errorMask.getAccess(), precision);
3625*35238bceSAndroid Build Coastguard Worker                 if (numFailed == 0)
3626*35238bceSAndroid Build Coastguard Worker                     levelOk = true;
3627*35238bceSAndroid Build Coastguard Worker                 else
3628*35238bceSAndroid Build Coastguard Worker                     log << tcu::TestLog::Message << "ERROR: Level " << levelNdx << ", face " << faceName
3629*35238bceSAndroid Build Coastguard Worker                         << " appears to contain " << numFailed << " completely wrong pixels, failing case!"
3630*35238bceSAndroid Build Coastguard Worker                         << tcu::TestLog::EndMessage;
3631*35238bceSAndroid Build Coastguard Worker             }
3632*35238bceSAndroid Build Coastguard Worker 
3633*35238bceSAndroid Build Coastguard Worker             if (!levelOk)
3634*35238bceSAndroid Build Coastguard Worker                 result = QP_TEST_RESULT_FAIL;
3635*35238bceSAndroid Build Coastguard Worker 
3636*35238bceSAndroid Build Coastguard Worker             log << tcu::TestLog::ImageSet(string("Level") + de::toString(levelNdx) + "Face" + de::toString(faceNdx),
3637*35238bceSAndroid Build Coastguard Worker                                           string("Level ") + de::toString(levelNdx) + ", face " + string(faceName) +
3638*35238bceSAndroid Build Coastguard Worker                                               " result")
3639*35238bceSAndroid Build Coastguard Worker                 << tcu::TestLog::Image("Result", "Result", dst);
3640*35238bceSAndroid Build Coastguard Worker 
3641*35238bceSAndroid Build Coastguard Worker             if (!levelOk)
3642*35238bceSAndroid Build Coastguard Worker                 log << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask);
3643*35238bceSAndroid Build Coastguard Worker 
3644*35238bceSAndroid Build Coastguard Worker             log << tcu::TestLog::EndImageSet;
3645*35238bceSAndroid Build Coastguard Worker         }
3646*35238bceSAndroid Build Coastguard Worker     }
3647*35238bceSAndroid Build Coastguard Worker 
3648*35238bceSAndroid Build Coastguard Worker     return result;
3649*35238bceSAndroid Build Coastguard Worker }
3650*35238bceSAndroid Build Coastguard Worker 
3651*35238bceSAndroid Build Coastguard Worker // Logging utilities.
3652*35238bceSAndroid Build Coastguard Worker 
operator <<(std::ostream & str,const LogGradientFmt & fmt)3653*35238bceSAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &str, const LogGradientFmt &fmt)
3654*35238bceSAndroid Build Coastguard Worker {
3655*35238bceSAndroid Build Coastguard Worker     return str << "(R: " << fmt.valueMin->x() << " -> " << fmt.valueMax->x() << ", "
3656*35238bceSAndroid Build Coastguard Worker                << "G: " << fmt.valueMin->y() << " -> " << fmt.valueMax->y() << ", "
3657*35238bceSAndroid Build Coastguard Worker                << "B: " << fmt.valueMin->z() << " -> " << fmt.valueMax->z() << ", "
3658*35238bceSAndroid Build Coastguard Worker                << "A: " << fmt.valueMin->w() << " -> " << fmt.valueMax->w() << ")";
3659*35238bceSAndroid Build Coastguard Worker }
3660*35238bceSAndroid Build Coastguard Worker 
3661*35238bceSAndroid Build Coastguard Worker } // namespace TextureTestUtil
3662*35238bceSAndroid Build Coastguard Worker } // namespace glu
3663