xref: /aosp_15_r20/external/deqp/modules/gles31/functional/es31fShaderPackingFunctionTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 3.1 Module
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Floating-point packing and unpacking function tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es31fShaderPackingFunctionTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "glsShaderExecUtil.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "tcuFormatUtil.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuFloat.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
31*35238bceSAndroid Build Coastguard Worker #include "deString.h"
32*35238bceSAndroid Build Coastguard Worker 
33*35238bceSAndroid Build Coastguard Worker namespace deqp
34*35238bceSAndroid Build Coastguard Worker {
35*35238bceSAndroid Build Coastguard Worker namespace gles31
36*35238bceSAndroid Build Coastguard Worker {
37*35238bceSAndroid Build Coastguard Worker namespace Functional
38*35238bceSAndroid Build Coastguard Worker {
39*35238bceSAndroid Build Coastguard Worker 
40*35238bceSAndroid Build Coastguard Worker using std::string;
41*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
42*35238bceSAndroid Build Coastguard Worker using namespace gls::ShaderExecUtil;
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker namespace
45*35238bceSAndroid Build Coastguard Worker {
46*35238bceSAndroid Build Coastguard Worker 
getUlpDiff(float a,float b)47*35238bceSAndroid Build Coastguard Worker inline uint32_t getUlpDiff(float a, float b)
48*35238bceSAndroid Build Coastguard Worker {
49*35238bceSAndroid Build Coastguard Worker     const uint32_t aBits = tcu::Float32(a).bits();
50*35238bceSAndroid Build Coastguard Worker     const uint32_t bBits = tcu::Float32(b).bits();
51*35238bceSAndroid Build Coastguard Worker     return aBits > bBits ? aBits - bBits : bBits - aBits;
52*35238bceSAndroid Build Coastguard Worker }
53*35238bceSAndroid Build Coastguard Worker 
54*35238bceSAndroid Build Coastguard Worker struct HexFloat
55*35238bceSAndroid Build Coastguard Worker {
56*35238bceSAndroid Build Coastguard Worker     const float value;
HexFloatdeqp::gles31::Functional::__anonf0671f880111::HexFloat57*35238bceSAndroid Build Coastguard Worker     HexFloat(const float value_) : value(value_)
58*35238bceSAndroid Build Coastguard Worker     {
59*35238bceSAndroid Build Coastguard Worker     }
60*35238bceSAndroid Build Coastguard Worker };
61*35238bceSAndroid Build Coastguard Worker 
operator <<(std::ostream & str,const HexFloat & v)62*35238bceSAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &str, const HexFloat &v)
63*35238bceSAndroid Build Coastguard Worker {
64*35238bceSAndroid Build Coastguard Worker     return str << v.value << " / " << tcu::toHex(tcu::Float32(v.value).bits());
65*35238bceSAndroid Build Coastguard Worker }
66*35238bceSAndroid Build Coastguard Worker 
67*35238bceSAndroid Build Coastguard Worker } // namespace
68*35238bceSAndroid Build Coastguard Worker 
69*35238bceSAndroid Build Coastguard Worker // ShaderPackingFunctionCase
70*35238bceSAndroid Build Coastguard Worker 
71*35238bceSAndroid Build Coastguard Worker class ShaderPackingFunctionCase : public TestCase
72*35238bceSAndroid Build Coastguard Worker {
73*35238bceSAndroid Build Coastguard Worker public:
74*35238bceSAndroid Build Coastguard Worker     ShaderPackingFunctionCase(Context &context, const char *name, const char *description, glu::ShaderType shaderType);
75*35238bceSAndroid Build Coastguard Worker     ~ShaderPackingFunctionCase(void);
76*35238bceSAndroid Build Coastguard Worker 
77*35238bceSAndroid Build Coastguard Worker     void init(void);
78*35238bceSAndroid Build Coastguard Worker     void deinit(void);
79*35238bceSAndroid Build Coastguard Worker 
80*35238bceSAndroid Build Coastguard Worker protected:
81*35238bceSAndroid Build Coastguard Worker     glu::ShaderType m_shaderType;
82*35238bceSAndroid Build Coastguard Worker     ShaderSpec m_spec;
83*35238bceSAndroid Build Coastguard Worker     ShaderExecutor *m_executor;
84*35238bceSAndroid Build Coastguard Worker 
85*35238bceSAndroid Build Coastguard Worker private:
86*35238bceSAndroid Build Coastguard Worker     ShaderPackingFunctionCase(const ShaderPackingFunctionCase &other);
87*35238bceSAndroid Build Coastguard Worker     ShaderPackingFunctionCase &operator=(const ShaderPackingFunctionCase &other);
88*35238bceSAndroid Build Coastguard Worker };
89*35238bceSAndroid Build Coastguard Worker 
ShaderPackingFunctionCase(Context & context,const char * name,const char * description,glu::ShaderType shaderType)90*35238bceSAndroid Build Coastguard Worker ShaderPackingFunctionCase::ShaderPackingFunctionCase(Context &context, const char *name, const char *description,
91*35238bceSAndroid Build Coastguard Worker                                                      glu::ShaderType shaderType)
92*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, description)
93*35238bceSAndroid Build Coastguard Worker     , m_shaderType(shaderType)
94*35238bceSAndroid Build Coastguard Worker     , m_executor(DE_NULL)
95*35238bceSAndroid Build Coastguard Worker {
96*35238bceSAndroid Build Coastguard Worker     m_spec.version = glu::getContextTypeGLSLVersion(context.getRenderContext().getType());
97*35238bceSAndroid Build Coastguard Worker }
98*35238bceSAndroid Build Coastguard Worker 
~ShaderPackingFunctionCase(void)99*35238bceSAndroid Build Coastguard Worker ShaderPackingFunctionCase::~ShaderPackingFunctionCase(void)
100*35238bceSAndroid Build Coastguard Worker {
101*35238bceSAndroid Build Coastguard Worker     ShaderPackingFunctionCase::deinit();
102*35238bceSAndroid Build Coastguard Worker }
103*35238bceSAndroid Build Coastguard Worker 
init(void)104*35238bceSAndroid Build Coastguard Worker void ShaderPackingFunctionCase::init(void)
105*35238bceSAndroid Build Coastguard Worker {
106*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_executor);
107*35238bceSAndroid Build Coastguard Worker 
108*35238bceSAndroid Build Coastguard Worker     m_executor = createExecutor(m_context.getRenderContext(), m_shaderType, m_spec);
109*35238bceSAndroid Build Coastguard Worker     m_testCtx.getLog() << m_executor;
110*35238bceSAndroid Build Coastguard Worker 
111*35238bceSAndroid Build Coastguard Worker     if (!m_executor->isOk())
112*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("Compile failed");
113*35238bceSAndroid Build Coastguard Worker }
114*35238bceSAndroid Build Coastguard Worker 
deinit(void)115*35238bceSAndroid Build Coastguard Worker void ShaderPackingFunctionCase::deinit(void)
116*35238bceSAndroid Build Coastguard Worker {
117*35238bceSAndroid Build Coastguard Worker     delete m_executor;
118*35238bceSAndroid Build Coastguard Worker     m_executor = DE_NULL;
119*35238bceSAndroid Build Coastguard Worker }
120*35238bceSAndroid Build Coastguard Worker 
121*35238bceSAndroid Build Coastguard Worker // Test cases
122*35238bceSAndroid Build Coastguard Worker 
123*35238bceSAndroid Build Coastguard Worker class PackSnorm2x16Case : public ShaderPackingFunctionCase
124*35238bceSAndroid Build Coastguard Worker {
125*35238bceSAndroid Build Coastguard Worker public:
PackSnorm2x16Case(Context & context,glu::ShaderType shaderType,glu::Precision precision)126*35238bceSAndroid Build Coastguard Worker     PackSnorm2x16Case(Context &context, glu::ShaderType shaderType, glu::Precision precision)
127*35238bceSAndroid Build Coastguard Worker         : ShaderPackingFunctionCase(
128*35238bceSAndroid Build Coastguard Worker               context,
129*35238bceSAndroid Build Coastguard Worker               (string("packsnorm2x16") + getPrecisionPostfix(precision) + getShaderTypePostfix(shaderType)).c_str(),
130*35238bceSAndroid Build Coastguard Worker               "packSnorm2x16", shaderType)
131*35238bceSAndroid Build Coastguard Worker         , m_precision(precision)
132*35238bceSAndroid Build Coastguard Worker     {
133*35238bceSAndroid Build Coastguard Worker         m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_FLOAT_VEC2, precision)));
134*35238bceSAndroid Build Coastguard Worker         m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
135*35238bceSAndroid Build Coastguard Worker 
136*35238bceSAndroid Build Coastguard Worker         m_spec.source = "out0 = packSnorm2x16(in0);";
137*35238bceSAndroid Build Coastguard Worker     }
138*35238bceSAndroid Build Coastguard Worker 
iterate(void)139*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
140*35238bceSAndroid Build Coastguard Worker     {
141*35238bceSAndroid Build Coastguard Worker         de::Random rnd(deStringHash(getName()) ^ 0x776002);
142*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::Vec2> inputs;
143*35238bceSAndroid Build Coastguard Worker         std::vector<uint32_t> outputs;
144*35238bceSAndroid Build Coastguard Worker         const int                    maxDiff = m_precision == glu::PRECISION_HIGHP    ? 1        : // Rounding only.
145*35238bceSAndroid Build Coastguard Worker                                                   m_precision == glu::PRECISION_MEDIUMP    ? 33    : // (2^-10) * (2^15) + 1
146*35238bceSAndroid Build Coastguard Worker                                                   m_precision == glu::PRECISION_LOWP    ? 129    : 0;    // (2^-8) * (2^15) + 1
147*35238bceSAndroid Build Coastguard Worker 
148*35238bceSAndroid Build Coastguard Worker         // Special values to check.
149*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec2(0.0f, 0.0f));
150*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec2(-1.0f, 1.0f));
151*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec2(0.5f, -0.5f));
152*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec2(-1.5f, 1.5f));
153*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec2(0.25f, -0.75f));
154*35238bceSAndroid Build Coastguard Worker 
155*35238bceSAndroid Build Coastguard Worker         // Random values, mostly in range.
156*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < 15; ndx++)
157*35238bceSAndroid Build Coastguard Worker         {
158*35238bceSAndroid Build Coastguard Worker             const float x = rnd.getFloat() * 2.5f - 1.25f;
159*35238bceSAndroid Build Coastguard Worker             const float y = rnd.getFloat() * 2.5f - 1.25f;
160*35238bceSAndroid Build Coastguard Worker             inputs.push_back(tcu::Vec2(x, y));
161*35238bceSAndroid Build Coastguard Worker         }
162*35238bceSAndroid Build Coastguard Worker 
163*35238bceSAndroid Build Coastguard Worker         // Large random values.
164*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < 80; ndx++)
165*35238bceSAndroid Build Coastguard Worker         {
166*35238bceSAndroid Build Coastguard Worker             const float x = rnd.getFloat() * 1e6f - 0.5e6f;
167*35238bceSAndroid Build Coastguard Worker             const float y = rnd.getFloat() * 1e6f - 0.5e6f;
168*35238bceSAndroid Build Coastguard Worker             inputs.push_back(tcu::Vec2(x, y));
169*35238bceSAndroid Build Coastguard Worker         }
170*35238bceSAndroid Build Coastguard Worker 
171*35238bceSAndroid Build Coastguard Worker         outputs.resize(inputs.size());
172*35238bceSAndroid Build Coastguard Worker 
173*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values"
174*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
175*35238bceSAndroid Build Coastguard Worker 
176*35238bceSAndroid Build Coastguard Worker         {
177*35238bceSAndroid Build Coastguard Worker             const void *in = &inputs[0];
178*35238bceSAndroid Build Coastguard Worker             void *out      = &outputs[0];
179*35238bceSAndroid Build Coastguard Worker 
180*35238bceSAndroid Build Coastguard Worker             m_executor->useProgram();
181*35238bceSAndroid Build Coastguard Worker             m_executor->execute((int)inputs.size(), &in, &out);
182*35238bceSAndroid Build Coastguard Worker         }
183*35238bceSAndroid Build Coastguard Worker 
184*35238bceSAndroid Build Coastguard Worker         // Verify
185*35238bceSAndroid Build Coastguard Worker         {
186*35238bceSAndroid Build Coastguard Worker             const int numValues = (int)inputs.size();
187*35238bceSAndroid Build Coastguard Worker             const int maxPrints = 10;
188*35238bceSAndroid Build Coastguard Worker             int numFailed       = 0;
189*35238bceSAndroid Build Coastguard Worker 
190*35238bceSAndroid Build Coastguard Worker             for (int valNdx = 0; valNdx < numValues; valNdx++)
191*35238bceSAndroid Build Coastguard Worker             {
192*35238bceSAndroid Build Coastguard Worker                 const uint16_t ref0 =
193*35238bceSAndroid Build Coastguard Worker                     (uint16_t)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].x(), -1.0f, 1.0f) * 32767.0f),
194*35238bceSAndroid Build Coastguard Worker                                         -(1 << 15), (1 << 15) - 1);
195*35238bceSAndroid Build Coastguard Worker                 const uint16_t ref1 =
196*35238bceSAndroid Build Coastguard Worker                     (uint16_t)de::clamp(deRoundFloatToInt32(de::clamp(inputs[valNdx].y(), -1.0f, 1.0f) * 32767.0f),
197*35238bceSAndroid Build Coastguard Worker                                         -(1 << 15), (1 << 15) - 1);
198*35238bceSAndroid Build Coastguard Worker                 const uint32_t ref  = (ref1 << 16) | ref0;
199*35238bceSAndroid Build Coastguard Worker                 const uint32_t res  = outputs[valNdx];
200*35238bceSAndroid Build Coastguard Worker                 const uint16_t res0 = (uint16_t)(res & 0xffff);
201*35238bceSAndroid Build Coastguard Worker                 const uint16_t res1 = (uint16_t)(res >> 16);
202*35238bceSAndroid Build Coastguard Worker                 const int diff0     = de::abs((int)ref0 - (int)res0);
203*35238bceSAndroid Build Coastguard Worker                 const int diff1     = de::abs((int)ref1 - (int)res1);
204*35238bceSAndroid Build Coastguard Worker 
205*35238bceSAndroid Build Coastguard Worker                 if (diff0 > maxDiff || diff1 > maxDiff)
206*35238bceSAndroid Build Coastguard Worker                 {
207*35238bceSAndroid Build Coastguard Worker                     if (numFailed < maxPrints)
208*35238bceSAndroid Build Coastguard Worker                     {
209*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx
210*35238bceSAndroid Build Coastguard Worker                                            << ", expected packSnorm2x16(" << inputs[valNdx] << ") = " << tcu::toHex(ref)
211*35238bceSAndroid Build Coastguard Worker                                            << ", got " << tcu::toHex(res) << "\n  diffs = (" << diff0 << ", " << diff1
212*35238bceSAndroid Build Coastguard Worker                                            << "), max diff = " << maxDiff << TestLog::EndMessage;
213*35238bceSAndroid Build Coastguard Worker                     }
214*35238bceSAndroid Build Coastguard Worker                     else if (numFailed == maxPrints)
215*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
216*35238bceSAndroid Build Coastguard Worker 
217*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
218*35238bceSAndroid Build Coastguard Worker                 }
219*35238bceSAndroid Build Coastguard Worker             }
220*35238bceSAndroid Build Coastguard Worker 
221*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed"
222*35238bceSAndroid Build Coastguard Worker                                << TestLog::EndMessage;
223*35238bceSAndroid Build Coastguard Worker 
224*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
225*35238bceSAndroid Build Coastguard Worker                                     numFailed == 0 ? "Pass" : "Result comparison failed");
226*35238bceSAndroid Build Coastguard Worker         }
227*35238bceSAndroid Build Coastguard Worker 
228*35238bceSAndroid Build Coastguard Worker         return STOP;
229*35238bceSAndroid Build Coastguard Worker     }
230*35238bceSAndroid Build Coastguard Worker 
231*35238bceSAndroid Build Coastguard Worker private:
232*35238bceSAndroid Build Coastguard Worker     glu::Precision m_precision;
233*35238bceSAndroid Build Coastguard Worker };
234*35238bceSAndroid Build Coastguard Worker 
235*35238bceSAndroid Build Coastguard Worker class UnpackSnorm2x16Case : public ShaderPackingFunctionCase
236*35238bceSAndroid Build Coastguard Worker {
237*35238bceSAndroid Build Coastguard Worker public:
UnpackSnorm2x16Case(Context & context,glu::ShaderType shaderType)238*35238bceSAndroid Build Coastguard Worker     UnpackSnorm2x16Case(Context &context, glu::ShaderType shaderType)
239*35238bceSAndroid Build Coastguard Worker         : ShaderPackingFunctionCase(context, (string("unpacksnorm2x16") + getShaderTypePostfix(shaderType)).c_str(),
240*35238bceSAndroid Build Coastguard Worker                                     "unpackSnorm2x16", shaderType)
241*35238bceSAndroid Build Coastguard Worker     {
242*35238bceSAndroid Build Coastguard Worker         m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
243*35238bceSAndroid Build Coastguard Worker         m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
244*35238bceSAndroid Build Coastguard Worker 
245*35238bceSAndroid Build Coastguard Worker         m_spec.source = "out0 = unpackSnorm2x16(in0);";
246*35238bceSAndroid Build Coastguard Worker     }
247*35238bceSAndroid Build Coastguard Worker 
iterate(void)248*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
249*35238bceSAndroid Build Coastguard Worker     {
250*35238bceSAndroid Build Coastguard Worker         const uint32_t maxDiff = 1; // Rounding error.
251*35238bceSAndroid Build Coastguard Worker         de::Random rnd(deStringHash(getName()) ^ 0x776002);
252*35238bceSAndroid Build Coastguard Worker         std::vector<uint32_t> inputs;
253*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::Vec2> outputs;
254*35238bceSAndroid Build Coastguard Worker 
255*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x00000000u);
256*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x7fff8000u);
257*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x80007fffu);
258*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0xffffffffu);
259*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x0001fffeu);
260*35238bceSAndroid Build Coastguard Worker 
261*35238bceSAndroid Build Coastguard Worker         // Random values.
262*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < 95; ndx++)
263*35238bceSAndroid Build Coastguard Worker             inputs.push_back(rnd.getUint32());
264*35238bceSAndroid Build Coastguard Worker 
265*35238bceSAndroid Build Coastguard Worker         outputs.resize(inputs.size());
266*35238bceSAndroid Build Coastguard Worker 
267*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values"
268*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
269*35238bceSAndroid Build Coastguard Worker 
270*35238bceSAndroid Build Coastguard Worker         {
271*35238bceSAndroid Build Coastguard Worker             const void *in = &inputs[0];
272*35238bceSAndroid Build Coastguard Worker             void *out      = &outputs[0];
273*35238bceSAndroid Build Coastguard Worker 
274*35238bceSAndroid Build Coastguard Worker             m_executor->useProgram();
275*35238bceSAndroid Build Coastguard Worker             m_executor->execute((int)inputs.size(), &in, &out);
276*35238bceSAndroid Build Coastguard Worker         }
277*35238bceSAndroid Build Coastguard Worker 
278*35238bceSAndroid Build Coastguard Worker         // Verify
279*35238bceSAndroid Build Coastguard Worker         {
280*35238bceSAndroid Build Coastguard Worker             const int numValues = (int)inputs.size();
281*35238bceSAndroid Build Coastguard Worker             const int maxPrints = 10;
282*35238bceSAndroid Build Coastguard Worker             int numFailed       = 0;
283*35238bceSAndroid Build Coastguard Worker 
284*35238bceSAndroid Build Coastguard Worker             for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
285*35238bceSAndroid Build Coastguard Worker             {
286*35238bceSAndroid Build Coastguard Worker                 const int16_t in0 = (int16_t)(uint16_t)(inputs[valNdx] & 0xffff);
287*35238bceSAndroid Build Coastguard Worker                 const int16_t in1 = (int16_t)(uint16_t)(inputs[valNdx] >> 16);
288*35238bceSAndroid Build Coastguard Worker                 const float ref0  = de::clamp(float(in0) / 32767.f, -1.0f, 1.0f);
289*35238bceSAndroid Build Coastguard Worker                 const float ref1  = de::clamp(float(in1) / 32767.f, -1.0f, 1.0f);
290*35238bceSAndroid Build Coastguard Worker                 const float res0  = outputs[valNdx].x();
291*35238bceSAndroid Build Coastguard Worker                 const float res1  = outputs[valNdx].y();
292*35238bceSAndroid Build Coastguard Worker 
293*35238bceSAndroid Build Coastguard Worker                 const uint32_t diff0 = getUlpDiff(ref0, res0);
294*35238bceSAndroid Build Coastguard Worker                 const uint32_t diff1 = getUlpDiff(ref1, res1);
295*35238bceSAndroid Build Coastguard Worker 
296*35238bceSAndroid Build Coastguard Worker                 if (diff0 > maxDiff || diff1 > maxDiff)
297*35238bceSAndroid Build Coastguard Worker                 {
298*35238bceSAndroid Build Coastguard Worker                     if (numFailed < maxPrints)
299*35238bceSAndroid Build Coastguard Worker                     {
300*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ",\n"
301*35238bceSAndroid Build Coastguard Worker                                            << "  expected unpackSnorm2x16(" << tcu::toHex(inputs[valNdx]) << ") = "
302*35238bceSAndroid Build Coastguard Worker                                            << "vec2(" << HexFloat(ref0) << ", " << HexFloat(ref1) << ")"
303*35238bceSAndroid Build Coastguard Worker                                            << ", got vec2(" << HexFloat(res0) << ", " << HexFloat(res1) << ")"
304*35238bceSAndroid Build Coastguard Worker                                            << "\n  ULP diffs = (" << diff0 << ", " << diff1
305*35238bceSAndroid Build Coastguard Worker                                            << "), max diff = " << maxDiff << TestLog::EndMessage;
306*35238bceSAndroid Build Coastguard Worker                     }
307*35238bceSAndroid Build Coastguard Worker                     else if (numFailed == maxPrints)
308*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
309*35238bceSAndroid Build Coastguard Worker 
310*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
311*35238bceSAndroid Build Coastguard Worker                 }
312*35238bceSAndroid Build Coastguard Worker             }
313*35238bceSAndroid Build Coastguard Worker 
314*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed"
315*35238bceSAndroid Build Coastguard Worker                                << TestLog::EndMessage;
316*35238bceSAndroid Build Coastguard Worker 
317*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
318*35238bceSAndroid Build Coastguard Worker                                     numFailed == 0 ? "Pass" : "Result comparison failed");
319*35238bceSAndroid Build Coastguard Worker         }
320*35238bceSAndroid Build Coastguard Worker 
321*35238bceSAndroid Build Coastguard Worker         return STOP;
322*35238bceSAndroid Build Coastguard Worker     }
323*35238bceSAndroid Build Coastguard Worker };
324*35238bceSAndroid Build Coastguard Worker 
325*35238bceSAndroid Build Coastguard Worker class PackUnorm2x16Case : public ShaderPackingFunctionCase
326*35238bceSAndroid Build Coastguard Worker {
327*35238bceSAndroid Build Coastguard Worker public:
PackUnorm2x16Case(Context & context,glu::ShaderType shaderType,glu::Precision precision)328*35238bceSAndroid Build Coastguard Worker     PackUnorm2x16Case(Context &context, glu::ShaderType shaderType, glu::Precision precision)
329*35238bceSAndroid Build Coastguard Worker         : ShaderPackingFunctionCase(
330*35238bceSAndroid Build Coastguard Worker               context,
331*35238bceSAndroid Build Coastguard Worker               (string("packunorm2x16") + getPrecisionPostfix(precision) + getShaderTypePostfix(shaderType)).c_str(),
332*35238bceSAndroid Build Coastguard Worker               "packUnorm2x16", shaderType)
333*35238bceSAndroid Build Coastguard Worker         , m_precision(precision)
334*35238bceSAndroid Build Coastguard Worker     {
335*35238bceSAndroid Build Coastguard Worker         m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_FLOAT_VEC2, precision)));
336*35238bceSAndroid Build Coastguard Worker         m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
337*35238bceSAndroid Build Coastguard Worker 
338*35238bceSAndroid Build Coastguard Worker         m_spec.source = "out0 = packUnorm2x16(in0);";
339*35238bceSAndroid Build Coastguard Worker     }
340*35238bceSAndroid Build Coastguard Worker 
iterate(void)341*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
342*35238bceSAndroid Build Coastguard Worker     {
343*35238bceSAndroid Build Coastguard Worker         de::Random rnd(deStringHash(getName()) ^ 0x776002);
344*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::Vec2> inputs;
345*35238bceSAndroid Build Coastguard Worker         std::vector<uint32_t> outputs;
346*35238bceSAndroid Build Coastguard Worker         const int                    maxDiff = m_precision == glu::PRECISION_HIGHP    ? 1        : // Rounding only.
347*35238bceSAndroid Build Coastguard Worker                                                   m_precision == glu::PRECISION_MEDIUMP    ? 65    : // (2^-10) * (2^16) + 1
348*35238bceSAndroid Build Coastguard Worker                                                   m_precision == glu::PRECISION_LOWP    ? 257    : 0;    // (2^-8) * (2^16) + 1
349*35238bceSAndroid Build Coastguard Worker 
350*35238bceSAndroid Build Coastguard Worker         // Special values to check.
351*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec2(0.0f, 0.0f));
352*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec2(0.5f, 1.0f));
353*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec2(1.0f, 0.5f));
354*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec2(-0.5f, 1.5f));
355*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec2(0.25f, 0.75f));
356*35238bceSAndroid Build Coastguard Worker 
357*35238bceSAndroid Build Coastguard Worker         // Random values, mostly in range.
358*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < 15; ndx++)
359*35238bceSAndroid Build Coastguard Worker         {
360*35238bceSAndroid Build Coastguard Worker             const float x = rnd.getFloat() * 1.25f;
361*35238bceSAndroid Build Coastguard Worker             const float y = rnd.getFloat() * 1.25f;
362*35238bceSAndroid Build Coastguard Worker             inputs.push_back(tcu::Vec2(x, y));
363*35238bceSAndroid Build Coastguard Worker         }
364*35238bceSAndroid Build Coastguard Worker 
365*35238bceSAndroid Build Coastguard Worker         // Large random values.
366*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < 80; ndx++)
367*35238bceSAndroid Build Coastguard Worker         {
368*35238bceSAndroid Build Coastguard Worker             const float x = rnd.getFloat() * 1e6f - 1e5f;
369*35238bceSAndroid Build Coastguard Worker             const float y = rnd.getFloat() * 1e6f - 1e5f;
370*35238bceSAndroid Build Coastguard Worker             inputs.push_back(tcu::Vec2(x, y));
371*35238bceSAndroid Build Coastguard Worker         }
372*35238bceSAndroid Build Coastguard Worker 
373*35238bceSAndroid Build Coastguard Worker         outputs.resize(inputs.size());
374*35238bceSAndroid Build Coastguard Worker 
375*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values"
376*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
377*35238bceSAndroid Build Coastguard Worker 
378*35238bceSAndroid Build Coastguard Worker         {
379*35238bceSAndroid Build Coastguard Worker             const void *in = &inputs[0];
380*35238bceSAndroid Build Coastguard Worker             void *out      = &outputs[0];
381*35238bceSAndroid Build Coastguard Worker 
382*35238bceSAndroid Build Coastguard Worker             m_executor->useProgram();
383*35238bceSAndroid Build Coastguard Worker             m_executor->execute((int)inputs.size(), &in, &out);
384*35238bceSAndroid Build Coastguard Worker         }
385*35238bceSAndroid Build Coastguard Worker 
386*35238bceSAndroid Build Coastguard Worker         // Verify
387*35238bceSAndroid Build Coastguard Worker         {
388*35238bceSAndroid Build Coastguard Worker             const int numValues = (int)inputs.size();
389*35238bceSAndroid Build Coastguard Worker             const int maxPrints = 10;
390*35238bceSAndroid Build Coastguard Worker             int numFailed       = 0;
391*35238bceSAndroid Build Coastguard Worker 
392*35238bceSAndroid Build Coastguard Worker             for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
393*35238bceSAndroid Build Coastguard Worker             {
394*35238bceSAndroid Build Coastguard Worker                 const uint16_t ref0 = (uint16_t)de::clamp(
395*35238bceSAndroid Build Coastguard Worker                     deRoundFloatToInt32(de::clamp(inputs[valNdx].x(), 0.0f, 1.0f) * 65535.0f), 0, (1 << 16) - 1);
396*35238bceSAndroid Build Coastguard Worker                 const uint16_t ref1 = (uint16_t)de::clamp(
397*35238bceSAndroid Build Coastguard Worker                     deRoundFloatToInt32(de::clamp(inputs[valNdx].y(), 0.0f, 1.0f) * 65535.0f), 0, (1 << 16) - 1);
398*35238bceSAndroid Build Coastguard Worker                 const uint32_t ref  = (ref1 << 16) | ref0;
399*35238bceSAndroid Build Coastguard Worker                 const uint32_t res  = outputs[valNdx];
400*35238bceSAndroid Build Coastguard Worker                 const uint16_t res0 = (uint16_t)(res & 0xffff);
401*35238bceSAndroid Build Coastguard Worker                 const uint16_t res1 = (uint16_t)(res >> 16);
402*35238bceSAndroid Build Coastguard Worker                 const int diff0     = de::abs((int)ref0 - (int)res0);
403*35238bceSAndroid Build Coastguard Worker                 const int diff1     = de::abs((int)ref1 - (int)res1);
404*35238bceSAndroid Build Coastguard Worker 
405*35238bceSAndroid Build Coastguard Worker                 if (diff0 > maxDiff || diff1 > maxDiff)
406*35238bceSAndroid Build Coastguard Worker                 {
407*35238bceSAndroid Build Coastguard Worker                     if (numFailed < maxPrints)
408*35238bceSAndroid Build Coastguard Worker                     {
409*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx
410*35238bceSAndroid Build Coastguard Worker                                            << ", expected packUnorm2x16(" << inputs[valNdx] << ") = " << tcu::toHex(ref)
411*35238bceSAndroid Build Coastguard Worker                                            << ", got " << tcu::toHex(res) << "\n  diffs = (" << diff0 << ", " << diff1
412*35238bceSAndroid Build Coastguard Worker                                            << "), max diff = " << maxDiff << TestLog::EndMessage;
413*35238bceSAndroid Build Coastguard Worker                     }
414*35238bceSAndroid Build Coastguard Worker                     else if (numFailed == maxPrints)
415*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
416*35238bceSAndroid Build Coastguard Worker 
417*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
418*35238bceSAndroid Build Coastguard Worker                 }
419*35238bceSAndroid Build Coastguard Worker             }
420*35238bceSAndroid Build Coastguard Worker 
421*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed"
422*35238bceSAndroid Build Coastguard Worker                                << TestLog::EndMessage;
423*35238bceSAndroid Build Coastguard Worker 
424*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
425*35238bceSAndroid Build Coastguard Worker                                     numFailed == 0 ? "Pass" : "Result comparison failed");
426*35238bceSAndroid Build Coastguard Worker         }
427*35238bceSAndroid Build Coastguard Worker 
428*35238bceSAndroid Build Coastguard Worker         return STOP;
429*35238bceSAndroid Build Coastguard Worker     }
430*35238bceSAndroid Build Coastguard Worker 
431*35238bceSAndroid Build Coastguard Worker private:
432*35238bceSAndroid Build Coastguard Worker     glu::Precision m_precision;
433*35238bceSAndroid Build Coastguard Worker };
434*35238bceSAndroid Build Coastguard Worker 
435*35238bceSAndroid Build Coastguard Worker class UnpackUnorm2x16Case : public ShaderPackingFunctionCase
436*35238bceSAndroid Build Coastguard Worker {
437*35238bceSAndroid Build Coastguard Worker public:
UnpackUnorm2x16Case(Context & context,glu::ShaderType shaderType)438*35238bceSAndroid Build Coastguard Worker     UnpackUnorm2x16Case(Context &context, glu::ShaderType shaderType)
439*35238bceSAndroid Build Coastguard Worker         : ShaderPackingFunctionCase(context, (string("unpackunorm2x16") + getShaderTypePostfix(shaderType)).c_str(),
440*35238bceSAndroid Build Coastguard Worker                                     "unpackUnorm2x16", shaderType)
441*35238bceSAndroid Build Coastguard Worker     {
442*35238bceSAndroid Build Coastguard Worker         m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
443*35238bceSAndroid Build Coastguard Worker         m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
444*35238bceSAndroid Build Coastguard Worker 
445*35238bceSAndroid Build Coastguard Worker         m_spec.source = "out0 = unpackUnorm2x16(in0);";
446*35238bceSAndroid Build Coastguard Worker     }
447*35238bceSAndroid Build Coastguard Worker 
iterate(void)448*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
449*35238bceSAndroid Build Coastguard Worker     {
450*35238bceSAndroid Build Coastguard Worker         const uint32_t maxDiff = 1; // Rounding error.
451*35238bceSAndroid Build Coastguard Worker         de::Random rnd(deStringHash(getName()) ^ 0x776002);
452*35238bceSAndroid Build Coastguard Worker         std::vector<uint32_t> inputs;
453*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::Vec2> outputs;
454*35238bceSAndroid Build Coastguard Worker 
455*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x00000000u);
456*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x7fff8000u);
457*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x80007fffu);
458*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0xffffffffu);
459*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x0001fffeu);
460*35238bceSAndroid Build Coastguard Worker 
461*35238bceSAndroid Build Coastguard Worker         // Random values.
462*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < 95; ndx++)
463*35238bceSAndroid Build Coastguard Worker             inputs.push_back(rnd.getUint32());
464*35238bceSAndroid Build Coastguard Worker 
465*35238bceSAndroid Build Coastguard Worker         outputs.resize(inputs.size());
466*35238bceSAndroid Build Coastguard Worker 
467*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values"
468*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
469*35238bceSAndroid Build Coastguard Worker 
470*35238bceSAndroid Build Coastguard Worker         {
471*35238bceSAndroid Build Coastguard Worker             const void *in = &inputs[0];
472*35238bceSAndroid Build Coastguard Worker             void *out      = &outputs[0];
473*35238bceSAndroid Build Coastguard Worker 
474*35238bceSAndroid Build Coastguard Worker             m_executor->useProgram();
475*35238bceSAndroid Build Coastguard Worker             m_executor->execute((int)inputs.size(), &in, &out);
476*35238bceSAndroid Build Coastguard Worker         }
477*35238bceSAndroid Build Coastguard Worker 
478*35238bceSAndroid Build Coastguard Worker         // Verify
479*35238bceSAndroid Build Coastguard Worker         {
480*35238bceSAndroid Build Coastguard Worker             const int numValues = (int)inputs.size();
481*35238bceSAndroid Build Coastguard Worker             const int maxPrints = 10;
482*35238bceSAndroid Build Coastguard Worker             int numFailed       = 0;
483*35238bceSAndroid Build Coastguard Worker 
484*35238bceSAndroid Build Coastguard Worker             for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
485*35238bceSAndroid Build Coastguard Worker             {
486*35238bceSAndroid Build Coastguard Worker                 const uint16_t in0 = (uint16_t)(inputs[valNdx] & 0xffff);
487*35238bceSAndroid Build Coastguard Worker                 const uint16_t in1 = (uint16_t)(inputs[valNdx] >> 16);
488*35238bceSAndroid Build Coastguard Worker                 const float ref0   = float(in0) / 65535.0f;
489*35238bceSAndroid Build Coastguard Worker                 const float ref1   = float(in1) / 65535.0f;
490*35238bceSAndroid Build Coastguard Worker                 const float res0   = outputs[valNdx].x();
491*35238bceSAndroid Build Coastguard Worker                 const float res1   = outputs[valNdx].y();
492*35238bceSAndroid Build Coastguard Worker 
493*35238bceSAndroid Build Coastguard Worker                 const uint32_t diff0 = getUlpDiff(ref0, res0);
494*35238bceSAndroid Build Coastguard Worker                 const uint32_t diff1 = getUlpDiff(ref1, res1);
495*35238bceSAndroid Build Coastguard Worker 
496*35238bceSAndroid Build Coastguard Worker                 if (diff0 > maxDiff || diff1 > maxDiff)
497*35238bceSAndroid Build Coastguard Worker                 {
498*35238bceSAndroid Build Coastguard Worker                     if (numFailed < maxPrints)
499*35238bceSAndroid Build Coastguard Worker                     {
500*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ",\n"
501*35238bceSAndroid Build Coastguard Worker                                            << "  expected unpackUnorm2x16(" << tcu::toHex(inputs[valNdx]) << ") = "
502*35238bceSAndroid Build Coastguard Worker                                            << "vec2(" << HexFloat(ref0) << ", " << HexFloat(ref1) << ")"
503*35238bceSAndroid Build Coastguard Worker                                            << ", got vec2(" << HexFloat(res0) << ", " << HexFloat(res1) << ")"
504*35238bceSAndroid Build Coastguard Worker                                            << "\n  ULP diffs = (" << diff0 << ", " << diff1
505*35238bceSAndroid Build Coastguard Worker                                            << "), max diff = " << maxDiff << TestLog::EndMessage;
506*35238bceSAndroid Build Coastguard Worker                     }
507*35238bceSAndroid Build Coastguard Worker                     else if (numFailed == maxPrints)
508*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
509*35238bceSAndroid Build Coastguard Worker 
510*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
511*35238bceSAndroid Build Coastguard Worker                 }
512*35238bceSAndroid Build Coastguard Worker             }
513*35238bceSAndroid Build Coastguard Worker 
514*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed"
515*35238bceSAndroid Build Coastguard Worker                                << TestLog::EndMessage;
516*35238bceSAndroid Build Coastguard Worker 
517*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
518*35238bceSAndroid Build Coastguard Worker                                     numFailed == 0 ? "Pass" : "Result comparison failed");
519*35238bceSAndroid Build Coastguard Worker         }
520*35238bceSAndroid Build Coastguard Worker 
521*35238bceSAndroid Build Coastguard Worker         return STOP;
522*35238bceSAndroid Build Coastguard Worker     }
523*35238bceSAndroid Build Coastguard Worker };
524*35238bceSAndroid Build Coastguard Worker 
525*35238bceSAndroid Build Coastguard Worker class PackHalf2x16Case : public ShaderPackingFunctionCase
526*35238bceSAndroid Build Coastguard Worker {
527*35238bceSAndroid Build Coastguard Worker public:
PackHalf2x16Case(Context & context,glu::ShaderType shaderType)528*35238bceSAndroid Build Coastguard Worker     PackHalf2x16Case(Context &context, glu::ShaderType shaderType)
529*35238bceSAndroid Build Coastguard Worker         : ShaderPackingFunctionCase(context, (string("packhalf2x16") + getShaderTypePostfix(shaderType)).c_str(),
530*35238bceSAndroid Build Coastguard Worker                                     "packHalf2x16", shaderType)
531*35238bceSAndroid Build Coastguard Worker     {
532*35238bceSAndroid Build Coastguard Worker         m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
533*35238bceSAndroid Build Coastguard Worker         m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
534*35238bceSAndroid Build Coastguard Worker 
535*35238bceSAndroid Build Coastguard Worker         m_spec.source = "out0 = packHalf2x16(in0);";
536*35238bceSAndroid Build Coastguard Worker     }
537*35238bceSAndroid Build Coastguard Worker 
iterate(void)538*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
539*35238bceSAndroid Build Coastguard Worker     {
540*35238bceSAndroid Build Coastguard Worker         const int maxDiff = 0; // Values can be represented exactly in mediump.
541*35238bceSAndroid Build Coastguard Worker         de::Random rnd(deStringHash(getName()) ^ 0x776002);
542*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::Vec2> inputs;
543*35238bceSAndroid Build Coastguard Worker         std::vector<uint32_t> outputs;
544*35238bceSAndroid Build Coastguard Worker 
545*35238bceSAndroid Build Coastguard Worker         // Special values to check.
546*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec2(0.0f, 0.0f));
547*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec2(0.5f, 1.0f));
548*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec2(1.0f, 0.5f));
549*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec2(-0.5f, 1.5f));
550*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec2(0.25f, 0.75f));
551*35238bceSAndroid Build Coastguard Worker 
552*35238bceSAndroid Build Coastguard Worker         // Random values.
553*35238bceSAndroid Build Coastguard Worker         {
554*35238bceSAndroid Build Coastguard Worker             const int minExp = -14;
555*35238bceSAndroid Build Coastguard Worker             const int maxExp = 15;
556*35238bceSAndroid Build Coastguard Worker 
557*35238bceSAndroid Build Coastguard Worker             for (int ndx = 0; ndx < 95; ndx++)
558*35238bceSAndroid Build Coastguard Worker             {
559*35238bceSAndroid Build Coastguard Worker                 tcu::Vec2 v;
560*35238bceSAndroid Build Coastguard Worker                 for (int c = 0; c < 2; c++)
561*35238bceSAndroid Build Coastguard Worker                 {
562*35238bceSAndroid Build Coastguard Worker                     const int s             = rnd.getBool() ? 1 : -1;
563*35238bceSAndroid Build Coastguard Worker                     const int exp           = rnd.getInt(minExp, maxExp);
564*35238bceSAndroid Build Coastguard Worker                     const uint32_t mantissa = rnd.getUint32() & ((1 << 23) - 1);
565*35238bceSAndroid Build Coastguard Worker 
566*35238bceSAndroid Build Coastguard Worker                     v[c] = tcu::Float32::construct(s, exp ? exp : 1 /* avoid denormals */, (1u << 23) | mantissa)
567*35238bceSAndroid Build Coastguard Worker                                .asFloat();
568*35238bceSAndroid Build Coastguard Worker                 }
569*35238bceSAndroid Build Coastguard Worker                 inputs.push_back(v);
570*35238bceSAndroid Build Coastguard Worker             }
571*35238bceSAndroid Build Coastguard Worker         }
572*35238bceSAndroid Build Coastguard Worker 
573*35238bceSAndroid Build Coastguard Worker         // Convert input values to fp16 and back to make sure they can be represented exactly in mediump.
574*35238bceSAndroid Build Coastguard Worker         for (std::vector<tcu::Vec2>::iterator inVal = inputs.begin(); inVal != inputs.end(); ++inVal)
575*35238bceSAndroid Build Coastguard Worker             *inVal = tcu::Vec2(tcu::Float16(inVal->x()).asFloat(), tcu::Float16(inVal->y()).asFloat());
576*35238bceSAndroid Build Coastguard Worker 
577*35238bceSAndroid Build Coastguard Worker         outputs.resize(inputs.size());
578*35238bceSAndroid Build Coastguard Worker 
579*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values"
580*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
581*35238bceSAndroid Build Coastguard Worker 
582*35238bceSAndroid Build Coastguard Worker         {
583*35238bceSAndroid Build Coastguard Worker             const void *in = &inputs[0];
584*35238bceSAndroid Build Coastguard Worker             void *out      = &outputs[0];
585*35238bceSAndroid Build Coastguard Worker 
586*35238bceSAndroid Build Coastguard Worker             m_executor->useProgram();
587*35238bceSAndroid Build Coastguard Worker             m_executor->execute((int)inputs.size(), &in, &out);
588*35238bceSAndroid Build Coastguard Worker         }
589*35238bceSAndroid Build Coastguard Worker 
590*35238bceSAndroid Build Coastguard Worker         // Verify
591*35238bceSAndroid Build Coastguard Worker         {
592*35238bceSAndroid Build Coastguard Worker             const int numValues = (int)inputs.size();
593*35238bceSAndroid Build Coastguard Worker             const int maxPrints = 10;
594*35238bceSAndroid Build Coastguard Worker             int numFailed       = 0;
595*35238bceSAndroid Build Coastguard Worker 
596*35238bceSAndroid Build Coastguard Worker             for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
597*35238bceSAndroid Build Coastguard Worker             {
598*35238bceSAndroid Build Coastguard Worker                 const uint16_t ref0 = (uint16_t)tcu::Float16(inputs[valNdx].x()).bits();
599*35238bceSAndroid Build Coastguard Worker                 const uint16_t ref1 = (uint16_t)tcu::Float16(inputs[valNdx].y()).bits();
600*35238bceSAndroid Build Coastguard Worker                 const uint32_t ref  = (ref1 << 16) | ref0;
601*35238bceSAndroid Build Coastguard Worker                 const uint32_t res  = outputs[valNdx];
602*35238bceSAndroid Build Coastguard Worker                 const uint16_t res0 = (uint16_t)(res & 0xffff);
603*35238bceSAndroid Build Coastguard Worker                 const uint16_t res1 = (uint16_t)(res >> 16);
604*35238bceSAndroid Build Coastguard Worker                 const int diff0     = de::abs((int)ref0 - (int)res0);
605*35238bceSAndroid Build Coastguard Worker                 const int diff1     = de::abs((int)ref1 - (int)res1);
606*35238bceSAndroid Build Coastguard Worker 
607*35238bceSAndroid Build Coastguard Worker                 if (diff0 > maxDiff || diff1 > maxDiff)
608*35238bceSAndroid Build Coastguard Worker                 {
609*35238bceSAndroid Build Coastguard Worker                     if (numFailed < maxPrints)
610*35238bceSAndroid Build Coastguard Worker                     {
611*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx
612*35238bceSAndroid Build Coastguard Worker                                            << ", expected packHalf2x16(" << inputs[valNdx] << ") = " << tcu::toHex(ref)
613*35238bceSAndroid Build Coastguard Worker                                            << ", got " << tcu::toHex(res) << "\n  diffs = (" << diff0 << ", " << diff1
614*35238bceSAndroid Build Coastguard Worker                                            << "), max diff = " << maxDiff << TestLog::EndMessage;
615*35238bceSAndroid Build Coastguard Worker                     }
616*35238bceSAndroid Build Coastguard Worker                     else if (numFailed == maxPrints)
617*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
618*35238bceSAndroid Build Coastguard Worker 
619*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
620*35238bceSAndroid Build Coastguard Worker                 }
621*35238bceSAndroid Build Coastguard Worker             }
622*35238bceSAndroid Build Coastguard Worker 
623*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed"
624*35238bceSAndroid Build Coastguard Worker                                << TestLog::EndMessage;
625*35238bceSAndroid Build Coastguard Worker 
626*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
627*35238bceSAndroid Build Coastguard Worker                                     numFailed == 0 ? "Pass" : "Result comparison failed");
628*35238bceSAndroid Build Coastguard Worker         }
629*35238bceSAndroid Build Coastguard Worker 
630*35238bceSAndroid Build Coastguard Worker         return STOP;
631*35238bceSAndroid Build Coastguard Worker     }
632*35238bceSAndroid Build Coastguard Worker };
633*35238bceSAndroid Build Coastguard Worker 
634*35238bceSAndroid Build Coastguard Worker class UnpackHalf2x16Case : public ShaderPackingFunctionCase
635*35238bceSAndroid Build Coastguard Worker {
636*35238bceSAndroid Build Coastguard Worker public:
UnpackHalf2x16Case(Context & context,glu::ShaderType shaderType)637*35238bceSAndroid Build Coastguard Worker     UnpackHalf2x16Case(Context &context, glu::ShaderType shaderType)
638*35238bceSAndroid Build Coastguard Worker         : ShaderPackingFunctionCase(context, (string("unpackhalf2x16") + getShaderTypePostfix(shaderType)).c_str(),
639*35238bceSAndroid Build Coastguard Worker                                     "unpackHalf2x16", shaderType)
640*35238bceSAndroid Build Coastguard Worker     {
641*35238bceSAndroid Build Coastguard Worker         m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
642*35238bceSAndroid Build Coastguard Worker         m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_MEDIUMP)));
643*35238bceSAndroid Build Coastguard Worker 
644*35238bceSAndroid Build Coastguard Worker         m_spec.source = "out0 = unpackHalf2x16(in0);";
645*35238bceSAndroid Build Coastguard Worker     }
646*35238bceSAndroid Build Coastguard Worker 
iterate(void)647*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
648*35238bceSAndroid Build Coastguard Worker     {
649*35238bceSAndroid Build Coastguard Worker         const int maxDiff = 0; // All bits must be accurate.
650*35238bceSAndroid Build Coastguard Worker         de::Random rnd(deStringHash(getName()) ^ 0x776002);
651*35238bceSAndroid Build Coastguard Worker         std::vector<uint32_t> inputs;
652*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::Vec2> outputs;
653*35238bceSAndroid Build Coastguard Worker 
654*35238bceSAndroid Build Coastguard Worker         // Special values.
655*35238bceSAndroid Build Coastguard Worker         inputs.push_back((tcu::Float16(0.0f).bits() << 16) | tcu::Float16(1.0f).bits());
656*35238bceSAndroid Build Coastguard Worker         inputs.push_back((tcu::Float16(1.0f).bits() << 16) | tcu::Float16(0.0f).bits());
657*35238bceSAndroid Build Coastguard Worker         inputs.push_back((tcu::Float16(-1.0f).bits() << 16) | tcu::Float16(0.5f).bits());
658*35238bceSAndroid Build Coastguard Worker         inputs.push_back((tcu::Float16(0.5f).bits() << 16) | tcu::Float16(-0.5f).bits());
659*35238bceSAndroid Build Coastguard Worker 
660*35238bceSAndroid Build Coastguard Worker         // Construct random values.
661*35238bceSAndroid Build Coastguard Worker         {
662*35238bceSAndroid Build Coastguard Worker             const int minExp   = -14;
663*35238bceSAndroid Build Coastguard Worker             const int maxExp   = 15;
664*35238bceSAndroid Build Coastguard Worker             const int mantBits = 10;
665*35238bceSAndroid Build Coastguard Worker 
666*35238bceSAndroid Build Coastguard Worker             for (int ndx = 0; ndx < 96; ndx++)
667*35238bceSAndroid Build Coastguard Worker             {
668*35238bceSAndroid Build Coastguard Worker                 uint32_t inVal = 0;
669*35238bceSAndroid Build Coastguard Worker                 for (int c = 0; c < 2; c++)
670*35238bceSAndroid Build Coastguard Worker                 {
671*35238bceSAndroid Build Coastguard Worker                     const int s             = rnd.getBool() ? 1 : -1;
672*35238bceSAndroid Build Coastguard Worker                     const int exp           = rnd.getInt(minExp, maxExp);
673*35238bceSAndroid Build Coastguard Worker                     const uint32_t mantissa = rnd.getUint32() & ((1 << mantBits) - 1);
674*35238bceSAndroid Build Coastguard Worker                     const uint16_t value =
675*35238bceSAndroid Build Coastguard Worker                         tcu::Float16::construct(s, exp ? exp : 1 /* avoid denorm */, (uint16_t)((1u << 10) | mantissa))
676*35238bceSAndroid Build Coastguard Worker                             .bits();
677*35238bceSAndroid Build Coastguard Worker 
678*35238bceSAndroid Build Coastguard Worker                     inVal |= value << (16 * c);
679*35238bceSAndroid Build Coastguard Worker                 }
680*35238bceSAndroid Build Coastguard Worker                 inputs.push_back(inVal);
681*35238bceSAndroid Build Coastguard Worker             }
682*35238bceSAndroid Build Coastguard Worker         }
683*35238bceSAndroid Build Coastguard Worker 
684*35238bceSAndroid Build Coastguard Worker         outputs.resize(inputs.size());
685*35238bceSAndroid Build Coastguard Worker 
686*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values"
687*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
688*35238bceSAndroid Build Coastguard Worker 
689*35238bceSAndroid Build Coastguard Worker         {
690*35238bceSAndroid Build Coastguard Worker             const void *in = &inputs[0];
691*35238bceSAndroid Build Coastguard Worker             void *out      = &outputs[0];
692*35238bceSAndroid Build Coastguard Worker 
693*35238bceSAndroid Build Coastguard Worker             m_executor->useProgram();
694*35238bceSAndroid Build Coastguard Worker             m_executor->execute((int)inputs.size(), &in, &out);
695*35238bceSAndroid Build Coastguard Worker         }
696*35238bceSAndroid Build Coastguard Worker 
697*35238bceSAndroid Build Coastguard Worker         // Verify
698*35238bceSAndroid Build Coastguard Worker         {
699*35238bceSAndroid Build Coastguard Worker             const int numValues = (int)inputs.size();
700*35238bceSAndroid Build Coastguard Worker             const int maxPrints = 10;
701*35238bceSAndroid Build Coastguard Worker             int numFailed       = 0;
702*35238bceSAndroid Build Coastguard Worker 
703*35238bceSAndroid Build Coastguard Worker             for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
704*35238bceSAndroid Build Coastguard Worker             {
705*35238bceSAndroid Build Coastguard Worker                 const uint16_t in0 = (uint16_t)(inputs[valNdx] & 0xffff);
706*35238bceSAndroid Build Coastguard Worker                 const uint16_t in1 = (uint16_t)(inputs[valNdx] >> 16);
707*35238bceSAndroid Build Coastguard Worker                 const float ref0   = tcu::Float16(in0).asFloat();
708*35238bceSAndroid Build Coastguard Worker                 const float ref1   = tcu::Float16(in1).asFloat();
709*35238bceSAndroid Build Coastguard Worker                 const float res0   = outputs[valNdx].x();
710*35238bceSAndroid Build Coastguard Worker                 const float res1   = outputs[valNdx].y();
711*35238bceSAndroid Build Coastguard Worker 
712*35238bceSAndroid Build Coastguard Worker                 const uint32_t refBits0 = tcu::Float32(ref0).bits();
713*35238bceSAndroid Build Coastguard Worker                 const uint32_t refBits1 = tcu::Float32(ref1).bits();
714*35238bceSAndroid Build Coastguard Worker                 const uint32_t resBits0 = tcu::Float32(res0).bits();
715*35238bceSAndroid Build Coastguard Worker                 const uint32_t resBits1 = tcu::Float32(res1).bits();
716*35238bceSAndroid Build Coastguard Worker 
717*35238bceSAndroid Build Coastguard Worker                 const int diff0 = de::abs((int)refBits0 - (int)resBits0);
718*35238bceSAndroid Build Coastguard Worker                 const int diff1 = de::abs((int)refBits1 - (int)resBits1);
719*35238bceSAndroid Build Coastguard Worker 
720*35238bceSAndroid Build Coastguard Worker                 if (diff0 > maxDiff || diff1 > maxDiff)
721*35238bceSAndroid Build Coastguard Worker                 {
722*35238bceSAndroid Build Coastguard Worker                     if (numFailed < maxPrints)
723*35238bceSAndroid Build Coastguard Worker                     {
724*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ",\n"
725*35238bceSAndroid Build Coastguard Worker                                            << "  expected unpackHalf2x16(" << tcu::toHex(inputs[valNdx]) << ") = "
726*35238bceSAndroid Build Coastguard Worker                                            << "vec2(" << ref0 << " / " << tcu::toHex(refBits0) << ", " << ref1 << " / "
727*35238bceSAndroid Build Coastguard Worker                                            << tcu::toHex(refBits1) << ")"
728*35238bceSAndroid Build Coastguard Worker                                            << ", got vec2(" << res0 << " / " << tcu::toHex(resBits0) << ", " << res1
729*35238bceSAndroid Build Coastguard Worker                                            << " / " << tcu::toHex(resBits1) << ")"
730*35238bceSAndroid Build Coastguard Worker                                            << "\n  ULP diffs = (" << diff0 << ", " << diff1
731*35238bceSAndroid Build Coastguard Worker                                            << "), max diff = " << maxDiff << TestLog::EndMessage;
732*35238bceSAndroid Build Coastguard Worker                     }
733*35238bceSAndroid Build Coastguard Worker                     else if (numFailed == maxPrints)
734*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
735*35238bceSAndroid Build Coastguard Worker 
736*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
737*35238bceSAndroid Build Coastguard Worker                 }
738*35238bceSAndroid Build Coastguard Worker             }
739*35238bceSAndroid Build Coastguard Worker 
740*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed"
741*35238bceSAndroid Build Coastguard Worker                                << TestLog::EndMessage;
742*35238bceSAndroid Build Coastguard Worker 
743*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
744*35238bceSAndroid Build Coastguard Worker                                     numFailed == 0 ? "Pass" : "Result comparison failed");
745*35238bceSAndroid Build Coastguard Worker         }
746*35238bceSAndroid Build Coastguard Worker 
747*35238bceSAndroid Build Coastguard Worker         return STOP;
748*35238bceSAndroid Build Coastguard Worker     }
749*35238bceSAndroid Build Coastguard Worker };
750*35238bceSAndroid Build Coastguard Worker 
751*35238bceSAndroid Build Coastguard Worker class PackSnorm4x8Case : public ShaderPackingFunctionCase
752*35238bceSAndroid Build Coastguard Worker {
753*35238bceSAndroid Build Coastguard Worker public:
PackSnorm4x8Case(Context & context,glu::ShaderType shaderType,glu::Precision precision)754*35238bceSAndroid Build Coastguard Worker     PackSnorm4x8Case(Context &context, glu::ShaderType shaderType, glu::Precision precision)
755*35238bceSAndroid Build Coastguard Worker         : ShaderPackingFunctionCase(
756*35238bceSAndroid Build Coastguard Worker               context,
757*35238bceSAndroid Build Coastguard Worker               (string("packsnorm4x8") + getPrecisionPostfix(precision) + getShaderTypePostfix(shaderType)).c_str(),
758*35238bceSAndroid Build Coastguard Worker               "packSnorm4x8", shaderType)
759*35238bceSAndroid Build Coastguard Worker         , m_precision(precision)
760*35238bceSAndroid Build Coastguard Worker     {
761*35238bceSAndroid Build Coastguard Worker         m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_FLOAT_VEC4, precision)));
762*35238bceSAndroid Build Coastguard Worker         m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
763*35238bceSAndroid Build Coastguard Worker 
764*35238bceSAndroid Build Coastguard Worker         m_spec.source = "out0 = packSnorm4x8(in0);";
765*35238bceSAndroid Build Coastguard Worker     }
766*35238bceSAndroid Build Coastguard Worker 
iterate(void)767*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
768*35238bceSAndroid Build Coastguard Worker     {
769*35238bceSAndroid Build Coastguard Worker         de::Random rnd(deStringHash(getName()) ^ 0x42f2c0);
770*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::Vec4> inputs;
771*35238bceSAndroid Build Coastguard Worker         std::vector<uint32_t> outputs;
772*35238bceSAndroid Build Coastguard Worker         const int                    maxDiff = m_precision == glu::PRECISION_HIGHP    ? 1    : // Rounding only.
773*35238bceSAndroid Build Coastguard Worker                                                   m_precision == glu::PRECISION_MEDIUMP    ? 1    : // (2^-10) * (2^7) + 1
774*35238bceSAndroid Build Coastguard Worker                                                   m_precision == glu::PRECISION_LOWP    ? 2    : 0;    // (2^-8) * (2^7) + 1
775*35238bceSAndroid Build Coastguard Worker 
776*35238bceSAndroid Build Coastguard Worker         // Special values to check.
777*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
778*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec4(-1.0f, 1.0f, -1.0f, 1.0f));
779*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec4(0.5f, -0.5f, -0.5f, 0.5f));
780*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec4(-1.5f, 1.5f, -1.5f, 1.5f));
781*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec4(0.25f, -0.75f, -0.25f, 0.75f));
782*35238bceSAndroid Build Coastguard Worker 
783*35238bceSAndroid Build Coastguard Worker         // Random values, mostly in range.
784*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < 15; ndx++)
785*35238bceSAndroid Build Coastguard Worker         {
786*35238bceSAndroid Build Coastguard Worker             const float x = rnd.getFloat() * 2.5f - 1.25f;
787*35238bceSAndroid Build Coastguard Worker             const float y = rnd.getFloat() * 2.5f - 1.25f;
788*35238bceSAndroid Build Coastguard Worker             const float z = rnd.getFloat() * 2.5f - 1.25f;
789*35238bceSAndroid Build Coastguard Worker             const float w = rnd.getFloat() * 2.5f - 1.25f;
790*35238bceSAndroid Build Coastguard Worker             inputs.push_back(tcu::Vec4(x, y, z, w));
791*35238bceSAndroid Build Coastguard Worker         }
792*35238bceSAndroid Build Coastguard Worker 
793*35238bceSAndroid Build Coastguard Worker         // Large random values.
794*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < 80; ndx++)
795*35238bceSAndroid Build Coastguard Worker         {
796*35238bceSAndroid Build Coastguard Worker             const float x = rnd.getFloat() * 1e6f - 0.5e6f;
797*35238bceSAndroid Build Coastguard Worker             const float y = rnd.getFloat() * 1e6f - 0.5e6f;
798*35238bceSAndroid Build Coastguard Worker             const float z = rnd.getFloat() * 1e6f - 0.5e6f;
799*35238bceSAndroid Build Coastguard Worker             const float w = rnd.getFloat() * 1e6f - 0.5e6f;
800*35238bceSAndroid Build Coastguard Worker             inputs.push_back(tcu::Vec4(x, y, z, w));
801*35238bceSAndroid Build Coastguard Worker         }
802*35238bceSAndroid Build Coastguard Worker 
803*35238bceSAndroid Build Coastguard Worker         outputs.resize(inputs.size());
804*35238bceSAndroid Build Coastguard Worker 
805*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values"
806*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
807*35238bceSAndroid Build Coastguard Worker 
808*35238bceSAndroid Build Coastguard Worker         {
809*35238bceSAndroid Build Coastguard Worker             const void *in = &inputs[0];
810*35238bceSAndroid Build Coastguard Worker             void *out      = &outputs[0];
811*35238bceSAndroid Build Coastguard Worker 
812*35238bceSAndroid Build Coastguard Worker             m_executor->useProgram();
813*35238bceSAndroid Build Coastguard Worker             m_executor->execute((int)inputs.size(), &in, &out);
814*35238bceSAndroid Build Coastguard Worker         }
815*35238bceSAndroid Build Coastguard Worker 
816*35238bceSAndroid Build Coastguard Worker         // Verify
817*35238bceSAndroid Build Coastguard Worker         {
818*35238bceSAndroid Build Coastguard Worker             const int numValues = (int)inputs.size();
819*35238bceSAndroid Build Coastguard Worker             const int maxPrints = 10;
820*35238bceSAndroid Build Coastguard Worker             int numFailed       = 0;
821*35238bceSAndroid Build Coastguard Worker 
822*35238bceSAndroid Build Coastguard Worker             for (int valNdx = 0; valNdx < numValues; valNdx++)
823*35238bceSAndroid Build Coastguard Worker             {
824*35238bceSAndroid Build Coastguard Worker                 const uint16_t ref0 = (uint8_t)de::clamp(
825*35238bceSAndroid Build Coastguard Worker                     deRoundFloatToInt32(de::clamp(inputs[valNdx].x(), -1.0f, 1.0f) * 127.0f), -(1 << 7), (1 << 7) - 1);
826*35238bceSAndroid Build Coastguard Worker                 const uint16_t ref1 = (uint8_t)de::clamp(
827*35238bceSAndroid Build Coastguard Worker                     deRoundFloatToInt32(de::clamp(inputs[valNdx].y(), -1.0f, 1.0f) * 127.0f), -(1 << 7), (1 << 7) - 1);
828*35238bceSAndroid Build Coastguard Worker                 const uint16_t ref2 = (uint8_t)de::clamp(
829*35238bceSAndroid Build Coastguard Worker                     deRoundFloatToInt32(de::clamp(inputs[valNdx].z(), -1.0f, 1.0f) * 127.0f), -(1 << 7), (1 << 7) - 1);
830*35238bceSAndroid Build Coastguard Worker                 const uint16_t ref3 = (uint8_t)de::clamp(
831*35238bceSAndroid Build Coastguard Worker                     deRoundFloatToInt32(de::clamp(inputs[valNdx].w(), -1.0f, 1.0f) * 127.0f), -(1 << 7), (1 << 7) - 1);
832*35238bceSAndroid Build Coastguard Worker                 const uint32_t ref =
833*35238bceSAndroid Build Coastguard Worker                     (uint32_t(ref3) << 24) | (uint32_t(ref2) << 16) | (uint32_t(ref1) << 8) | uint32_t(ref0);
834*35238bceSAndroid Build Coastguard Worker                 const uint32_t res  = outputs[valNdx];
835*35238bceSAndroid Build Coastguard Worker                 const uint16_t res0 = (uint8_t)(res & 0xff);
836*35238bceSAndroid Build Coastguard Worker                 const uint16_t res1 = (uint8_t)((res >> 8) & 0xff);
837*35238bceSAndroid Build Coastguard Worker                 const uint16_t res2 = (uint8_t)((res >> 16) & 0xff);
838*35238bceSAndroid Build Coastguard Worker                 const uint16_t res3 = (uint8_t)((res >> 24) & 0xff);
839*35238bceSAndroid Build Coastguard Worker                 const int diff0     = de::abs((int)ref0 - (int)res0);
840*35238bceSAndroid Build Coastguard Worker                 const int diff1     = de::abs((int)ref1 - (int)res1);
841*35238bceSAndroid Build Coastguard Worker                 const int diff2     = de::abs((int)ref2 - (int)res2);
842*35238bceSAndroid Build Coastguard Worker                 const int diff3     = de::abs((int)ref3 - (int)res3);
843*35238bceSAndroid Build Coastguard Worker 
844*35238bceSAndroid Build Coastguard Worker                 if (diff0 > maxDiff || diff1 > maxDiff || diff2 > maxDiff || diff3 > maxDiff)
845*35238bceSAndroid Build Coastguard Worker                 {
846*35238bceSAndroid Build Coastguard Worker                     if (numFailed < maxPrints)
847*35238bceSAndroid Build Coastguard Worker                     {
848*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog()
849*35238bceSAndroid Build Coastguard Worker                             << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ", expected packSnorm4x8("
850*35238bceSAndroid Build Coastguard Worker                             << inputs[valNdx] << ") = " << tcu::toHex(ref) << ", got " << tcu::toHex(res)
851*35238bceSAndroid Build Coastguard Worker                             << "\n  diffs = " << tcu::IVec4(diff0, diff1, diff2, diff3) << ", max diff = " << maxDiff
852*35238bceSAndroid Build Coastguard Worker                             << TestLog::EndMessage;
853*35238bceSAndroid Build Coastguard Worker                     }
854*35238bceSAndroid Build Coastguard Worker                     else if (numFailed == maxPrints)
855*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
856*35238bceSAndroid Build Coastguard Worker 
857*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
858*35238bceSAndroid Build Coastguard Worker                 }
859*35238bceSAndroid Build Coastguard Worker             }
860*35238bceSAndroid Build Coastguard Worker 
861*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed"
862*35238bceSAndroid Build Coastguard Worker                                << TestLog::EndMessage;
863*35238bceSAndroid Build Coastguard Worker 
864*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
865*35238bceSAndroid Build Coastguard Worker                                     numFailed == 0 ? "Pass" : "Result comparison failed");
866*35238bceSAndroid Build Coastguard Worker         }
867*35238bceSAndroid Build Coastguard Worker 
868*35238bceSAndroid Build Coastguard Worker         return STOP;
869*35238bceSAndroid Build Coastguard Worker     }
870*35238bceSAndroid Build Coastguard Worker 
871*35238bceSAndroid Build Coastguard Worker private:
872*35238bceSAndroid Build Coastguard Worker     glu::Precision m_precision;
873*35238bceSAndroid Build Coastguard Worker };
874*35238bceSAndroid Build Coastguard Worker 
875*35238bceSAndroid Build Coastguard Worker class UnpackSnorm4x8Case : public ShaderPackingFunctionCase
876*35238bceSAndroid Build Coastguard Worker {
877*35238bceSAndroid Build Coastguard Worker public:
UnpackSnorm4x8Case(Context & context,glu::ShaderType shaderType)878*35238bceSAndroid Build Coastguard Worker     UnpackSnorm4x8Case(Context &context, glu::ShaderType shaderType)
879*35238bceSAndroid Build Coastguard Worker         : ShaderPackingFunctionCase(context, (string("unpacksnorm4x8") + getShaderTypePostfix(shaderType)).c_str(),
880*35238bceSAndroid Build Coastguard Worker                                     "unpackSnorm4x8", shaderType)
881*35238bceSAndroid Build Coastguard Worker     {
882*35238bceSAndroid Build Coastguard Worker         m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
883*35238bceSAndroid Build Coastguard Worker         m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
884*35238bceSAndroid Build Coastguard Worker 
885*35238bceSAndroid Build Coastguard Worker         m_spec.source = "out0 = unpackSnorm4x8(in0);";
886*35238bceSAndroid Build Coastguard Worker     }
887*35238bceSAndroid Build Coastguard Worker 
iterate(void)888*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
889*35238bceSAndroid Build Coastguard Worker     {
890*35238bceSAndroid Build Coastguard Worker         const uint32_t maxDiff = 1; // Rounding error.
891*35238bceSAndroid Build Coastguard Worker         de::Random rnd(deStringHash(getName()) ^ 0x776002);
892*35238bceSAndroid Build Coastguard Worker         std::vector<uint32_t> inputs;
893*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::Vec4> outputs;
894*35238bceSAndroid Build Coastguard Worker 
895*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x00000000u);
896*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x7fff8000u);
897*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x80007fffu);
898*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0xffffffffu);
899*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x0001fffeu);
900*35238bceSAndroid Build Coastguard Worker 
901*35238bceSAndroid Build Coastguard Worker         // Random values.
902*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < 95; ndx++)
903*35238bceSAndroid Build Coastguard Worker             inputs.push_back(rnd.getUint32());
904*35238bceSAndroid Build Coastguard Worker 
905*35238bceSAndroid Build Coastguard Worker         outputs.resize(inputs.size());
906*35238bceSAndroid Build Coastguard Worker 
907*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values"
908*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
909*35238bceSAndroid Build Coastguard Worker 
910*35238bceSAndroid Build Coastguard Worker         {
911*35238bceSAndroid Build Coastguard Worker             const void *in = &inputs[0];
912*35238bceSAndroid Build Coastguard Worker             void *out      = &outputs[0];
913*35238bceSAndroid Build Coastguard Worker 
914*35238bceSAndroid Build Coastguard Worker             m_executor->useProgram();
915*35238bceSAndroid Build Coastguard Worker             m_executor->execute((int)inputs.size(), &in, &out);
916*35238bceSAndroid Build Coastguard Worker         }
917*35238bceSAndroid Build Coastguard Worker 
918*35238bceSAndroid Build Coastguard Worker         // Verify
919*35238bceSAndroid Build Coastguard Worker         {
920*35238bceSAndroid Build Coastguard Worker             const int numValues = (int)inputs.size();
921*35238bceSAndroid Build Coastguard Worker             const int maxPrints = 10;
922*35238bceSAndroid Build Coastguard Worker             int numFailed       = 0;
923*35238bceSAndroid Build Coastguard Worker 
924*35238bceSAndroid Build Coastguard Worker             for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
925*35238bceSAndroid Build Coastguard Worker             {
926*35238bceSAndroid Build Coastguard Worker                 const int8_t in0 = (int8_t)(uint8_t)(inputs[valNdx] & 0xff);
927*35238bceSAndroid Build Coastguard Worker                 const int8_t in1 = (int8_t)(uint8_t)((inputs[valNdx] >> 8) & 0xff);
928*35238bceSAndroid Build Coastguard Worker                 const int8_t in2 = (int8_t)(uint8_t)((inputs[valNdx] >> 16) & 0xff);
929*35238bceSAndroid Build Coastguard Worker                 const int8_t in3 = (int8_t)(uint8_t)(inputs[valNdx] >> 24);
930*35238bceSAndroid Build Coastguard Worker                 const float ref0 = de::clamp(float(in0) / 127.f, -1.0f, 1.0f);
931*35238bceSAndroid Build Coastguard Worker                 const float ref1 = de::clamp(float(in1) / 127.f, -1.0f, 1.0f);
932*35238bceSAndroid Build Coastguard Worker                 const float ref2 = de::clamp(float(in2) / 127.f, -1.0f, 1.0f);
933*35238bceSAndroid Build Coastguard Worker                 const float ref3 = de::clamp(float(in3) / 127.f, -1.0f, 1.0f);
934*35238bceSAndroid Build Coastguard Worker                 const float res0 = outputs[valNdx].x();
935*35238bceSAndroid Build Coastguard Worker                 const float res1 = outputs[valNdx].y();
936*35238bceSAndroid Build Coastguard Worker                 const float res2 = outputs[valNdx].z();
937*35238bceSAndroid Build Coastguard Worker                 const float res3 = outputs[valNdx].w();
938*35238bceSAndroid Build Coastguard Worker 
939*35238bceSAndroid Build Coastguard Worker                 const uint32_t diff0 = getUlpDiff(ref0, res0);
940*35238bceSAndroid Build Coastguard Worker                 const uint32_t diff1 = getUlpDiff(ref1, res1);
941*35238bceSAndroid Build Coastguard Worker                 const uint32_t diff2 = getUlpDiff(ref2, res2);
942*35238bceSAndroid Build Coastguard Worker                 const uint32_t diff3 = getUlpDiff(ref3, res3);
943*35238bceSAndroid Build Coastguard Worker 
944*35238bceSAndroid Build Coastguard Worker                 if (diff0 > maxDiff || diff1 > maxDiff || diff2 > maxDiff || diff3 > maxDiff)
945*35238bceSAndroid Build Coastguard Worker                 {
946*35238bceSAndroid Build Coastguard Worker                     if (numFailed < maxPrints)
947*35238bceSAndroid Build Coastguard Worker                     {
948*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ",\n"
949*35238bceSAndroid Build Coastguard Worker                                            << "  expected unpackSnorm4x8(" << tcu::toHex(inputs[valNdx]) << ") = "
950*35238bceSAndroid Build Coastguard Worker                                            << "vec4(" << HexFloat(ref0) << ", " << HexFloat(ref1) << ", "
951*35238bceSAndroid Build Coastguard Worker                                            << HexFloat(ref2) << ", " << HexFloat(ref3) << ")"
952*35238bceSAndroid Build Coastguard Worker                                            << ", got vec4(" << HexFloat(res0) << ", " << HexFloat(res1) << ", "
953*35238bceSAndroid Build Coastguard Worker                                            << HexFloat(res2) << ", " << HexFloat(res3) << ")"
954*35238bceSAndroid Build Coastguard Worker                                            << "\n  ULP diffs = (" << diff0 << ", " << diff1 << ", " << diff2 << ", "
955*35238bceSAndroid Build Coastguard Worker                                            << diff3 << "), max diff = " << maxDiff << TestLog::EndMessage;
956*35238bceSAndroid Build Coastguard Worker                     }
957*35238bceSAndroid Build Coastguard Worker                     else if (numFailed == maxPrints)
958*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
959*35238bceSAndroid Build Coastguard Worker 
960*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
961*35238bceSAndroid Build Coastguard Worker                 }
962*35238bceSAndroid Build Coastguard Worker             }
963*35238bceSAndroid Build Coastguard Worker 
964*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed"
965*35238bceSAndroid Build Coastguard Worker                                << TestLog::EndMessage;
966*35238bceSAndroid Build Coastguard Worker 
967*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
968*35238bceSAndroid Build Coastguard Worker                                     numFailed == 0 ? "Pass" : "Result comparison failed");
969*35238bceSAndroid Build Coastguard Worker         }
970*35238bceSAndroid Build Coastguard Worker 
971*35238bceSAndroid Build Coastguard Worker         return STOP;
972*35238bceSAndroid Build Coastguard Worker     }
973*35238bceSAndroid Build Coastguard Worker };
974*35238bceSAndroid Build Coastguard Worker 
975*35238bceSAndroid Build Coastguard Worker class PackUnorm4x8Case : public ShaderPackingFunctionCase
976*35238bceSAndroid Build Coastguard Worker {
977*35238bceSAndroid Build Coastguard Worker public:
PackUnorm4x8Case(Context & context,glu::ShaderType shaderType,glu::Precision precision)978*35238bceSAndroid Build Coastguard Worker     PackUnorm4x8Case(Context &context, glu::ShaderType shaderType, glu::Precision precision)
979*35238bceSAndroid Build Coastguard Worker         : ShaderPackingFunctionCase(
980*35238bceSAndroid Build Coastguard Worker               context,
981*35238bceSAndroid Build Coastguard Worker               (string("packunorm4x8") + getPrecisionPostfix(precision) + getShaderTypePostfix(shaderType)).c_str(),
982*35238bceSAndroid Build Coastguard Worker               "packUnorm4x8", shaderType)
983*35238bceSAndroid Build Coastguard Worker         , m_precision(precision)
984*35238bceSAndroid Build Coastguard Worker     {
985*35238bceSAndroid Build Coastguard Worker         m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_FLOAT_VEC4, precision)));
986*35238bceSAndroid Build Coastguard Worker         m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
987*35238bceSAndroid Build Coastguard Worker 
988*35238bceSAndroid Build Coastguard Worker         m_spec.source = "out0 = packUnorm4x8(in0);";
989*35238bceSAndroid Build Coastguard Worker     }
990*35238bceSAndroid Build Coastguard Worker 
iterate(void)991*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
992*35238bceSAndroid Build Coastguard Worker     {
993*35238bceSAndroid Build Coastguard Worker         de::Random rnd(deStringHash(getName()) ^ 0x776002);
994*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::Vec4> inputs;
995*35238bceSAndroid Build Coastguard Worker         std::vector<uint32_t> outputs;
996*35238bceSAndroid Build Coastguard Worker         const int                    maxDiff = m_precision == glu::PRECISION_HIGHP    ? 1    : // Rounding only.
997*35238bceSAndroid Build Coastguard Worker                                                   m_precision == glu::PRECISION_MEDIUMP    ? 1    : // (2^-10) * (2^8) + 1
998*35238bceSAndroid Build Coastguard Worker                                                   m_precision == glu::PRECISION_LOWP    ? 2    : 0;    // (2^-8) * (2^8) + 1
999*35238bceSAndroid Build Coastguard Worker 
1000*35238bceSAndroid Build Coastguard Worker         // Special values to check.
1001*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
1002*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec4(-1.0f, 1.0f, -1.0f, 1.0f));
1003*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec4(0.5f, -0.5f, -0.5f, 0.5f));
1004*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec4(-1.5f, 1.5f, -1.5f, 1.5f));
1005*35238bceSAndroid Build Coastguard Worker         inputs.push_back(tcu::Vec4(0.25f, -0.75f, -0.25f, 0.75f));
1006*35238bceSAndroid Build Coastguard Worker 
1007*35238bceSAndroid Build Coastguard Worker         // Random values, mostly in range.
1008*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < 15; ndx++)
1009*35238bceSAndroid Build Coastguard Worker         {
1010*35238bceSAndroid Build Coastguard Worker             const float x = rnd.getFloat() * 1.25f - 0.125f;
1011*35238bceSAndroid Build Coastguard Worker             const float y = rnd.getFloat() * 1.25f - 0.125f;
1012*35238bceSAndroid Build Coastguard Worker             const float z = rnd.getFloat() * 1.25f - 0.125f;
1013*35238bceSAndroid Build Coastguard Worker             const float w = rnd.getFloat() * 1.25f - 0.125f;
1014*35238bceSAndroid Build Coastguard Worker             inputs.push_back(tcu::Vec4(x, y, z, w));
1015*35238bceSAndroid Build Coastguard Worker         }
1016*35238bceSAndroid Build Coastguard Worker 
1017*35238bceSAndroid Build Coastguard Worker         // Large random values.
1018*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < 80; ndx++)
1019*35238bceSAndroid Build Coastguard Worker         {
1020*35238bceSAndroid Build Coastguard Worker             const float x = rnd.getFloat() * 1e6f - 1e5f;
1021*35238bceSAndroid Build Coastguard Worker             const float y = rnd.getFloat() * 1e6f - 1e5f;
1022*35238bceSAndroid Build Coastguard Worker             const float z = rnd.getFloat() * 1e6f - 1e5f;
1023*35238bceSAndroid Build Coastguard Worker             const float w = rnd.getFloat() * 1e6f - 1e5f;
1024*35238bceSAndroid Build Coastguard Worker             inputs.push_back(tcu::Vec4(x, y, z, w));
1025*35238bceSAndroid Build Coastguard Worker         }
1026*35238bceSAndroid Build Coastguard Worker 
1027*35238bceSAndroid Build Coastguard Worker         outputs.resize(inputs.size());
1028*35238bceSAndroid Build Coastguard Worker 
1029*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values"
1030*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1031*35238bceSAndroid Build Coastguard Worker 
1032*35238bceSAndroid Build Coastguard Worker         {
1033*35238bceSAndroid Build Coastguard Worker             const void *in = &inputs[0];
1034*35238bceSAndroid Build Coastguard Worker             void *out      = &outputs[0];
1035*35238bceSAndroid Build Coastguard Worker 
1036*35238bceSAndroid Build Coastguard Worker             m_executor->useProgram();
1037*35238bceSAndroid Build Coastguard Worker             m_executor->execute((int)inputs.size(), &in, &out);
1038*35238bceSAndroid Build Coastguard Worker         }
1039*35238bceSAndroid Build Coastguard Worker 
1040*35238bceSAndroid Build Coastguard Worker         // Verify
1041*35238bceSAndroid Build Coastguard Worker         {
1042*35238bceSAndroid Build Coastguard Worker             const int numValues = (int)inputs.size();
1043*35238bceSAndroid Build Coastguard Worker             const int maxPrints = 10;
1044*35238bceSAndroid Build Coastguard Worker             int numFailed       = 0;
1045*35238bceSAndroid Build Coastguard Worker 
1046*35238bceSAndroid Build Coastguard Worker             for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
1047*35238bceSAndroid Build Coastguard Worker             {
1048*35238bceSAndroid Build Coastguard Worker                 const uint16_t ref0 = (uint8_t)de::clamp(
1049*35238bceSAndroid Build Coastguard Worker                     deRoundFloatToInt32(de::clamp(inputs[valNdx].x(), 0.0f, 1.0f) * 255.0f), 0, (1 << 8) - 1);
1050*35238bceSAndroid Build Coastguard Worker                 const uint16_t ref1 = (uint8_t)de::clamp(
1051*35238bceSAndroid Build Coastguard Worker                     deRoundFloatToInt32(de::clamp(inputs[valNdx].y(), 0.0f, 1.0f) * 255.0f), 0, (1 << 8) - 1);
1052*35238bceSAndroid Build Coastguard Worker                 const uint16_t ref2 = (uint8_t)de::clamp(
1053*35238bceSAndroid Build Coastguard Worker                     deRoundFloatToInt32(de::clamp(inputs[valNdx].z(), 0.0f, 1.0f) * 255.0f), 0, (1 << 8) - 1);
1054*35238bceSAndroid Build Coastguard Worker                 const uint16_t ref3 = (uint8_t)de::clamp(
1055*35238bceSAndroid Build Coastguard Worker                     deRoundFloatToInt32(de::clamp(inputs[valNdx].w(), 0.0f, 1.0f) * 255.0f), 0, (1 << 8) - 1);
1056*35238bceSAndroid Build Coastguard Worker                 const uint32_t ref =
1057*35238bceSAndroid Build Coastguard Worker                     (uint32_t(ref3) << 24) | (uint32_t(ref2) << 16) | (uint32_t(ref1) << 8) | uint32_t(ref0);
1058*35238bceSAndroid Build Coastguard Worker                 const uint32_t res  = outputs[valNdx];
1059*35238bceSAndroid Build Coastguard Worker                 const uint16_t res0 = (uint8_t)(res & 0xff);
1060*35238bceSAndroid Build Coastguard Worker                 const uint16_t res1 = (uint8_t)((res >> 8) & 0xff);
1061*35238bceSAndroid Build Coastguard Worker                 const uint16_t res2 = (uint8_t)((res >> 16) & 0xff);
1062*35238bceSAndroid Build Coastguard Worker                 const uint16_t res3 = (uint8_t)((res >> 24) & 0xff);
1063*35238bceSAndroid Build Coastguard Worker                 const int diff0     = de::abs((int)ref0 - (int)res0);
1064*35238bceSAndroid Build Coastguard Worker                 const int diff1     = de::abs((int)ref1 - (int)res1);
1065*35238bceSAndroid Build Coastguard Worker                 const int diff2     = de::abs((int)ref2 - (int)res2);
1066*35238bceSAndroid Build Coastguard Worker                 const int diff3     = de::abs((int)ref3 - (int)res3);
1067*35238bceSAndroid Build Coastguard Worker 
1068*35238bceSAndroid Build Coastguard Worker                 if (diff0 > maxDiff || diff1 > maxDiff || diff2 > maxDiff || diff3 > maxDiff)
1069*35238bceSAndroid Build Coastguard Worker                 {
1070*35238bceSAndroid Build Coastguard Worker                     if (numFailed < maxPrints)
1071*35238bceSAndroid Build Coastguard Worker                     {
1072*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog()
1073*35238bceSAndroid Build Coastguard Worker                             << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ", expected packUnorm4x8("
1074*35238bceSAndroid Build Coastguard Worker                             << inputs[valNdx] << ") = " << tcu::toHex(ref) << ", got " << tcu::toHex(res)
1075*35238bceSAndroid Build Coastguard Worker                             << "\n  diffs = " << tcu::IVec4(diff0, diff1, diff2, diff3) << ", max diff = " << maxDiff
1076*35238bceSAndroid Build Coastguard Worker                             << TestLog::EndMessage;
1077*35238bceSAndroid Build Coastguard Worker                     }
1078*35238bceSAndroid Build Coastguard Worker                     else if (numFailed == maxPrints)
1079*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
1080*35238bceSAndroid Build Coastguard Worker 
1081*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
1082*35238bceSAndroid Build Coastguard Worker                 }
1083*35238bceSAndroid Build Coastguard Worker             }
1084*35238bceSAndroid Build Coastguard Worker 
1085*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed"
1086*35238bceSAndroid Build Coastguard Worker                                << TestLog::EndMessage;
1087*35238bceSAndroid Build Coastguard Worker 
1088*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
1089*35238bceSAndroid Build Coastguard Worker                                     numFailed == 0 ? "Pass" : "Result comparison failed");
1090*35238bceSAndroid Build Coastguard Worker         }
1091*35238bceSAndroid Build Coastguard Worker 
1092*35238bceSAndroid Build Coastguard Worker         return STOP;
1093*35238bceSAndroid Build Coastguard Worker     }
1094*35238bceSAndroid Build Coastguard Worker 
1095*35238bceSAndroid Build Coastguard Worker private:
1096*35238bceSAndroid Build Coastguard Worker     glu::Precision m_precision;
1097*35238bceSAndroid Build Coastguard Worker };
1098*35238bceSAndroid Build Coastguard Worker 
1099*35238bceSAndroid Build Coastguard Worker class UnpackUnorm4x8Case : public ShaderPackingFunctionCase
1100*35238bceSAndroid Build Coastguard Worker {
1101*35238bceSAndroid Build Coastguard Worker public:
UnpackUnorm4x8Case(Context & context,glu::ShaderType shaderType)1102*35238bceSAndroid Build Coastguard Worker     UnpackUnorm4x8Case(Context &context, glu::ShaderType shaderType)
1103*35238bceSAndroid Build Coastguard Worker         : ShaderPackingFunctionCase(context, (string("unpackunorm4x8") + getShaderTypePostfix(shaderType)).c_str(),
1104*35238bceSAndroid Build Coastguard Worker                                     "unpackUnorm4x8", shaderType)
1105*35238bceSAndroid Build Coastguard Worker     {
1106*35238bceSAndroid Build Coastguard Worker         m_spec.inputs.push_back(Symbol("in0", glu::VarType(glu::TYPE_UINT, glu::PRECISION_HIGHP)));
1107*35238bceSAndroid Build Coastguard Worker         m_spec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
1108*35238bceSAndroid Build Coastguard Worker 
1109*35238bceSAndroid Build Coastguard Worker         m_spec.source = "out0 = unpackUnorm4x8(in0);";
1110*35238bceSAndroid Build Coastguard Worker     }
1111*35238bceSAndroid Build Coastguard Worker 
iterate(void)1112*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void)
1113*35238bceSAndroid Build Coastguard Worker     {
1114*35238bceSAndroid Build Coastguard Worker         const uint32_t maxDiff = 1; // Rounding error.
1115*35238bceSAndroid Build Coastguard Worker         de::Random rnd(deStringHash(getName()) ^ 0x776002);
1116*35238bceSAndroid Build Coastguard Worker         std::vector<uint32_t> inputs;
1117*35238bceSAndroid Build Coastguard Worker         std::vector<tcu::Vec4> outputs;
1118*35238bceSAndroid Build Coastguard Worker 
1119*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x00000000u);
1120*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x7fff8000u);
1121*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x80007fffu);
1122*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0xffffffffu);
1123*35238bceSAndroid Build Coastguard Worker         inputs.push_back(0x0001fffeu);
1124*35238bceSAndroid Build Coastguard Worker 
1125*35238bceSAndroid Build Coastguard Worker         // Random values.
1126*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < 95; ndx++)
1127*35238bceSAndroid Build Coastguard Worker             inputs.push_back(rnd.getUint32());
1128*35238bceSAndroid Build Coastguard Worker 
1129*35238bceSAndroid Build Coastguard Worker         outputs.resize(inputs.size());
1130*35238bceSAndroid Build Coastguard Worker 
1131*35238bceSAndroid Build Coastguard Worker         m_testCtx.getLog() << TestLog::Message << "Executing shader for " << inputs.size() << " input values"
1132*35238bceSAndroid Build Coastguard Worker                            << tcu::TestLog::EndMessage;
1133*35238bceSAndroid Build Coastguard Worker 
1134*35238bceSAndroid Build Coastguard Worker         {
1135*35238bceSAndroid Build Coastguard Worker             const void *in = &inputs[0];
1136*35238bceSAndroid Build Coastguard Worker             void *out      = &outputs[0];
1137*35238bceSAndroid Build Coastguard Worker 
1138*35238bceSAndroid Build Coastguard Worker             m_executor->useProgram();
1139*35238bceSAndroid Build Coastguard Worker             m_executor->execute((int)inputs.size(), &in, &out);
1140*35238bceSAndroid Build Coastguard Worker         }
1141*35238bceSAndroid Build Coastguard Worker 
1142*35238bceSAndroid Build Coastguard Worker         // Verify
1143*35238bceSAndroid Build Coastguard Worker         {
1144*35238bceSAndroid Build Coastguard Worker             const int numValues = (int)inputs.size();
1145*35238bceSAndroid Build Coastguard Worker             const int maxPrints = 10;
1146*35238bceSAndroid Build Coastguard Worker             int numFailed       = 0;
1147*35238bceSAndroid Build Coastguard Worker 
1148*35238bceSAndroid Build Coastguard Worker             for (int valNdx = 0; valNdx < (int)inputs.size(); valNdx++)
1149*35238bceSAndroid Build Coastguard Worker             {
1150*35238bceSAndroid Build Coastguard Worker                 const uint8_t in0 = (uint8_t)(inputs[valNdx] & 0xff);
1151*35238bceSAndroid Build Coastguard Worker                 const uint8_t in1 = (uint8_t)((inputs[valNdx] >> 8) & 0xff);
1152*35238bceSAndroid Build Coastguard Worker                 const uint8_t in2 = (uint8_t)((inputs[valNdx] >> 16) & 0xff);
1153*35238bceSAndroid Build Coastguard Worker                 const uint8_t in3 = (uint8_t)(inputs[valNdx] >> 24);
1154*35238bceSAndroid Build Coastguard Worker                 const float ref0  = de::clamp(float(in0) / 255.f, 0.0f, 1.0f);
1155*35238bceSAndroid Build Coastguard Worker                 const float ref1  = de::clamp(float(in1) / 255.f, 0.0f, 1.0f);
1156*35238bceSAndroid Build Coastguard Worker                 const float ref2  = de::clamp(float(in2) / 255.f, 0.0f, 1.0f);
1157*35238bceSAndroid Build Coastguard Worker                 const float ref3  = de::clamp(float(in3) / 255.f, 0.0f, 1.0f);
1158*35238bceSAndroid Build Coastguard Worker                 const float res0  = outputs[valNdx].x();
1159*35238bceSAndroid Build Coastguard Worker                 const float res1  = outputs[valNdx].y();
1160*35238bceSAndroid Build Coastguard Worker                 const float res2  = outputs[valNdx].z();
1161*35238bceSAndroid Build Coastguard Worker                 const float res3  = outputs[valNdx].w();
1162*35238bceSAndroid Build Coastguard Worker 
1163*35238bceSAndroid Build Coastguard Worker                 const uint32_t diff0 = getUlpDiff(ref0, res0);
1164*35238bceSAndroid Build Coastguard Worker                 const uint32_t diff1 = getUlpDiff(ref1, res1);
1165*35238bceSAndroid Build Coastguard Worker                 const uint32_t diff2 = getUlpDiff(ref2, res2);
1166*35238bceSAndroid Build Coastguard Worker                 const uint32_t diff3 = getUlpDiff(ref3, res3);
1167*35238bceSAndroid Build Coastguard Worker 
1168*35238bceSAndroid Build Coastguard Worker                 if (diff0 > maxDiff || diff1 > maxDiff || diff2 > maxDiff || diff3 > maxDiff)
1169*35238bceSAndroid Build Coastguard Worker                 {
1170*35238bceSAndroid Build Coastguard Worker                     if (numFailed < maxPrints)
1171*35238bceSAndroid Build Coastguard Worker                     {
1172*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "ERROR: Mismatch in value " << valNdx << ",\n"
1173*35238bceSAndroid Build Coastguard Worker                                            << "  expected unpackUnorm4x8(" << tcu::toHex(inputs[valNdx]) << ") = "
1174*35238bceSAndroid Build Coastguard Worker                                            << "vec4(" << HexFloat(ref0) << ", " << HexFloat(ref1) << ", "
1175*35238bceSAndroid Build Coastguard Worker                                            << HexFloat(ref2) << ", " << HexFloat(ref3) << ")"
1176*35238bceSAndroid Build Coastguard Worker                                            << ", got vec4(" << HexFloat(res0) << ", " << HexFloat(res1) << ", "
1177*35238bceSAndroid Build Coastguard Worker                                            << HexFloat(res2) << ", " << HexFloat(res3) << ")"
1178*35238bceSAndroid Build Coastguard Worker                                            << "\n  ULP diffs = (" << diff0 << ", " << diff1 << ", " << diff2 << ", "
1179*35238bceSAndroid Build Coastguard Worker                                            << diff3 << "), max diff = " << maxDiff << TestLog::EndMessage;
1180*35238bceSAndroid Build Coastguard Worker                     }
1181*35238bceSAndroid Build Coastguard Worker                     else if (numFailed == maxPrints)
1182*35238bceSAndroid Build Coastguard Worker                         m_testCtx.getLog() << TestLog::Message << "..." << TestLog::EndMessage;
1183*35238bceSAndroid Build Coastguard Worker 
1184*35238bceSAndroid Build Coastguard Worker                     numFailed += 1;
1185*35238bceSAndroid Build Coastguard Worker                 }
1186*35238bceSAndroid Build Coastguard Worker             }
1187*35238bceSAndroid Build Coastguard Worker 
1188*35238bceSAndroid Build Coastguard Worker             m_testCtx.getLog() << TestLog::Message << (numValues - numFailed) << " / " << numValues << " values passed"
1189*35238bceSAndroid Build Coastguard Worker                                << TestLog::EndMessage;
1190*35238bceSAndroid Build Coastguard Worker 
1191*35238bceSAndroid Build Coastguard Worker             m_testCtx.setTestResult(numFailed == 0 ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
1192*35238bceSAndroid Build Coastguard Worker                                     numFailed == 0 ? "Pass" : "Result comparison failed");
1193*35238bceSAndroid Build Coastguard Worker         }
1194*35238bceSAndroid Build Coastguard Worker 
1195*35238bceSAndroid Build Coastguard Worker         return STOP;
1196*35238bceSAndroid Build Coastguard Worker     }
1197*35238bceSAndroid Build Coastguard Worker };
1198*35238bceSAndroid Build Coastguard Worker 
ShaderPackingFunctionTests(Context & context)1199*35238bceSAndroid Build Coastguard Worker ShaderPackingFunctionTests::ShaderPackingFunctionTests(Context &context)
1200*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, "pack_unpack", "Floating-point pack and unpack function tests")
1201*35238bceSAndroid Build Coastguard Worker {
1202*35238bceSAndroid Build Coastguard Worker }
1203*35238bceSAndroid Build Coastguard Worker 
~ShaderPackingFunctionTests(void)1204*35238bceSAndroid Build Coastguard Worker ShaderPackingFunctionTests::~ShaderPackingFunctionTests(void)
1205*35238bceSAndroid Build Coastguard Worker {
1206*35238bceSAndroid Build Coastguard Worker }
1207*35238bceSAndroid Build Coastguard Worker 
init(void)1208*35238bceSAndroid Build Coastguard Worker void ShaderPackingFunctionTests::init(void)
1209*35238bceSAndroid Build Coastguard Worker {
1210*35238bceSAndroid Build Coastguard Worker     // New built-in functions in GLES 3.1
1211*35238bceSAndroid Build Coastguard Worker     {
1212*35238bceSAndroid Build Coastguard Worker         const glu::ShaderType allShaderTypes[] = {glu::SHADERTYPE_VERTEX,
1213*35238bceSAndroid Build Coastguard Worker                                                   glu::SHADERTYPE_TESSELLATION_CONTROL,
1214*35238bceSAndroid Build Coastguard Worker                                                   glu::SHADERTYPE_TESSELLATION_EVALUATION,
1215*35238bceSAndroid Build Coastguard Worker                                                   glu::SHADERTYPE_GEOMETRY,
1216*35238bceSAndroid Build Coastguard Worker                                                   glu::SHADERTYPE_FRAGMENT,
1217*35238bceSAndroid Build Coastguard Worker                                                   glu::SHADERTYPE_COMPUTE};
1218*35238bceSAndroid Build Coastguard Worker 
1219*35238bceSAndroid Build Coastguard Worker         // packSnorm4x8
1220*35238bceSAndroid Build Coastguard Worker         for (int prec = 0; prec < glu::PRECISION_LAST; prec++)
1221*35238bceSAndroid Build Coastguard Worker         {
1222*35238bceSAndroid Build Coastguard Worker             for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(allShaderTypes); shaderTypeNdx++)
1223*35238bceSAndroid Build Coastguard Worker                 addChild(new PackSnorm4x8Case(m_context, allShaderTypes[shaderTypeNdx], glu::Precision(prec)));
1224*35238bceSAndroid Build Coastguard Worker         }
1225*35238bceSAndroid Build Coastguard Worker 
1226*35238bceSAndroid Build Coastguard Worker         // unpackSnorm4x8
1227*35238bceSAndroid Build Coastguard Worker         for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(allShaderTypes); shaderTypeNdx++)
1228*35238bceSAndroid Build Coastguard Worker             addChild(new UnpackSnorm4x8Case(m_context, allShaderTypes[shaderTypeNdx]));
1229*35238bceSAndroid Build Coastguard Worker 
1230*35238bceSAndroid Build Coastguard Worker         // packUnorm4x8
1231*35238bceSAndroid Build Coastguard Worker         for (int prec = 0; prec < glu::PRECISION_LAST; prec++)
1232*35238bceSAndroid Build Coastguard Worker         {
1233*35238bceSAndroid Build Coastguard Worker             for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(allShaderTypes); shaderTypeNdx++)
1234*35238bceSAndroid Build Coastguard Worker                 addChild(new PackUnorm4x8Case(m_context, allShaderTypes[shaderTypeNdx], glu::Precision(prec)));
1235*35238bceSAndroid Build Coastguard Worker         }
1236*35238bceSAndroid Build Coastguard Worker 
1237*35238bceSAndroid Build Coastguard Worker         // unpackUnorm4x8
1238*35238bceSAndroid Build Coastguard Worker         for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(allShaderTypes); shaderTypeNdx++)
1239*35238bceSAndroid Build Coastguard Worker             addChild(new UnpackUnorm4x8Case(m_context, allShaderTypes[shaderTypeNdx]));
1240*35238bceSAndroid Build Coastguard Worker     }
1241*35238bceSAndroid Build Coastguard Worker 
1242*35238bceSAndroid Build Coastguard Worker     // GLES 3 functions in new shader types.
1243*35238bceSAndroid Build Coastguard Worker     {
1244*35238bceSAndroid Build Coastguard Worker         const glu::ShaderType newShaderTypes[] = {glu::SHADERTYPE_GEOMETRY, glu::SHADERTYPE_COMPUTE};
1245*35238bceSAndroid Build Coastguard Worker 
1246*35238bceSAndroid Build Coastguard Worker         // packSnorm2x16
1247*35238bceSAndroid Build Coastguard Worker         for (int prec = 0; prec < glu::PRECISION_LAST; prec++)
1248*35238bceSAndroid Build Coastguard Worker         {
1249*35238bceSAndroid Build Coastguard Worker             for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
1250*35238bceSAndroid Build Coastguard Worker                 addChild(new PackSnorm2x16Case(m_context, newShaderTypes[shaderTypeNdx], glu::Precision(prec)));
1251*35238bceSAndroid Build Coastguard Worker         }
1252*35238bceSAndroid Build Coastguard Worker 
1253*35238bceSAndroid Build Coastguard Worker         // unpackSnorm2x16
1254*35238bceSAndroid Build Coastguard Worker         for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
1255*35238bceSAndroid Build Coastguard Worker             addChild(new UnpackSnorm2x16Case(m_context, newShaderTypes[shaderTypeNdx]));
1256*35238bceSAndroid Build Coastguard Worker 
1257*35238bceSAndroid Build Coastguard Worker         // packUnorm2x16
1258*35238bceSAndroid Build Coastguard Worker         for (int prec = 0; prec < glu::PRECISION_LAST; prec++)
1259*35238bceSAndroid Build Coastguard Worker         {
1260*35238bceSAndroid Build Coastguard Worker             for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
1261*35238bceSAndroid Build Coastguard Worker                 addChild(new PackUnorm2x16Case(m_context, newShaderTypes[shaderTypeNdx], glu::Precision(prec)));
1262*35238bceSAndroid Build Coastguard Worker         }
1263*35238bceSAndroid Build Coastguard Worker 
1264*35238bceSAndroid Build Coastguard Worker         // unpackUnorm2x16
1265*35238bceSAndroid Build Coastguard Worker         for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
1266*35238bceSAndroid Build Coastguard Worker             addChild(new UnpackUnorm2x16Case(m_context, newShaderTypes[shaderTypeNdx]));
1267*35238bceSAndroid Build Coastguard Worker 
1268*35238bceSAndroid Build Coastguard Worker         // packHalf2x16
1269*35238bceSAndroid Build Coastguard Worker         for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
1270*35238bceSAndroid Build Coastguard Worker             addChild(new PackHalf2x16Case(m_context, newShaderTypes[shaderTypeNdx]));
1271*35238bceSAndroid Build Coastguard Worker 
1272*35238bceSAndroid Build Coastguard Worker         // unpackHalf2x16
1273*35238bceSAndroid Build Coastguard Worker         for (int shaderTypeNdx = 0; shaderTypeNdx < DE_LENGTH_OF_ARRAY(newShaderTypes); shaderTypeNdx++)
1274*35238bceSAndroid Build Coastguard Worker             addChild(new UnpackHalf2x16Case(m_context, newShaderTypes[shaderTypeNdx]));
1275*35238bceSAndroid Build Coastguard Worker     }
1276*35238bceSAndroid Build Coastguard Worker }
1277*35238bceSAndroid Build Coastguard Worker 
1278*35238bceSAndroid Build Coastguard Worker } // namespace Functional
1279*35238bceSAndroid Build Coastguard Worker } // namespace gles31
1280*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1281