Home | History | Annotate | Download | only in glshared
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL Shared Module
      3  * -------------------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Shared shader constant expression test components
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "glsShaderConstExprTests.hpp"
     25 #include "glsShaderLibrary.hpp"
     26 #include "glsShaderLibraryCase.hpp"
     27 
     28 #include "tcuStringTemplate.hpp"
     29 
     30 #include "deStringUtil.hpp"
     31 #include "deMath.h"
     32 
     33 namespace deqp
     34 {
     35 namespace gls
     36 {
     37 namespace ShaderConstExpr
     38 {
     39 
     40 std::vector<tcu::TestNode*> createTests (tcu::TestContext&			testContext,
     41 										 glu::RenderContext&		renderContext,
     42 										 const glu::ContextInfo&	contextInfo,
     43 										 const TestParams*			cases,
     44 										 int						numCases,
     45 										 glu::GLSLVersion			version,
     46 										 TestShaderStage			testStage)
     47 {
     48 	using std::string;
     49 	using std::vector;
     50 	using gls::sl::ShaderCase;
     51 
     52 	// Needed for autogenerating shader code for increased component counts
     53 	DE_STATIC_ASSERT(glu::TYPE_FLOAT+1 == glu::TYPE_FLOAT_VEC2);
     54 	DE_STATIC_ASSERT(glu::TYPE_FLOAT+2 == glu::TYPE_FLOAT_VEC3);
     55 	DE_STATIC_ASSERT(glu::TYPE_FLOAT+3 == glu::TYPE_FLOAT_VEC4);
     56 
     57 	DE_STATIC_ASSERT(glu::TYPE_INT+1 == glu::TYPE_INT_VEC2);
     58 	DE_STATIC_ASSERT(glu::TYPE_INT+2 == glu::TYPE_INT_VEC3);
     59 	DE_STATIC_ASSERT(glu::TYPE_INT+3 == glu::TYPE_INT_VEC4);
     60 
     61 	DE_STATIC_ASSERT(glu::TYPE_UINT+1 == glu::TYPE_UINT_VEC2);
     62 	DE_STATIC_ASSERT(glu::TYPE_UINT+2 == glu::TYPE_UINT_VEC3);
     63 	DE_STATIC_ASSERT(glu::TYPE_UINT+3 == glu::TYPE_UINT_VEC4);
     64 
     65 	DE_STATIC_ASSERT(glu::TYPE_BOOL+1 == glu::TYPE_BOOL_VEC2);
     66 	DE_STATIC_ASSERT(glu::TYPE_BOOL+2 == glu::TYPE_BOOL_VEC3);
     67 	DE_STATIC_ASSERT(glu::TYPE_BOOL+3 == glu::TYPE_BOOL_VEC4);
     68 
     69 	DE_ASSERT(testStage);
     70 
     71 	const char* shaderTemplateSrc =
     72 		"#version ${GLES_VERSION}\n"
     73 		"precision highp float;\n"
     74 		"precision highp int;\n"
     75 		"${DECLARATIONS}\n"
     76 		"void main()\n"
     77 		"{\n"
     78 		"	const ${CASE_BASE_TYPE} cval = ${CASE_EXPRESSION};\n"
     79 		"	out0 = cval;\n"
     80 		"	${OUTPUT}\n"
     81 		"}\n";
     82 
     83 	const tcu::StringTemplate		shaderTemplate	(shaderTemplateSrc);
     84 	vector<tcu::TestNode*>			ret;
     85 	vector<ShaderCase::ValueBlock>	shaderOutput	(1);
     86 
     87 	shaderOutput[0].arrayLength = 1;
     88 	shaderOutput[0].values.push_back(ShaderCase::Value());
     89 	shaderOutput[0].values[0].storageType		= ShaderCase::Value::STORAGE_OUTPUT;
     90 	shaderOutput[0].values[0].valueName			= "out0";
     91 	shaderOutput[0].values[0].dataType			= glu::TYPE_FLOAT;
     92 	shaderOutput[0].values[0].arrayLength		= 1;
     93 	shaderOutput[0].values[0].elements.push_back(ShaderCase::Value::Element());
     94 
     95 	for (int caseNdx = 0; caseNdx < numCases; caseNdx++)
     96 	{
     97 		std::map<string, string>	shaderTemplateParams;
     98 		const int					minComponents	= cases[caseNdx].minComponents;
     99 		const int					maxComponents	= cases[caseNdx].maxComponents;
    100 		const DataType				inType			= cases[caseNdx].inType;
    101 		const DataType				outType			= cases[caseNdx].outType;
    102 		const string				expression		= cases[caseNdx].expression;
    103 		// Check for presence of func(vec, scalar) style specialization, use as gatekeeper for applying said specialization
    104 		const bool					alwaysScalar	= expression.find("${MT}")!=string::npos;
    105 		ShaderCase::Value&			expected		= shaderOutput[0].values[0];
    106 
    107 		switch (outType)
    108 		{
    109 			case glu::TYPE_INT:
    110 				expected.elements[0].int32 = (int)cases[caseNdx].output;
    111 				break;
    112 
    113 			case glu::TYPE_UINT:
    114 				expected.elements[0].int32 = (unsigned int)cases[caseNdx].output;
    115 				break;
    116 
    117 			case glu::TYPE_BOOL:
    118 				expected.elements[0].bool32 = cases[caseNdx].output!=0.0f;
    119 				break;
    120 
    121 			case glu::TYPE_FLOAT:
    122 				expected.elements[0].float32 = cases[caseNdx].output;
    123 				break;
    124 
    125 			default:
    126 				DE_ASSERT(false);
    127 		}
    128 
    129 		expected.dataType = outType;
    130 
    131 		shaderTemplateParams["GLES_VERSION"]	= version == glu::GLSL_VERSION_300_ES ? "300 es" : "100";
    132 		shaderTemplateParams["CASE_BASE_TYPE"]	= glu::getDataTypeName(outType);
    133 		shaderTemplateParams["DECLARATIONS"]	= "${DECLARATIONS}";
    134 		shaderTemplateParams["OUTPUT"]			= "${OUTPUT}";
    135 
    136 		for (int compCount = minComponents-1; compCount < maxComponents; compCount++)
    137 		{
    138 			vector<tcu::TestNode*>		children;
    139 			std::map<string, string>	expressionTemplateParams;
    140 			string						typeName			= glu::getDataTypeName((glu::DataType)(inType + compCount)); // results in float, vec2, vec3, vec4 progression (same for other primitive types)
    141 			const char*					componentAccess[]	= {"", ".y", ".z", ".w"};
    142 			const tcu::StringTemplate	expressionTemplate	(expression);
    143 			// Add type to case name if we are generating multiple versions
    144 			const string				caseName			= string(cases[caseNdx].name) + (minComponents==maxComponents ? "" : ("_" + typeName));
    145 
    146 			// ${T} => final type, ${MT} => final type but with scalar version usable even when T is a vector
    147 			expressionTemplateParams["T"]			= typeName;
    148 			expressionTemplateParams["MT"]			= typeName;
    149 
    150 			shaderTemplateParams["CASE_EXPRESSION"]	= expressionTemplate.specialize(expressionTemplateParams) + componentAccess[compCount]; // Add vector access to expression as needed
    151 
    152 			{
    153 				const string mapped = shaderTemplate.specialize(shaderTemplateParams);
    154 
    155 				if (testStage & SHADER_VERTEX)
    156 					ret.push_back(new ShaderCase(testContext,
    157 												 renderContext,
    158 												 contextInfo,
    159 												 (caseName + "_vertex").c_str(),
    160 												 "",
    161 												 ShaderCase::ShaderCaseSpecification::generateSharedSourceVertexCase(ShaderCase::EXPECT_PASS,
    162 																													 version,
    163 																													 shaderOutput,
    164 																													 mapped)));
    165 
    166 				if (testStage & SHADER_FRAGMENT)
    167 					ret.push_back(new ShaderCase(testContext,
    168 												 renderContext,
    169 												 contextInfo,
    170 												 (caseName + "_fragment").c_str(),
    171 												 "",
    172 												 ShaderCase::ShaderCaseSpecification::generateSharedSourceFragmentCase(ShaderCase::EXPECT_PASS,
    173 																													   version,
    174 																													   shaderOutput,
    175 																													   mapped)));
    176 			}
    177 
    178 			// Deal with functions that allways accept one ore more scalar parameters even when others are vectors
    179 			if (alwaysScalar && compCount > 0)
    180 			{
    181 				const string	scalarCaseName	= string(cases[caseNdx].name) + "_" + typeName + "_" + glu::getDataTypeName(inType);
    182 
    183 				expressionTemplateParams["MT"] = glu::getDataTypeName(inType);
    184 				shaderTemplateParams["CASE_EXPRESSION"]	= expressionTemplate.specialize(expressionTemplateParams) + componentAccess[compCount];
    185 
    186 				{
    187 					const string mapped = shaderTemplate.specialize(shaderTemplateParams);
    188 
    189 					if (testStage & SHADER_VERTEX)
    190 						ret.push_back(new ShaderCase(testContext,
    191 													 renderContext,
    192 													 contextInfo,
    193 													 (scalarCaseName + "_vertex").c_str(),
    194 													 "",
    195 													 ShaderCase::ShaderCaseSpecification::generateSharedSourceVertexCase(ShaderCase::EXPECT_PASS,
    196 																														 version,
    197 																														 shaderOutput,
    198 																														 mapped)));
    199 
    200 					if (testStage & SHADER_FRAGMENT)
    201 						ret.push_back(new ShaderCase(testContext,
    202 													 renderContext,
    203 													 contextInfo,
    204 													 (scalarCaseName + "_fragment").c_str(),
    205 													 "",
    206 													 ShaderCase::ShaderCaseSpecification::generateSharedSourceFragmentCase(ShaderCase::EXPECT_PASS,
    207 																														   version,
    208 																														   shaderOutput,
    209 																														   mapped)));
    210 				}
    211 			}
    212 		}
    213 	}
    214 
    215 	return ret;
    216 }
    217 
    218 } // ShaderConstExpr
    219 } // gls
    220 } // deqp
    221