13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*------------------------------------------------------------------------- 23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 3.0 Module 33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ------------------------------------------------- 43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project 63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License"); 83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License. 93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at 103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * http://www.apache.org/licenses/LICENSE-2.0 123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software 143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS, 153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and 173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License. 183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*! 203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file 213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Shader precision tests. 223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * 233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \note Floating-point case uses R32UI render target and uses 243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * floatBitsToUint() in shader to write out floating-point value bits. 253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * This is done since ES3 core doesn't support FP render targets. 263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/ 273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es3fShaderPrecisionTests.hpp" 293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp" 303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp" 313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVectorUtil.hpp" 323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuFloat.hpp" 333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuFormatUtil.hpp" 343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp" 353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp" 363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderUtil.hpp" 373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluDrawUtil.hpp" 383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp" 393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deString.h" 403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp" 423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp" 433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm> 453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp 473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles3 493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Functional 513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string; 543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector; 553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::ostringstream; 563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog; 573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum 593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FRAMEBUFFER_WIDTH = 32, 613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry FRAMEBUFFER_HEIGHT = 32 623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic glu::ShaderProgram* createFloatPrecisionEvalProgram (const glu::RenderContext& context, glu::Precision precision, const char* evalOp, bool isVertexCase) 653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::DataType type = glu::TYPE_FLOAT; 673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::DataType outType = glu::TYPE_UINT; 683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* typeName = glu::getDataTypeName(type); 693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* outTypeName = glu::getDataTypeName(outType); 703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* precName = glu::getPrecisionName(precision); 713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostringstream vtx; 723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostringstream frag; 733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostringstream& op = isVertexCase ? vtx : frag; 743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vtx << "#version 300 es\n" 763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "in highp vec4 a_position;\n" 773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "in " << precName << " " << typeName << " a_in0;\n" 783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "in " << precName << " " << typeName << " a_in1;\n"; 793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry frag << "#version 300 es\n" 803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout(location = 0) out highp " << outTypeName << " o_out;\n"; 813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isVertexCase) 833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vtx << "flat out " << precName << " " << typeName << " v_out;\n"; 853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry frag << "flat in " << precName << " " << typeName << " v_out;\n"; 863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vtx << "flat out " << precName << " " << typeName << " v_in0;\n" 903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "flat out " << precName << " " << typeName << " v_in1;\n"; 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry frag << "flat in " << precName << " " << typeName << " v_in0;\n" 923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "flat in " << precName << " " << typeName << " v_in1;\n"; 933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vtx << "\nvoid main (void)\n{\n" 963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_Position = a_position;\n"; 973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry frag << "\nvoid main (void)\n{\n"; 983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry op << "\t" << precName << " " << typeName << " in0 = " << (isVertexCase ? "a_" : "v_") << "in0;\n" 1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\t" << precName << " " << typeName << " in1 = " << (isVertexCase ? "a_" : "v_") << "in1;\n"; 1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!isVertexCase) 1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry op << "\t" << precName << " " << typeName << " res;\n"; 1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry op << "\t" << (isVertexCase ? "v_out" : "res") << " = " << evalOp << ";\n"; 1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isVertexCase) 1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry frag << " o_out = floatBitsToUint(v_out);\n"; 1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vtx << " v_in0 = a_in0;\n" 1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " v_in1 = a_in1;\n"; 1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry frag << " o_out = floatBitsToUint(res);\n"; 1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vtx << "}\n"; 1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry frag << "}\n"; 1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return new glu::ShaderProgram(context, glu::makeVtxFragSources(vtx.str(), frag.str())); 1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic glu::ShaderProgram* createIntUintPrecisionEvalProgram (const glu::RenderContext& context, glu::DataType type, glu::Precision precision, const char* evalOp, bool isVertexCase) 1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* typeName = glu::getDataTypeName(type); 1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* precName = glu::getPrecisionName(precision); 1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostringstream vtx; 1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostringstream frag; 1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ostringstream& op = isVertexCase ? vtx : frag; 1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vtx << "#version 300 es\n" 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "in highp vec4 a_position;\n" 1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "in " << precName << " " << typeName << " a_in0;\n" 1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "in " << precName << " " << typeName << " a_in1;\n"; 1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry frag << "#version 300 es\n" 1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "layout(location = 0) out " << precName << " " << typeName << " o_out;\n"; 1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isVertexCase) 1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vtx << "flat out " << precName << " " << typeName << " v_out;\n"; 1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry frag << "flat in " << precName << " " << typeName << " v_out;\n"; 1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vtx << "flat out " << precName << " " << typeName << " v_in0;\n" 1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "flat out " << precName << " " << typeName << " v_in1;\n"; 1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry frag << "flat in " << precName << " " << typeName << " v_in0;\n" 1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "flat in " << precName << " " << typeName << " v_in1;\n"; 1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vtx << "\nvoid main (void)\n{\n" 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " gl_Position = a_position;\n"; 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry frag << "\nvoid main (void)\n{\n"; 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry op << "\t" << precName << " " << typeName << " in0 = " << (isVertexCase ? "a_" : "v_") << "in0;\n" 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "\t" << precName << " " << typeName << " in1 = " << (isVertexCase ? "a_" : "v_") << "in1;\n"; 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry op << "\t" << (isVertexCase ? "v_" : "o_") << "out = " << evalOp << ";\n"; 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (isVertexCase) 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry frag << " o_out = v_out;\n"; 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vtx << " v_in0 = a_in0;\n" 1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << " v_in1 = a_in1;\n"; 1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vtx << "}\n"; 1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry frag << "}\n"; 1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return new glu::ShaderProgram(context, glu::makeVtxFragSources(vtx.str(), frag.str())); 1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderFloatPrecisionCase : public TestCase 1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef double (*EvalFunc) (double in0, double in1); 1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderFloatPrecisionCase (Context& context, const char* name, const char* desc, const char* op, EvalFunc evalFunc, glu::Precision precision, const tcu::Vec2& rangeA, const tcu::Vec2& rangeB, bool isVertexCase); 1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~ShaderFloatPrecisionCase (void); 1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 19000b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos bool compare (float in0, float in1, double reference, float result) 19100b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos#if (DE_COMPILER == DE_COMPILER_GCC) && (DE_CPU == DE_CPU_ARM_64) 19200b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos# if (__GNUC__ == 4) && (__GNUC_MINOR__ == 9) && (__GNUC_PATCHLEVEL__ == 0) 19300b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos // Some prerelease GCC 4.9 versions have a bug in shift right when 19400b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos // targeting ARMv8. 19500b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos // 19600b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos // If compiler wants to perform logical shift by variable/register 19700b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos // in fp/vector registers it uses USHL that selects shift direction 19800b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos // based on shift operand value. Thus for right shifts the shift 19900b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos // operand needs to be negated. 20000b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos // 20100b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos // The bug is in right shift pattern; it doesn't mark shift operand 20200b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos // as clobbered and thus later code using that same register may 20300b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos // see the negated value. 20400b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos // 20500b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos // Workaround is to disable optimization for this function. 20600b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos // 20700b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61633 20800b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos __attribute__((optimize(0))) 20900b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos# endif 21000b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos#endif 21100b60d29a1da01c554a3af8f96112199231145d2Pyry Haulos ; 2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderFloatPrecisionCase (const ShaderFloatPrecisionCase& other); 2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderFloatPrecisionCase& operator= (const ShaderFloatPrecisionCase& other); 2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Case parameters. 2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string m_op; 2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry EvalFunc m_evalFunc; 2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::Precision m_precision; 2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec2 m_rangeA; 2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec2 m_rangeB; 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool m_isVertexCase; 2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_numTestsPerIter; 2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_numIters; 2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random m_rnd; 2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Iteration state. 2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_program; 2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_framebuffer; 2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_renderbuffer; 2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_iterNdx; 2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderFloatPrecisionCase::ShaderFloatPrecisionCase (Context& context, const char* name, const char* desc, const char* op, EvalFunc evalFunc, glu::Precision precision, const tcu::Vec2& rangeA, const tcu::Vec2& rangeB, bool isVertexCase) 2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, desc) 2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_op (op) 2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_evalFunc (evalFunc) 2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_precision (precision) 2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_rangeA (rangeA) 2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_rangeB (rangeB) 2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_isVertexCase (isVertexCase) 2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numTestsPerIter (32) 2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numIters (4) 2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_rnd (deStringHash(name)) 2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_program (DE_NULL) 2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_framebuffer (0) 2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_renderbuffer (0) 2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_iterNdx (0) 2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderFloatPrecisionCase::~ShaderFloatPrecisionCase (void) 2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderFloatPrecisionCase::deinit(); 2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderFloatPrecisionCase::init (void) 2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!m_program && !m_framebuffer && !m_renderbuffer); 2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Create program. 2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = createFloatPrecisionEvalProgram(m_context.getRenderContext(), m_precision, m_op.c_str(), m_isVertexCase); 2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << *m_program; 2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(m_program->isOk()); 2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Create framebuffer. 2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genFramebuffers(1, &m_framebuffer); 2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genRenderbuffers(1, &m_renderbuffer); 2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderbuffer); 2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT); 2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_renderbuffer); 2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Post framebuffer setup"); 2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); 2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer()); 2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Initialize test result to pass. 2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_iterNdx = 0; 2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderFloatPrecisionCase::deinit (void) 2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_framebuffer) 2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteFramebuffers(1, &m_framebuffer); 2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_renderbuffer) 3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteRenderbuffers(1, &m_renderbuffer); 3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = DE_NULL; 3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_framebuffer = 0; 3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_renderbuffer = 0; 3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ShaderFloatPrecisionCase::compare (float in0, float in1, double reference, float result) 3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Comparison is done using 64-bit reference value to accurately evaluate rounding mode error. 3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // If 32-bit reference value is used, 2 bits of rounding error must be allowed. 3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // For mediump and lowp types the comparison currently allows 3 bits of rounding error: 3138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry // two bits from conversions and one from actual operation. 3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2013-09-30 pyry] Make this more strict: determine if rounding can actually happen. 3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int mantissaBits = m_precision == glu::PRECISION_HIGHP ? 23 : 10; 3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numPrecBits = 52 - mantissaBits; 3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int in0Exp = tcu::Float32(in0).exponent(); 3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int in1Exp = tcu::Float32(in1).exponent(); 3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int resExp = tcu::Float32(result).exponent(); 3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numLostBits = de::max(de::max(in0Exp-resExp, in1Exp-resExp), 0); // Lost due to mantissa shift. 3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry const int roundingUlpError = m_precision == glu::PRECISION_HIGHP ? 1 : 3; 3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int maskBits = numLostBits + numPrecBits; 3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "Assuming " << mantissaBits << " mantissa bits, " << numLostBits << " bits lost in operation, and " << roundingUlpError << " ULP rounding error." 3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint64 refBits = tcu::Float64(reference).bits(); 3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint64 resBits = tcu::Float64(result).bits(); 3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint64 accurateRefBits = refBits >> maskBits; 3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint64 accurateResBits = resBits >> maskBits; 3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint64 ulpDiff = (deUint64)de::abs((deInt64)accurateRefBits - (deInt64)accurateResBits); 3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (ulpDiff > (deUint64)roundingUlpError) 3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.getLog() << TestLog::Message << "ERROR: comparison failed! ULP diff (ignoring lost/undefined bits) = " << ulpDiff << TestLog::EndMessage; 3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return false; 3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return true; 3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderFloatPrecisionCase::IterateResult ShaderFloatPrecisionCase::iterate (void) 3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Constant data. 3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float position[] = 3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry -1.0f, -1.0f, 0.0f, 1.0f, 3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry -1.0f, 1.0f, 0.0f, 1.0f, 3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1.0f, -1.0f, 0.0f, 1.0f, 3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1.0f, 1.0f, 0.0f, 1.0f 3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 }; 3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numVertices = 4; 3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float in0Arr[4] = { 0.0f }; 3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float in1Arr[4] = { 0.0f }; 3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<glu::VertexArrayBinding> vertexArrays; 3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Image read from GL. 3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::vector<float> pixels (FRAMEBUFFER_WIDTH*FRAMEBUFFER_HEIGHT*4); 3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2012-05-03 pyry] Could be cached. 3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 prog = m_program->getProgram(); 3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(prog); 3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArrays.push_back(glu::va::Float("a_position", 4, numVertices, 0, &position[0])); 3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArrays.push_back(glu::va::Float("a_in0", 1, numVertices, 0, &in0Arr[0])); 3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArrays.push_back(glu::va::Float("a_in1", 1, numVertices, 0, &in1Arr[0])); 3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "After program setup"); 3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Compute values and reference. 3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int testNdx = 0; testNdx < m_numTestsPerIter; testNdx++) 3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float in0 = m_rnd.getFloat(m_rangeA.x(), m_rangeA.y()); 3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float in1 = m_rnd.getFloat(m_rangeB.x(), m_rangeB.y()); 3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const double refD = m_evalFunc((double)in0, (double)in1); 3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float refF = tcu::Float64(refD).asFloat(); // Uses RTE rounding mode. 3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "iter " << m_iterNdx << ", test " << testNdx << ": " 3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "in0 = " << in0 << " / " << tcu::toHex(tcu::Float32(in0).bits()) 3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << ", in1 = " << in1 << " / " << tcu::toHex(tcu::Float32(in1).bits()) 3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage 3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::Message << " reference = " << refF << " / " << tcu::toHex(tcu::Float32(refF).bits()) << TestLog::EndMessage; 3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::fill(&in0Arr[0], &in0Arr[0] + DE_LENGTH_OF_ARRAY(in0Arr), in0); 3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::fill(&in1Arr[0], &in1Arr[0] + DE_LENGTH_OF_ARRAY(in1Arr), in1); 3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::draw(m_context.getRenderContext(), prog, (int)vertexArrays.size(), &vertexArrays[0], 4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0])); 4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.readPixels(0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &pixels[0]); 4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "After render"); 4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << " result = " << pixels[0] << " / " << tcu::toHex(tcu::Float32(pixels[0]).bits()) << TestLog::EndMessage; 4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Verify results 4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const bool firstPixelOk = compare(in0, in1, refD, pixels[0]); 4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (firstPixelOk) 4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Check that rest of pixels match to first one. 4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 firstPixelBits = tcu::Float32(pixels[0]).bits(); 4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool allPixelsOk = true; 4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int y = 0; y < FRAMEBUFFER_HEIGHT; y++) 4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int x = 0; x < FRAMEBUFFER_WIDTH; x++) 4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint32 pixelBits = tcu::Float32(pixels[(y*FRAMEBUFFER_WIDTH + x)*4]).bits(); 4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (pixelBits != firstPixelBits) 4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "ERROR: Inconsistent results, got " << tcu::toHex(pixelBits) << " at (" << x << ", " << y << ")" << TestLog::EndMessage; 4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry allPixelsOk = false; 4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!allPixelsOk) 4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (!allPixelsOk) 4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Inconsistent values in framebuffer"); 4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry else 4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result comparison failed"); 4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS) 4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry break; 4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer()); 4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "After iteration"); 4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_iterNdx += 1; 4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (m_iterNdx < m_numIters && m_testCtx.getTestResult() == QP_TEST_RESULT_PASS) ? CONTINUE : STOP; 4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderIntPrecisionCase : public TestCase 4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef int (*EvalFunc) (int a, int b); 4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderIntPrecisionCase (Context& context, const char* name, const char* desc, const char* op, EvalFunc evalFunc, glu::Precision precision, int bits, const tcu::IVec2& rangeA, const tcu::IVec2& rangeB, bool isVertexCase); 4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~ShaderIntPrecisionCase (void); 4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderIntPrecisionCase (const ShaderIntPrecisionCase& other); 4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderIntPrecisionCase& operator= (const ShaderIntPrecisionCase& other); 4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Case parameters. 4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string m_op; 4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry EvalFunc m_evalFunc; 4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::Precision m_precision; 4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_bits; 4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::IVec2 m_rangeA; 4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::IVec2 m_rangeB; 4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool m_isVertexCase; 4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_numTestsPerIter; 4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_numIters; 4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random m_rnd; 4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Iteration state. 4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_program; 4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_framebuffer; 4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_renderbuffer; 4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_iterNdx; 4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 4883c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderIntPrecisionCase::ShaderIntPrecisionCase (Context& context, const char* name, const char* desc, const char* op, EvalFunc evalFunc, glu::Precision precision, int bits, const tcu::IVec2& rangeA, const tcu::IVec2& rangeB, bool isVertexCase) 4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, desc) 4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_op (op) 4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_evalFunc (evalFunc) 4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_precision (precision) 4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_bits (bits) 4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_rangeA (rangeA) 4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_rangeB (rangeB) 4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_isVertexCase (isVertexCase) 4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numTestsPerIter (32) 4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numIters (4) 4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_rnd (deStringHash(name)) 5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_program (DE_NULL) 5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_framebuffer (0) 5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_renderbuffer (0) 5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_iterNdx (0) 5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5073c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderIntPrecisionCase::~ShaderIntPrecisionCase (void) 5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderIntPrecisionCase::deinit(); 5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderIntPrecisionCase::init (void) 5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!m_program && !m_framebuffer && !m_renderbuffer); 5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Create program. 5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = createIntUintPrecisionEvalProgram(m_context.getRenderContext(), glu::TYPE_INT, m_precision, m_op.c_str(), m_isVertexCase); 5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << *m_program; 5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(m_program->isOk()); 5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Create framebuffer. 5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genFramebuffers(1, &m_framebuffer); 5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genRenderbuffers(1, &m_renderbuffer); 5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderbuffer); 5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32I, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT); 5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_renderbuffer); 5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Post framebuffer setup"); 5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); 5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer()); 5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Initialize test result to pass. 5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_iterNdx = 0; 5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Number of accurate bits assumed = " << m_bits << TestLog::EndMessage; 5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderIntPrecisionCase::deinit (void) 5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_framebuffer) 5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteFramebuffers(1, &m_framebuffer); 5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_renderbuffer) 5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteRenderbuffers(1, &m_renderbuffer); 5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = DE_NULL; 5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_framebuffer = 0; 5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_renderbuffer = 0; 5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline int extendTo32Bit (int value, int bits) 5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (value & ((1<<(bits-1))-1)) | (((value & (1<<(bits-1))) << (32-bits)) >> (32-bits)); 5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5673c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderIntPrecisionCase::IterateResult ShaderIntPrecisionCase::iterate (void) 5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Constant data. 5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float position[] = 5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry -1.0f, -1.0f, 0.0f, 1.0f, 5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry -1.0f, 1.0f, 0.0f, 1.0f, 5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1.0f, -1.0f, 0.0f, 1.0f, 5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1.0f, 1.0f, 0.0f, 1.0f 5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 }; 5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numVertices = 4; 5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int in0Arr[4] = { 0 }; 5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int in1Arr[4] = { 0 }; 5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 mask = m_bits == 32 ? 0xffffffffu : ((1u<<m_bits)-1); 5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<int> pixels (FRAMEBUFFER_WIDTH*FRAMEBUFFER_HEIGHT*4); 5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<glu::VertexArrayBinding> vertexArrays; 5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 prog = m_program->getProgram(); 5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2012-05-03 pyry] A bit hacky. getInt() should work fine with ranges like this. 5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isMaxRangeA = m_rangeA.x() == (int)0x80000000 && m_rangeA.y() == (int)0x7fffffff; 5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isMaxRangeB = m_rangeB.x() == (int)0x80000000 && m_rangeB.y() == (int)0x7fffffff; 5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(prog); 5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArrays.push_back(glu::va::Float("a_position", 4, numVertices, 0, &position[0])); 5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArrays.push_back(glu::va::Int32("a_in0", 1, numVertices, 0, &in0Arr[0])); 6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArrays.push_back(glu::va::Int32("a_in1", 1, numVertices, 0, &in1Arr[0])); 6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "After program setup"); 6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Compute values and reference. 6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int testNdx = 0; testNdx < m_numTestsPerIter; testNdx++) 6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int in0 = extendTo32Bit(((isMaxRangeA ? (int)m_rnd.getUint32() : m_rnd.getInt(m_rangeA.x(), m_rangeA.y())) & mask), m_bits); 6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int in1 = extendTo32Bit(((isMaxRangeB ? (int)m_rnd.getUint32() : m_rnd.getInt(m_rangeB.x(), m_rangeB.y())) & mask), m_bits); 6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int refMasked = m_evalFunc(in0, in1) & mask; 6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int refOut = extendTo32Bit(refMasked, m_bits); 6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "iter " << m_iterNdx << ", test " << testNdx << ": " 6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "in0 = " << in0 << ", in1 = " << in1 << ", ref out = " << refOut << " / " << tcu::toHex(refMasked) 6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::fill(&in0Arr[0], &in0Arr[0] + DE_LENGTH_OF_ARRAY(in0Arr), in0); 6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::fill(&in1Arr[0], &in1Arr[0] + DE_LENGTH_OF_ARRAY(in1Arr), in1); 6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::draw(m_context.getRenderContext(), prog, (int)vertexArrays.size(), &vertexArrays[0], 6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0])); 6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.readPixels(0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, GL_RGBA_INTEGER, GL_INT, &pixels[0]); 6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "After render"); 6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Compare pixels. 6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int y = 0; y < FRAMEBUFFER_HEIGHT; y++) 6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int x = 0; x < FRAMEBUFFER_WIDTH; x++) 6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int cmpOut = pixels[(y*FRAMEBUFFER_WIDTH + x)*4]; 6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int cmpMasked = cmpOut & mask; 6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (cmpMasked != refMasked) 6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Comparison failed (at " << x << ", " << y << "): " 6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "got " << cmpOut << " / " << tcu::toHex(cmpOut) 6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer()); 6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "After iteration"); 6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_iterNdx += 1; 6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (m_iterNdx < m_numIters) ? CONTINUE : STOP; 6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderUintPrecisionCase : public TestCase 6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry typedef deUint32 (*EvalFunc) (deUint32 a, deUint32 b); 6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderUintPrecisionCase (Context& context, const char* name, const char* desc, const char* op, EvalFunc evalFunc, glu::Precision precision, int bits, const tcu::UVec2& rangeA, const tcu::UVec2& rangeB, bool isVertexCase); 6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ~ShaderUintPrecisionCase (void); 6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void init (void); 6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void deinit (void); 6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry IterateResult iterate (void); 6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderUintPrecisionCase (const ShaderUintPrecisionCase& other); 6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderUintPrecisionCase& operator= (const ShaderUintPrecisionCase& other); 6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Case parameters. 6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::string m_op; 6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry EvalFunc m_evalFunc; 6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::Precision m_precision; 6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_bits; 6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::UVec2 m_rangeA; 6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::UVec2 m_rangeB; 6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool m_isVertexCase; 6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_numTestsPerIter; 6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_numIters; 6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry de::Random m_rnd; 6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Iteration state. 6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::ShaderProgram* m_program; 6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_framebuffer; 6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 m_renderbuffer; 6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int m_iterNdx; 6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 6873c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderUintPrecisionCase::ShaderUintPrecisionCase (Context& context, const char* name, const char* desc, const char* op, EvalFunc evalFunc, glu::Precision precision, int bits, const tcu::UVec2& rangeA, const tcu::UVec2& rangeB, bool isVertexCase) 6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCase (context, name, desc) 6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_op (op) 6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_evalFunc (evalFunc) 6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_precision (precision) 6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_bits (bits) 6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_rangeA (rangeA) 6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_rangeB (rangeB) 6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_isVertexCase (isVertexCase) 6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numTestsPerIter (32) 6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_numIters (4) 6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_rnd (deStringHash(name)) 6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_program (DE_NULL) 7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_framebuffer (0) 7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_renderbuffer (0) 7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry , m_iterNdx (0) 7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7063c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderUintPrecisionCase::~ShaderUintPrecisionCase (void) 7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderUintPrecisionCase::deinit(); 7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderUintPrecisionCase::init (void) 7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry DE_ASSERT(!m_program && !m_framebuffer && !m_renderbuffer); 7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Create program. 7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = createIntUintPrecisionEvalProgram(m_context.getRenderContext(), glu::TYPE_UINT, m_precision, m_op.c_str(), m_isVertexCase); 7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << *m_program; 7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(m_program->isOk()); 7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Create framebuffer. 7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genFramebuffers(1, &m_framebuffer); 7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.genRenderbuffers(1, &m_renderbuffer); 7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderbuffer); 7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT); 7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_renderbuffer); 7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "Post framebuffer setup"); 7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); 7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindFramebuffer(GL_FRAMEBUFFER, m_context.getRenderContext().getDefaultFramebuffer()); 7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Initialize test result to pass. 7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_iterNdx = 0; 7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Number of accurate bits assumed = " << m_bits << TestLog::EndMessage; 7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderUintPrecisionCase::deinit (void) 7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry delete m_program; 7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_framebuffer) 7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteFramebuffers(1, &m_framebuffer); 7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (m_renderbuffer) 7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_context.getRenderContext().getFunctions().deleteRenderbuffers(1, &m_renderbuffer); 7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_program = DE_NULL; 7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_framebuffer = 0; 7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_renderbuffer = 0; 7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderUintPrecisionCase::IterateResult ShaderUintPrecisionCase::iterate (void) 7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Constant data. 7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const float position[] = 7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry -1.0f, -1.0f, 0.0f, 1.0f, 7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry -1.0f, 1.0f, 0.0f, 1.0f, 7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1.0f, -1.0f, 0.0f, 1.0f, 7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1.0f, 1.0f, 0.0f, 1.0f 7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 }; 7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const int numVertices = 4; 7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 in0Arr[4] = { 0 }; 7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 in1Arr[4] = { 0 }; 7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry TestLog& log = m_testCtx.getLog(); 7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 mask = m_bits == 32 ? 0xffffffffu : ((1u<<m_bits)-1); 7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<deUint32> pixels (FRAMEBUFFER_WIDTH*FRAMEBUFFER_HEIGHT*4); 7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vector<glu::VertexArrayBinding> vertexArrays; 7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 prog = m_program->getProgram(); 7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \todo [2012-05-03 pyry] A bit hacky. 7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isMaxRangeA = m_rangeA.x() == 0 && m_rangeA.y() == 0xffffffff; 7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry bool isMaxRangeB = m_rangeB.x() == 0 && m_rangeB.y() == 0xffffffff; 7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.useProgram(prog); 7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArrays.push_back(glu::va::Float("a_position", 4, numVertices, 0, &position[0])); 7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArrays.push_back(glu::va::Uint32("a_in0", 1, numVertices, 0, &in0Arr[0])); 7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry vertexArrays.push_back(glu::va::Uint32("a_in1", 1, numVertices, 0, &in1Arr[0])); 7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "After program setup"); 7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Compute values and reference. 7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int testNdx = 0; testNdx < m_numTestsPerIter; testNdx++) 8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 in0 = (isMaxRangeA ? m_rnd.getUint32() : (m_rangeA.x() + m_rnd.getUint32()%(m_rangeA.y()-m_rangeA.x()+1))) & mask; 8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 in1 = (isMaxRangeB ? m_rnd.getUint32() : (m_rangeB.x() + m_rnd.getUint32()%(m_rangeB.y()-m_rangeB.x()+1))) & mask; 8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 refOut = m_evalFunc(in0, in1) & mask; 8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "iter " << m_iterNdx << ", test " << testNdx << ": " 8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "in0 = " << tcu::toHex(in0) << ", in1 = " << tcu::toHex(in1) << ", ref out = " << tcu::toHex(refOut) 8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::fill(&in0Arr[0], &in0Arr[0] + DE_LENGTH_OF_ARRAY(in0Arr), in0); 8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry std::fill(&in1Arr[0], &in1Arr[0] + DE_LENGTH_OF_ARRAY(in1Arr), in1); 8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::draw(m_context.getRenderContext(), prog, (int)vertexArrays.size(), &vertexArrays[0], 8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0])); 8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.readPixels(0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &pixels[0]); 8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "After render"); 8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Compare pixels. 8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int y = 0; y < FRAMEBUFFER_HEIGHT; y++) 8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int x = 0; x < FRAMEBUFFER_WIDTH; x++) 8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 cmpOut = pixels[(y*FRAMEBUFFER_WIDTH + x)*4]; 8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry deUint32 cmpMasked = cmpOut & mask; 8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry if (cmpMasked != refOut) 8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry log << TestLog::Message << "Comparison failed (at " << x << ", " << y << "): " 8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << "got " << tcu::toHex(cmpOut) 8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry << TestLog::EndMessage; 8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail"); 8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return STOP; 8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry gl.bindFramebuffer(GL_FRAMEBUFFER, 0); 8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLU_EXPECT_NO_ERROR(gl.getError(), "After iteration"); 8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry m_iterNdx += 1; 8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry return (m_iterNdx < m_numIters) ? CONTINUE : STOP; 8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8443c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderPrecisionTests::ShaderPrecisionTests (Context& context) 8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : TestCaseGroup(context, "precision", "Shader precision requirements validation tests") 8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8493c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderPrecisionTests::~ShaderPrecisionTests (void) 8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderPrecisionTests::init (void) 8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using tcu::add; 8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using tcu::sub; 8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using tcu::mul; 8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using tcu::div; 8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using tcu::Vec2; 8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using tcu::IVec2; 8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry using tcu::UVec2; 8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Exp = Emax-2, Mantissa = 0 8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float minF32 = tcu::Float32((1u<<31) | (0xfdu<<23) | 0x0u).asFloat(); 8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float maxF32 = tcu::Float32((0u<<31) | (0xfdu<<23) | 0x0u).asFloat(); 8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float minF16 = tcu::Float16((deUint16)((1u<<15) | (0x1du<<10) | 0x0u)).asFloat(); 8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry float maxF16 = tcu::Float16((deUint16)((0u<<15) | (0x1du<<10) | 0x0u)).asFloat(); 8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec2 fullRange32F (minF32, maxF32); 8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec2 fullRange16F (minF16, maxF16); 8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::IVec2 fullRange32I (0x80000000, 0x7fffffff); 8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::IVec2 fullRange16I (-(1<<15), (1<<15)-1); 8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::IVec2 fullRange8I (-(1<<7), (1<<7)-1); 8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::UVec2 fullRange32U (0u, 0xffffffffu); 8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::UVec2 fullRange16U (0u, 0xffffu); 8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::UVec2 fullRange8U (0u, 0xffu); 8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // \note Right now it is not programmatically verified that the results shouldn't end up being inf/nan but 8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // actual values used are ok. 8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const struct 8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* name; 8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* op; 8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderFloatPrecisionCase::EvalFunc evalFunc; 8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::Precision precision; 8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec2 rangeA; 8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::Vec2 rangeB; 8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } floatCases[] = 8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Name Op Eval Precision RangeA RangeB 8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "highp_add", "in0 + in1", add<double>, glu::PRECISION_HIGHP, fullRange32F, fullRange32F }, 8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "highp_sub", "in0 - in1", sub<double>, glu::PRECISION_HIGHP, fullRange32F, fullRange32F }, 8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "highp_mul", "in0 * in1", mul<double>, glu::PRECISION_HIGHP, Vec2(-1e5f, 1e5f), Vec2(-1e5f, 1e5f) }, 8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "highp_div", "in0 / in1", div<double>, glu::PRECISION_HIGHP, Vec2(-1e5f, 1e5f), Vec2(-1e5f, 1e5f) }, 8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "mediump_add", "in0 + in1", add<double>, glu::PRECISION_MEDIUMP, fullRange16F, fullRange16F }, 8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "mediump_sub", "in0 - in1", sub<double>, glu::PRECISION_MEDIUMP, fullRange16F, fullRange16F }, 8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "mediump_mul", "in0 * in1", mul<double>, glu::PRECISION_MEDIUMP, Vec2(-1e2f, 1e2f), Vec2(-1e2f, 1e2f) }, 8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "mediump_div", "in0 / in1", div<double>, glu::PRECISION_MEDIUMP, Vec2(-1e2f, 1e2f), Vec2(-1e2f, 1e2f) } 8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const struct 9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* name; 9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* op; 9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderIntPrecisionCase::EvalFunc evalFunc; 9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::Precision precision; 9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int bits; 9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::IVec2 rangeA; 9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::IVec2 rangeB; 9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } intCases[] = 9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Name Op Eval Precision Bits RangeA RangeB 9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "highp_add", "in0 + in1", add<int>, glu::PRECISION_HIGHP, 32, fullRange32I, fullRange32I }, 9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "highp_sub", "in0 - in1", sub<int>, glu::PRECISION_HIGHP, 32, fullRange32I, fullRange32I }, 9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "highp_mul", "in0 * in1", mul<int>, glu::PRECISION_HIGHP, 32, fullRange32I, fullRange32I }, 9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "highp_div", "in0 / in1", div<int>, glu::PRECISION_HIGHP, 32, fullRange32I, IVec2(-10000, -1) }, 9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "mediump_add", "in0 + in1", add<int>, glu::PRECISION_MEDIUMP, 16, fullRange16I, fullRange16I }, 9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "mediump_sub", "in0 - in1", sub<int>, glu::PRECISION_MEDIUMP, 16, fullRange16I, fullRange16I }, 9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "mediump_mul", "in0 * in1", mul<int>, glu::PRECISION_MEDIUMP, 16, fullRange16I, fullRange16I }, 9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "mediump_div", "in0 / in1", div<int>, glu::PRECISION_MEDIUMP, 16, fullRange16I, IVec2(1, 1000) }, 9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "lowp_add", "in0 + in1", add<int>, glu::PRECISION_LOWP, 8, fullRange8I, fullRange8I }, 9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "lowp_sub", "in0 - in1", sub<int>, glu::PRECISION_LOWP, 8, fullRange8I, fullRange8I }, 9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "lowp_mul", "in0 * in1", mul<int>, glu::PRECISION_LOWP, 8, fullRange8I, fullRange8I }, 9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "lowp_div", "in0 / in1", div<int>, glu::PRECISION_LOWP, 8, fullRange8I, IVec2(-50, -1) } 9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry static const struct 9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* name; 9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const char* op; 9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry ShaderUintPrecisionCase::EvalFunc evalFunc; 9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry glu::Precision precision; 9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry int bits; 9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::UVec2 rangeA; 9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::UVec2 rangeB; 9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } uintCases[] = 9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry // Name Op Eval Precision Bits RangeA RangeB 9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "highp_add", "in0 + in1", add<deUint32>, glu::PRECISION_HIGHP, 32, fullRange32U, fullRange32U }, 9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "highp_sub", "in0 - in1", sub<deUint32>, glu::PRECISION_HIGHP, 32, fullRange32U, fullRange32U }, 9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "highp_mul", "in0 * in1", mul<deUint32>, glu::PRECISION_HIGHP, 32, fullRange32U, fullRange32U }, 9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "highp_div", "in0 / in1", div<deUint32>, glu::PRECISION_HIGHP, 32, fullRange32U, UVec2(1u, 10000u) }, 9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "mediump_add", "in0 + in1", add<deUint32>, glu::PRECISION_MEDIUMP, 16, fullRange16U, fullRange16U }, 9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "mediump_sub", "in0 - in1", sub<deUint32>, glu::PRECISION_MEDIUMP, 16, fullRange16U, fullRange16U }, 9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "mediump_mul", "in0 * in1", mul<deUint32>, glu::PRECISION_MEDIUMP, 16, fullRange16U, fullRange16U }, 9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "mediump_div", "in0 / in1", div<deUint32>, glu::PRECISION_MEDIUMP, 16, fullRange16U, UVec2(1, 1000u) }, 9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "lowp_add", "in0 + in1", add<deUint32>, glu::PRECISION_LOWP, 8, fullRange8U, fullRange8U }, 9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "lowp_sub", "in0 - in1", sub<deUint32>, glu::PRECISION_LOWP, 8, fullRange8U, fullRange8U }, 9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "lowp_mul", "in0 * in1", mul<deUint32>, glu::PRECISION_LOWP, 8, fullRange8U, fullRange8U }, 9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { "lowp_div", "in0 / in1", div<deUint32>, glu::PRECISION_LOWP, 8, fullRange8U, UVec2(1, 50u) } 9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry }; 9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* floatGroup = new tcu::TestCaseGroup(m_testCtx, "float", "Floating-point precision tests"); 9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(floatGroup); 9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(floatCases); ndx++) 9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry floatGroup->addChild(new ShaderFloatPrecisionCase(m_context, 9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (string(floatCases[ndx].name) + "_vertex").c_str(), "", 9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry floatCases[ndx].op, 9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry floatCases[ndx].evalFunc, 9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry floatCases[ndx].precision, 9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry floatCases[ndx].rangeA, 9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry floatCases[ndx].rangeB, 9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry true)); 9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry floatGroup->addChild(new ShaderFloatPrecisionCase(m_context, 9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (string(floatCases[ndx].name) + "_fragment").c_str(), "", 9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry floatCases[ndx].op, 9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry floatCases[ndx].evalFunc, 9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry floatCases[ndx].precision, 9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry floatCases[ndx].rangeA, 9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry floatCases[ndx].rangeB, 9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry false)); 9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* intGroup = new tcu::TestCaseGroup(m_testCtx, "int", "Integer precision tests"); 9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(intGroup); 9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(intCases); ndx++) 9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry intGroup->addChild(new ShaderIntPrecisionCase(m_context, 9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (string(intCases[ndx].name) + "_vertex").c_str(), "", 9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry intCases[ndx].op, 9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry intCases[ndx].evalFunc, 9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry intCases[ndx].precision, 9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry intCases[ndx].bits, 9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry intCases[ndx].rangeA, 9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry intCases[ndx].rangeB, 9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry true)); 9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry intGroup->addChild(new ShaderIntPrecisionCase(m_context, 9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (string(intCases[ndx].name) + "_fragment").c_str(), "", 9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry intCases[ndx].op, 9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry intCases[ndx].evalFunc, 9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry intCases[ndx].precision, 9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry intCases[ndx].bits, 9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry intCases[ndx].rangeA, 9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry intCases[ndx].rangeB, 9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry false)); 9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry tcu::TestCaseGroup* uintGroup = new tcu::TestCaseGroup(m_testCtx, "uint", "Unsigned integer precision tests"); 10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry addChild(uintGroup); 10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(uintCases); ndx++) 10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry { 10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uintGroup->addChild(new ShaderUintPrecisionCase(m_context, 10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (string(uintCases[ndx].name) + "_vertex").c_str(), "", 10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uintCases[ndx].op, 10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uintCases[ndx].evalFunc, 10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uintCases[ndx].precision, 10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uintCases[ndx].bits, 10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uintCases[ndx].rangeA, 10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uintCases[ndx].rangeB, 10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry true)); 10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uintGroup->addChild(new ShaderUintPrecisionCase(m_context, 10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry (string(uintCases[ndx].name) + "_fragment").c_str(), "", 10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uintCases[ndx].op, 10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uintCases[ndx].evalFunc, 10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uintCases[ndx].precision, 10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uintCases[ndx].bits, 10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uintCases[ndx].rangeA, 10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry uintCases[ndx].rangeB, 10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry false)); 10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry } 10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} 10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Functional 10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles3 10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp 1027