Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 2.0 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 Algorithm implementation tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es2fShaderAlgorithmTests.hpp"
     25 #include "glsShaderRenderCase.hpp"
     26 #include "gluShaderUtil.hpp"
     27 #include "tcuStringTemplate.hpp"
     28 
     29 #include "deInt32.h"
     30 #include "deMemory.h"
     31 
     32 #include <map>
     33 #include <algorithm>
     34 
     35 using namespace std;
     36 using namespace tcu;
     37 using namespace glu;
     38 using namespace deqp::gls;
     39 
     40 namespace deqp
     41 {
     42 namespace gles2
     43 {
     44 namespace Functional
     45 {
     46 
     47 // ShaderAlgorithmCase
     48 
     49 class ShaderAlgorithmCase : public ShaderRenderCase
     50 {
     51 public:
     52 								ShaderAlgorithmCase			(Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, const char* vertShaderSource, const char* fragShaderSource);
     53 	virtual						~ShaderAlgorithmCase		(void);
     54 
     55 private:
     56 								ShaderAlgorithmCase			(const ShaderAlgorithmCase&);	// not allowed!
     57 	ShaderAlgorithmCase&		operator=					(const ShaderAlgorithmCase&);	// not allowed!
     58 };
     59 
     60 ShaderAlgorithmCase::ShaderAlgorithmCase (Context& context, const char* name, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, const char* vertShaderSource, const char* fragShaderSource)
     61 	: ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, description, isVertexCase, evalFunc)
     62 {
     63 	m_vertShaderSource	= vertShaderSource;
     64 	m_fragShaderSource	= fragShaderSource;
     65 }
     66 
     67 ShaderAlgorithmCase::~ShaderAlgorithmCase (void)
     68 {
     69 }
     70 
     71 // Helpers.
     72 
     73 static ShaderAlgorithmCase* createExpressionCase (Context& context, const char* caseName, const char* description, bool isVertexCase, ShaderEvalFunc evalFunc, LineStream& shaderBody)
     74 {
     75 	std::ostringstream vtx;
     76 	std::ostringstream frag;
     77 	std::ostringstream& op = isVertexCase ? vtx : frag;
     78 
     79 	vtx << "attribute highp vec4 a_position;\n";
     80 	vtx << "attribute highp vec4 a_unitCoords;\n";
     81 
     82 	if (isVertexCase)
     83 	{
     84 		vtx << "varying mediump vec3 v_color;\n";
     85 		frag << "varying mediump vec3 v_color;\n";
     86 	}
     87 	else
     88 	{
     89 		vtx << "varying mediump vec4 v_coords;\n";
     90 		frag << "varying mediump vec4 v_coords;\n";
     91 	}
     92 
     93 //	op << "uniform mediump sampler2D ut_brick;\n";
     94 
     95 	vtx << "\n";
     96 	vtx << "void main()\n";
     97 	vtx << "{\n";
     98 	vtx << "	gl_Position = a_position;\n";
     99 
    100 	frag << "\n";
    101 	frag << "void main()\n";
    102 	frag << "{\n";
    103 
    104 	// Write matrix.
    105 	if (isVertexCase)
    106 		op << "	${PRECISION} vec4 coords = a_unitCoords;\n";
    107 	else
    108 		op << "	${PRECISION} vec4 coords = v_coords;\n";
    109 
    110 	op << "	${PRECISION} vec3 res = vec3(0.0);\n";
    111 	op << shaderBody.str();
    112 
    113 	if (isVertexCase)
    114 	{
    115 		vtx << "	v_color = res;\n";
    116 		frag << "	gl_FragColor = vec4(v_color, 1.0);\n";
    117 	}
    118 	else
    119 	{
    120 		vtx << "	v_coords = a_unitCoords;\n";
    121 		frag << "	gl_FragColor = vec4(res, 1.0);\n";
    122 	}
    123 
    124 	vtx << "}\n";
    125 	frag << "}\n";
    126 
    127 	// Fill in shader templates.
    128 	map<string, string> params;
    129 	params.insert(pair<string, string>("PRECISION", "mediump"));
    130 
    131 	StringTemplate vertTemplate(vtx.str().c_str());
    132 	StringTemplate fragTemplate(frag.str().c_str());
    133 	string vertexShaderSource = vertTemplate.specialize(params);
    134 	string fragmentShaderSource = fragTemplate.specialize(params);
    135 
    136 	return new ShaderAlgorithmCase(context, caseName, description, isVertexCase, evalFunc, vertexShaderSource.c_str(), fragmentShaderSource.c_str());
    137 }
    138 
    139 // ShaderAlgorithmTests.
    140 
    141 ShaderAlgorithmTests::ShaderAlgorithmTests(Context& context)
    142 	: TestCaseGroup(context, "algorithm", "Miscellaneous algorithm implementations using shaders.")
    143 {
    144 }
    145 
    146 ShaderAlgorithmTests::~ShaderAlgorithmTests (void)
    147 {
    148 }
    149 
    150 void ShaderAlgorithmTests::init (void)
    151 {
    152 //	TestCaseGroup* colorGroup = new TestCaseGroup(m_testCtx, "color", "Miscellaneous color related algorithm tests.");
    153 //	addChild(colorGroup);
    154 
    155 	#define SHADER_OP_CASE(NAME, DESCRIPTION, SHADER_OP, EVAL_FUNC_BODY)														\
    156 		do {																													\
    157 			struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY };										\
    158 			addChild(createExpressionCase(m_context, #NAME "_vertex", DESCRIPTION, true, &Eval_##NAME::eval, SHADER_OP));		\
    159 			addChild(createExpressionCase(m_context, #NAME "_fragment", DESCRIPTION, false, &Eval_##NAME::eval, SHADER_OP));	\
    160 		} while (deGetFalse())
    161 
    162 	SHADER_OP_CASE(hsl_to_rgb, "Conversion from HSL color space into RGB.",
    163 		LineStream(1)
    164 		<< "mediump float H = coords.x, S = coords.y, L = coords.z;"
    165 		<< "mediump float v = (L <= 0.5) ? (L * (1.0 + S)) : (L + S - L * S);"
    166 		<< "res = vec3(L); // default to gray"
    167 		<< "if (v > 0.0)"
    168 		<< "{"
    169 		<< "	mediump float m = L + L - v;"
    170 		<< "	mediump float sv = (v - m) / v;"
    171 		<< "	H *= 6.0;"
    172 		<< "	mediump int sextant = int(H);"
    173 		<< "	mediump float fract = H - float(sextant);"
    174 		<< "	mediump float vsf = v * sv * fract;"
    175 		<< "	mediump float mid1 = m + vsf;"
    176 		<< "	mediump float mid2 = m - vsf;"
    177 		<< "	if (sextant == 0)      res = vec3(v, mid1, m);"
    178 		<< "	else if (sextant == 1) res = vec3(mid2, v, m);"
    179 		<< "	else if (sextant == 2) res = vec3(m, v, mid1);"
    180 		<< "	else if (sextant == 3) res = vec3(m, mid2, v);"
    181 		<< "	else if (sextant == 4) res = vec3(mid1, m, v);"
    182 		<< "	else                   res = vec3(v, m, mid2);"
    183 		<< "}",
    184 		{
    185 			float H = c.unitCoords.x();
    186 			float S = c.unitCoords.y();
    187 			float L = c.unitCoords.z();
    188 			Vec3 rgb = Vec3(L);
    189 			float v = (L <= 0.5f) ? (L * (1.0f + S)) : (L + S - L * S);
    190 			if (v > 0.0f)
    191 			{
    192 				float m = L + L - v;
    193 				float sv = (v - m) / v;
    194 				H *= 6.0f;
    195 				int sextant = int(H);
    196 				float fract = H - float(sextant);
    197 				float vsf = v * sv * fract;
    198 				float mid1 = m + vsf;
    199 				float mid2 = m - vsf;
    200 				if (sextant == 0)		rgb = Vec3(v, mid1, m);
    201 				else if (sextant == 1)	rgb = Vec3(mid2, v, m);
    202 				else if (sextant == 2)	rgb = Vec3(m, v, mid1);
    203 				else if (sextant == 3)	rgb = Vec3(m, mid2, v);
    204 				else if (sextant == 4)	rgb = Vec3(mid1, m, v);
    205 				else					rgb = Vec3(v, m, mid2);
    206 			}
    207 			c.color.xyz() = rgb;
    208 		});
    209 
    210 	SHADER_OP_CASE(rgb_to_hsl, "Conversion from RGB color space into HSL.",
    211 		LineStream(1)
    212 		<< "mediump float r = coords.x, g = coords.y, b = coords.z;"
    213 		<< "mediump float minVal = min(min(r, g), b);"
    214 		<< "mediump float maxVal = max(max(r, g), b);"
    215 		<< "mediump float L = (minVal + maxVal) * 0.5;"
    216 		<< "if (minVal == maxVal)"
    217 		<< "	res = vec3(0.0, 0.0, L);"
    218 		<< "else"
    219 		<< "{"
    220 		<< "	mediump float H;"
    221 		<< "	mediump float S;"
    222 		<< "	if (L < 0.5)"
    223 		<< "		S = (maxVal - minVal) / (maxVal + minVal);"
    224 		<< "	else"
    225 		<< "		S = (maxVal - minVal) / (2.0 - maxVal - minVal);"
    226 		<< ""
    227 		<< "	mediump float ooDiff = 1.0 / (maxVal - minVal);"
    228 		<< "	if (r == maxVal)      H = (g - b) * ooDiff;"
    229 		<< "	else if (g == maxVal) H = 2.0 + (b - r) * ooDiff;"
    230 		<< "	else                  H = 4.0 + (r - g) * ooDiff;"
    231 		<< "	H /= 6.0;"
    232 		<< ""
    233 		<< "	res = vec3(H, S, L);"
    234 		<< "}",
    235 		{
    236 			float r = c.unitCoords.x();
    237 			float g = c.unitCoords.y();
    238 			float b = c.unitCoords.z();
    239 			float minVal = min(min(r, g), b);
    240 			float maxVal = max(max(r, g), b);
    241 			float L = (minVal + maxVal) * 0.5f;
    242 			Vec3 hsl;
    243 
    244 			if (minVal == maxVal)
    245 				hsl = Vec3(0.0f, 0.0f, L);
    246 			else
    247 			{
    248 				float H;
    249 				float S;
    250 				if (L < 0.5f)
    251 					S = (maxVal - minVal) / (maxVal + minVal);
    252 				else
    253 					S = (maxVal - minVal) / (2.0f - maxVal - minVal);
    254 
    255 				float ooDiff = 1.0f / (maxVal - minVal);
    256 				if (r == maxVal)		H = (g - b) * ooDiff;
    257 				else if (g == maxVal)	H = 2.0f + (b - r) * ooDiff;
    258 				else					H = 4.0f + (r - g) * ooDiff;
    259 				H /= 6.0f;
    260 
    261 				hsl = Vec3(H, S, L);
    262 			}
    263 			c.color.xyz() = hsl;
    264 		});
    265 
    266 /*	SHADER_OP_CASE(image_to_grayscale, "Convert image to grayscale.",
    267 		LineStream(1)
    268 		<< "res = texture2D(ut_brick, coords.xy).rgb;",
    269 		{
    270 			c.color.xyz() = Vec3(0.5f);
    271 		});*/
    272 }
    273 
    274 } // Functional
    275 } // gles2
    276 } // deqp
    277