Path: blob/main_old/src/tests/deqp_support/glcShaderConstExprTests_override.cpp
1693 views
/*-------------------------------------------------------------------------1* OpenGL Conformance Test Suite2* -----------------------------3*4* Copyright (c) 2017 The Khronos Group Inc.5*6* Licensed under the Apache License, Version 2.0 (the "License");7* you may not use this file except in compliance with the License.8* You may obtain a copy of the License at9*10* http://www.apache.org/licenses/LICENSE-2.011*12* Unless required by applicable law or agreed to in writing, software13* distributed under the License is distributed on an "AS IS" BASIS,14* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.15* See the License for the specific language governing permissions and16* limitations under the License.17*18* \file glcShaderConstExprTests.cpp19* \brief Declares shader constant expressions tests.20*/ /*-------------------------------------------------------------------*/2122#include <map>23#include "deMath.h"24#include "deSharedPtr.hpp"25#include "glcShaderConstExprTests.hpp"26#include "glsShaderExecUtil.hpp"27#include "gluContextInfo.hpp"28#include "gluShaderUtil.hpp"29#include "tcuFloat.hpp"30#include "tcuStringTemplate.hpp"31#include "tcuTestLog.hpp"3233using namespace deqp::gls::ShaderExecUtil;3435namespace glcts36{3738namespace ShaderConstExpr39{4041struct TestParams42{43const char *name;44const char *expression;4546glu::DataType inType;47int minComponents;48int maxComponents;4950glu::DataType outType;51union52{53float outputFloat;54int outputInt;55};56};5758struct ShaderExecutorParams59{60deqp::Context *context;6162std::string caseName;63std::string source;6465glu::DataType outType;66union67{68float outputFloat;69int outputInt;70};71};7273template <typename OutputType>74class ExecutorTestCase : public deqp::TestCase75{76public:77ExecutorTestCase(deqp::Context &context,78const char *name,79glu::ShaderType shaderType,80const ShaderSpec &shaderSpec,81OutputType expectedOutput);82virtual ~ExecutorTestCase(void);83virtual tcu::TestNode::IterateResult iterate(void);8485protected:86void validateOutput(de::SharedPtr<ShaderExecutor> executor);8788glu::ShaderType m_shaderType;89ShaderSpec m_shaderSpec;90OutputType m_expectedOutput;91};9293template <typename OutputType>94ExecutorTestCase<OutputType>::ExecutorTestCase(deqp::Context &context,95const char *name,96glu::ShaderType shaderType,97const ShaderSpec &shaderSpec,98OutputType expectedOutput)99: deqp::TestCase(context, name, ""),100m_shaderType(shaderType),101m_shaderSpec(shaderSpec),102m_expectedOutput(expectedOutput)103{}104105template <typename OutputType>106ExecutorTestCase<OutputType>::~ExecutorTestCase(void)107{}108109template <>110void ExecutorTestCase<float>::validateOutput(de::SharedPtr<ShaderExecutor> executor)111{112float result = 0.0f;113void *const outputs = &result;114executor->execute(1, DE_NULL, &outputs);115116const float epsilon = 0.01f;117if (de::abs(m_expectedOutput - result) > epsilon)118{119m_context.getTestContext().getLog()120<< tcu::TestLog::Message << "Expected: " << m_expectedOutput << " ("121<< tcu::toHex(tcu::Float32(m_expectedOutput).bits())122<< ") but constant expresion returned: " << result << " ("123<< tcu::toHex(tcu::Float32(result).bits()) << "), used " << epsilon124<< " epsilon for comparison" << tcu::TestLog::EndMessage;125m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");126return;127}128129m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");130return;131}132133template <>134void ExecutorTestCase<int>::validateOutput(de::SharedPtr<ShaderExecutor> executor)135{136int result = 0;137void *const outputs = &result;138executor->execute(1, DE_NULL, &outputs);139140if (result == m_expectedOutput)141{142m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");143return;144}145146m_context.getTestContext().getLog()147<< tcu::TestLog::Message << "Expected: " << m_expectedOutput148<< " but constant expresion returned: " << result << tcu::TestLog::EndMessage;149m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");150}151152template <typename OutputType>153tcu::TestNode::IterateResult ExecutorTestCase<OutputType>::iterate(void)154{155de::SharedPtr<ShaderExecutor> executor(156createExecutor(m_context.getRenderContext(), m_shaderType, m_shaderSpec));157158DE_ASSERT(executor.get());159160executor->log(m_context.getTestContext().getLog());161162try163{164if (!executor->isOk())165TCU_FAIL("Compilation failed");166167executor->useProgram();168169validateOutput(executor);170}171catch (const tcu::NotSupportedError &e)172{173m_testCtx.getLog() << tcu::TestLog::Message << e.what() << tcu::TestLog::EndMessage;174m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, e.getMessage());175}176catch (const tcu::TestError &e)177{178m_testCtx.getLog() << tcu::TestLog::Message << e.what() << tcu::TestLog::EndMessage;179m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, e.getMessage());180}181182return tcu::TestNode::STOP;183}184185template <typename OutputType>186void createTestCasesForAllShaderTypes(const ShaderExecutorParams ¶ms,187std::vector<tcu::TestNode *> &outputTests)188{189DE_ASSERT(params.context);190191deqp::Context &context = *(params.context);192glu::ContextType contextType = context.getRenderContext().getType();193194ShaderSpec shaderSpec;195shaderSpec.version = glu::getContextTypeGLSLVersion(contextType);196shaderSpec.source = params.source;197shaderSpec.outputs.push_back(198Symbol("out0", glu::VarType(params.outType, glu::PRECISION_HIGHP)));199200// Construct list of shaders for which tests can be created201std::vector<glu::ShaderType> shaderTypes;202203if (glu::contextSupports(contextType, glu::ApiType::core(4, 3)))204{205shaderTypes.push_back(glu::SHADERTYPE_VERTEX);206shaderTypes.push_back(glu::SHADERTYPE_FRAGMENT);207shaderTypes.push_back(glu::SHADERTYPE_COMPUTE);208shaderTypes.push_back(glu::SHADERTYPE_GEOMETRY);209shaderTypes.push_back(glu::SHADERTYPE_TESSELLATION_CONTROL);210shaderTypes.push_back(glu::SHADERTYPE_TESSELLATION_EVALUATION);211}212else if (glu::contextSupports(contextType, glu::ApiType::es(3, 2)))213{214shaderSpec.version = glu::GLSL_VERSION_320_ES;215shaderTypes.push_back(glu::SHADERTYPE_GEOMETRY);216shaderTypes.push_back(glu::SHADERTYPE_TESSELLATION_CONTROL);217shaderTypes.push_back(glu::SHADERTYPE_TESSELLATION_EVALUATION);218}219else if (glu::contextSupports(contextType, glu::ApiType::es(3, 1)))220{221shaderSpec.version = glu::GLSL_VERSION_310_ES;222shaderTypes.push_back(glu::SHADERTYPE_COMPUTE);223shaderTypes.push_back(glu::SHADERTYPE_GEOMETRY);224shaderTypes.push_back(glu::SHADERTYPE_TESSELLATION_CONTROL);225shaderTypes.push_back(glu::SHADERTYPE_TESSELLATION_EVALUATION);226}227else228{229shaderTypes.push_back(glu::SHADERTYPE_VERTEX);230shaderTypes.push_back(glu::SHADERTYPE_FRAGMENT);231}232233shaderSpec.globalDeclarations += "precision highp float;\n";234235for (std::size_t typeIndex = 0; typeIndex < shaderTypes.size(); ++typeIndex)236{237glu::ShaderType shaderType = shaderTypes[typeIndex];238std::string caseName(params.caseName + '_' + getShaderTypeName(shaderType));239240outputTests.push_back(241new ExecutorTestCase<OutputType>(context, caseName.c_str(), shaderType, shaderSpec,242static_cast<OutputType>(params.outputFloat)));243}244}245246void createTests(deqp::Context &context,247const TestParams *cases,248int numCases,249const char *shaderTemplateSrc,250const char *casePrefix,251std::vector<tcu::TestNode *> &outputTests)252{253const tcu::StringTemplate shaderTemplate(shaderTemplateSrc);254const char *componentAccess[] = {"", ".y", ".z", ".w"};255256ShaderExecutorParams shaderExecutorParams;257shaderExecutorParams.context = &context;258259for (int caseIndex = 0; caseIndex < numCases; caseIndex++)260{261const TestParams &testCase = cases[caseIndex];262const std::string baseName = testCase.name;263const int minComponents = testCase.minComponents;264const int maxComponents = testCase.maxComponents;265const glu::DataType inType = testCase.inType;266const std::string expression = testCase.expression;267268// Check for presence of func(vec, scalar) style specialization,269// use as gatekeeper for applying said specialization270const bool alwaysScalar = expression.find("${MT}") != std::string::npos;271272std::map<std::string, std::string> shaderTemplateParams;273shaderTemplateParams["CASE_BASE_TYPE"] = glu::getDataTypeName(testCase.outType);274275shaderExecutorParams.outType = testCase.outType;276shaderExecutorParams.outputFloat = testCase.outputFloat;277278for (int component = minComponents - 1; component < maxComponents; component++)279{280// Get type name eg. float, vec2, vec3, vec4 (same for other primitive types)281glu::DataType dataType = static_cast<glu::DataType>(inType + component);282std::string typeName = glu::getDataTypeName(dataType);283284// ${T} => final type, ${MT} => final type but with scalar version usable even when T is285// a vector286std::map<std::string, std::string> expressionTemplateParams;287expressionTemplateParams["T"] = typeName;288expressionTemplateParams["MT"] = typeName;289290const tcu::StringTemplate expressionTemplate(expression);291292// Add vector access to expression as needed293shaderTemplateParams["CASE_EXPRESSION"] =294expressionTemplate.specialize(expressionTemplateParams) +295componentAccess[component];296297{298// Add type to case name if we are generating multiple versions299shaderExecutorParams.caseName = (casePrefix + baseName);300if (minComponents != maxComponents)301shaderExecutorParams.caseName += ("_" + typeName);302303shaderExecutorParams.source = shaderTemplate.specialize(shaderTemplateParams);304if (shaderExecutorParams.outType == glu::TYPE_FLOAT)305createTestCasesForAllShaderTypes<float>(shaderExecutorParams, outputTests);306else307createTestCasesForAllShaderTypes<int>(shaderExecutorParams, outputTests);308}309310// Deal with functions that allways accept one ore more scalar parameters even when311// others are vectors312if (alwaysScalar && component > 0)313{314shaderExecutorParams.caseName =315casePrefix + baseName + "_" + typeName + "_" + glu::getDataTypeName(inType);316317expressionTemplateParams["MT"] = glu::getDataTypeName(inType);318shaderTemplateParams["CASE_EXPRESSION"] =319expressionTemplate.specialize(expressionTemplateParams) +320componentAccess[component];321322shaderExecutorParams.source = shaderTemplate.specialize(shaderTemplateParams);323if (shaderExecutorParams.outType == glu::TYPE_FLOAT)324createTestCasesForAllShaderTypes<float>(shaderExecutorParams, outputTests);325else326createTestCasesForAllShaderTypes<int>(shaderExecutorParams, outputTests);327}328} // component loop329}330}331332} // namespace ShaderConstExpr333334ShaderConstExprTests::ShaderConstExprTests(deqp::Context &context)335: deqp::TestCaseGroup(context, "constant_expressions", "Constant expressions")336{}337338ShaderConstExprTests::~ShaderConstExprTests(void) {}339340void ShaderConstExprTests::init(void)341{342// Needed for autogenerating shader code for increased component counts343DE_STATIC_ASSERT(glu::TYPE_FLOAT + 1 == glu::TYPE_FLOAT_VEC2);344DE_STATIC_ASSERT(glu::TYPE_FLOAT + 2 == glu::TYPE_FLOAT_VEC3);345DE_STATIC_ASSERT(glu::TYPE_FLOAT + 3 == glu::TYPE_FLOAT_VEC4);346347DE_STATIC_ASSERT(glu::TYPE_INT + 1 == glu::TYPE_INT_VEC2);348DE_STATIC_ASSERT(glu::TYPE_INT + 2 == glu::TYPE_INT_VEC3);349DE_STATIC_ASSERT(glu::TYPE_INT + 3 == glu::TYPE_INT_VEC4);350351DE_STATIC_ASSERT(glu::TYPE_UINT + 1 == glu::TYPE_UINT_VEC2);352DE_STATIC_ASSERT(glu::TYPE_UINT + 2 == glu::TYPE_UINT_VEC3);353DE_STATIC_ASSERT(glu::TYPE_UINT + 3 == glu::TYPE_UINT_VEC4);354355DE_STATIC_ASSERT(glu::TYPE_BOOL + 1 == glu::TYPE_BOOL_VEC2);356DE_STATIC_ASSERT(glu::TYPE_BOOL + 2 == glu::TYPE_BOOL_VEC3);357DE_STATIC_ASSERT(glu::TYPE_BOOL + 3 == glu::TYPE_BOOL_VEC4);358359// ${T} => final type, ${MT} => final type but with scalar version usable even when T is a360// vector361const ShaderConstExpr::TestParams baseCases[] = {362{"radians",363"radians(${T} (90.0))",364glu::TYPE_FLOAT,3651,3664,367glu::TYPE_FLOAT,368{deFloatRadians(90.0f)}},369{"degrees",370"degrees(${T} (2.0))",371glu::TYPE_FLOAT,3721,3734,374glu::TYPE_FLOAT,375{deFloatDegrees(2.0f)}},376{"sin", "sin(${T} (3.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, {deFloatSin(3.0f)}},377{"cos", "cos(${T} (3.2))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, {deFloatCos(3.2f)}},378{"asin", "asin(${T} (0.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, {deFloatAsin(0.0f)}},379{"acos", "acos(${T} (1.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, {deFloatAcos(1.0f)}},380{"pow",381"pow(${T} (1.7), ${T} (3.5))",382glu::TYPE_FLOAT,3831,3844,385glu::TYPE_FLOAT,386{deFloatPow(1.7f, 3.5f)}},387{"exp", "exp(${T} (4.2))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, {deFloatExp(4.2f)}},388{"log", "log(${T} (42.12))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, {deFloatLog(42.12f)}},389{"exp2", "exp2(${T} (6.7))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, {deFloatExp2(6.7f)}},390{"log2",391"log2(${T} (100.0))",392glu::TYPE_FLOAT,3931,3944,395glu::TYPE_FLOAT,396{deFloatLog2(100.0f)}},397{"sqrt", "sqrt(${T} (10.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, {deFloatSqrt(10.0f)}},398{"inversesqrt",399"inversesqrt(${T} (10.0))",400glu::TYPE_FLOAT,4011,4024,403glu::TYPE_FLOAT,404{deFloatRsq(10.0f)}},405{"abs", "abs(${T} (-42))", glu::TYPE_INT, 1, 4, glu::TYPE_INT, {42}},406{"sign", "sign(${T} (-18.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, {-1.0f}},407{"floor",408"floor(${T} (37.3))",409glu::TYPE_FLOAT,4101,4114,412glu::TYPE_FLOAT,413{deFloatFloor(37.3f)}},414{"trunc", "trunc(${T} (-1.8))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, {-1.0f}},415{"round", "round(${T} (42.1))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, {42.0f}},416{"ceil", "ceil(${T} (82.2))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, {deFloatCeil(82.2f)}},417{"mod",418"mod(${T} (87.65), ${MT} (3.7))",419glu::TYPE_FLOAT,4201,4214,422glu::TYPE_FLOAT,423{deFloatMod(87.65f, 3.7f)}},424{"min", "min(${T} (12.3), ${MT} (32.1))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, {12.3f}},425{"max", "max(${T} (12.3), ${MT} (32.1))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, {32.1f}},426{"clamp",427"clamp(${T} (42.1), ${MT} (10.0), ${MT} (15.0))",428glu::TYPE_FLOAT,4291,4304,431glu::TYPE_FLOAT,432{15.0f}},433{"length_float", "length(1.0)", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, {1.0f}},434{"length_vec2",435"length(vec2(1.0))",436glu::TYPE_FLOAT,4371,4381,439glu::TYPE_FLOAT,440{deFloatSqrt(2.0f)}},441{"length_vec3",442"length(vec3(1.0))",443glu::TYPE_FLOAT,4441,4451,446glu::TYPE_FLOAT,447{deFloatSqrt(3.0f)}},448{"length_vec4",449"length(vec4(1.0))",450glu::TYPE_FLOAT,4511,4521,453glu::TYPE_FLOAT,454{deFloatSqrt(4.0f)}},455{"dot_float", "dot(1.0, 1.0)", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, {1.0f}},456{"dot_vec2", "dot(vec2(1.0), vec2(1.0))", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, {2.0f}},457{"dot_vec3", "dot(vec3(1.0), vec3(1.0))", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, {3.0f}},458{"dot_vec4", "dot(vec4(1.0), vec4(1.0))", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, {4.0f}},459{"normalize_float", "normalize(1.0)", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, {1.0f}},460{"normalize_vec2",461"normalize(vec2(1.0)).x",462glu::TYPE_FLOAT,4631,4641,465glu::TYPE_FLOAT,466{deFloatRsq(2.0f)}},467{"normalize_vec3",468"normalize(vec3(1.0)).x",469glu::TYPE_FLOAT,4701,4711,472glu::TYPE_FLOAT,473{deFloatRsq(3.0f)}},474{"normalize_vec4",475"normalize(vec4(1.0)).x",476glu::TYPE_FLOAT,4771,4781,479glu::TYPE_FLOAT,480{deFloatRsq(4.0f)}},481};482483const ShaderConstExpr::TestParams arrayCases[] = {484{"radians",485"radians(${T} (60.0))",486glu::TYPE_FLOAT,4871,4884,489glu::TYPE_INT,490{deFloatRadians(60.0f)}},491{"degrees",492"degrees(${T} (0.11))",493glu::TYPE_FLOAT,4941,4954,496glu::TYPE_INT,497{deFloatDegrees(0.11f)}},498{"sin",499"${T} (1.0) + sin(${T} (0.7))",500glu::TYPE_FLOAT,5011,5024,503glu::TYPE_INT,504{1.0f + deFloatSin(0.7f)}},505{"cos",506"${T} (1.0) + cos(${T} (0.7))",507glu::TYPE_FLOAT,5081,5094,510glu::TYPE_INT,511{1.0f + deFloatCos(0.7f)}},512{"asin", "asin(${T} (0.9))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_INT, {deFloatAsin(0.9f)}},513{"acos", "acos(${T} (-0.5))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_INT, {deFloatAcos(-0.5f)}},514{"pow",515"pow(${T} (2.0), ${T} (2.0))",516glu::TYPE_FLOAT,5171,5184,519glu::TYPE_INT,520{deFloatPow(2.0f, 2.0f)}},521{"exp", "exp(${T} (1.2))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_INT, {deFloatExp(1.2f)}},522{"log", "log(${T} (8.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_INT, {deFloatLog(8.0f)}},523{"exp2", "exp2(${T} (2.1))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_INT, {deFloatExp2(2.1f)}},524{"log2", "log2(${T} (9.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_INT, {deFloatLog2(9.0)}},525{"sqrt", "sqrt(${T} (4.5))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_INT, {deFloatSqrt(4.5f)}},526{"inversesqrt",527"inversesqrt(${T} (0.26))",528glu::TYPE_FLOAT,5291,5304,531glu::TYPE_INT,532{deFloatRsq(0.26f)}},533{"abs", "abs(${T} (-2))", glu::TYPE_INT, 1, 4, glu::TYPE_INT, {2}},534{"sign", "sign(${T} (18.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_INT, {deFloatSign(18.0f)}},535{"floor", "floor(${T} (3.3))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_INT, {deFloatFloor(3.3f)}},536{"trunc", "trunc(${T} (2.8))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_INT, {2}},537{"round", "round(${T} (2.2))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_INT, {deFloatRound(2.2f)}},538{"ceil", "ceil(${T} (2.2))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_INT, {deFloatCeil(2.2f)}},539{"mod",540"mod(${T} (7.1), ${MT} (4.0))",541glu::TYPE_FLOAT,5421,5434,544glu::TYPE_INT,545{deFloatMod(7.1f, 4.0f)}},546{"min",547"min(${T} (2.3), ${MT} (3.1))",548glu::TYPE_FLOAT,5491,5504,551glu::TYPE_INT,552{deFloatMin(2.3f, 3.1f)}},553{"max",554"max(${T} (2.3), ${MT} (3.1))",555glu::TYPE_FLOAT,5561,5574,558glu::TYPE_INT,559{deFloatMax(2.3f, 3.1f)}},560{"clamp",561"clamp(${T} (4.1), ${MT} (2.1), ${MT} (3.1))",562glu::TYPE_FLOAT,5631,5644,565glu::TYPE_INT,566{3}},567{"length_float", "length(2.1)", glu::TYPE_FLOAT, 1, 1, glu::TYPE_INT, {2}},568{"length_vec2",569"length(vec2(1.0))",570glu::TYPE_FLOAT,5711,5721,573glu::TYPE_INT,574{deFloatSqrt(2.0f)}},575{"length_vec3",576"length(vec3(1.0))",577glu::TYPE_FLOAT,5781,5791,580glu::TYPE_INT,581{deFloatSqrt(3.0f)}},582{"length_vec4",583"length(vec4(1.0))",584glu::TYPE_FLOAT,5851,5861,587glu::TYPE_INT,588{deFloatSqrt(4.0f)}},589{"dot_float", "dot(1.0, 1.0)", glu::TYPE_FLOAT, 1, 1, glu::TYPE_INT, {1}},590{"dot_vec2", "dot(vec2(1.0), vec2(1.01))", glu::TYPE_FLOAT, 1, 1, glu::TYPE_INT, {2}},591{"dot_vec3", "dot(vec3(1.0), vec3(1.1))", glu::TYPE_FLOAT, 1, 1, glu::TYPE_INT, {3}},592{"dot_vec4", "dot(vec4(1.0), vec4(1.1))", glu::TYPE_FLOAT, 1, 1, glu::TYPE_INT, {4}},593{"normalize_float",594"${T} (1.0) + normalize(2.0)",595glu::TYPE_FLOAT,5961,5971,598glu::TYPE_INT,599{2}},600{"normalize_vec2",601"${T} (1.0) + normalize(vec2(1.0)).x",602glu::TYPE_FLOAT,6031,6041,605glu::TYPE_INT,606{1.0f + deFloatRsq(2.0f)}},607{"normalize_vec3",608"${T} (1.0) + normalize(vec3(1.0)).x",609glu::TYPE_FLOAT,6101,6111,612glu::TYPE_INT,613{1.0f + deFloatRsq(3.0f)}},614{"normalize_vec4",615"${T} (1.0) + normalize(vec4(1.0)).x",616glu::TYPE_FLOAT,6171,6181,619glu::TYPE_INT,620{1.0f + deFloatRsq(4.0f)}},621};622623const char *basicShaderTemplate =624"const ${CASE_BASE_TYPE} cval = ${CASE_EXPRESSION};\n"625"out0 = cval;\n";626627std::vector<tcu::TestNode *> children;628ShaderConstExpr::createTests(m_context, baseCases, DE_LENGTH_OF_ARRAY(baseCases),629basicShaderTemplate, "basic_", children);630631const char *arrayShaderTemplate =632"float array[int(${CASE_EXPRESSION})];\n"633"out0 = array.length();\n";634635ShaderConstExpr::createTests(m_context, arrayCases, DE_LENGTH_OF_ARRAY(arrayCases),636arrayShaderTemplate, "array_", children);637638for (std::size_t i = 0; i < children.size(); i++)639addChild(children[i]);640}641642} // namespace glcts643644645