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 GLES2 shader constant expression tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "es2fShaderConstExprTests.hpp"
25
26 #include "glsShaderLibrary.hpp"
27 #include "glsShaderConstExprTests.hpp"
28
29 #include "tcuStringTemplate.hpp"
30
31 #include "deStringUtil.hpp"
32 #include "deMath.h"
33
34 namespace deqp
35 {
36 namespace gles2
37 {
38 namespace Functional
39 {
40
41 // builtins
42 class ShaderConstExprBuiltinTests : public TestCaseGroup
43 {
44 public:
ShaderConstExprBuiltinTests(Context & context)45 ShaderConstExprBuiltinTests (Context& context) : TestCaseGroup (context, "builtin_functions", "Builtin functions") {}
~ShaderConstExprBuiltinTests(void)46 virtual ~ShaderConstExprBuiltinTests (void) {}
47
48 void init (void);
49
50 void addChildGroup (const char* name, const char* desc, const gls::ShaderConstExpr::TestParams* cases, int numCases);
51 };
52
addChildGroup(const char * name,const char * desc,const gls::ShaderConstExpr::TestParams * cases,int numCases)53 void ShaderConstExprBuiltinTests::addChildGroup (const char* name, const char* desc, const gls::ShaderConstExpr::TestParams* cases, int numCases)
54 {
55 const std::vector<tcu::TestNode*> children = createTests(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), cases, numCases, glu::GLSL_VERSION_100_ES);
56 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(m_testCtx, name, desc);
57
58 addChild(group);
59
60 for (int i = 0; i < (int)children.size(); i++)
61 group->addChild(children[i]);
62 }
63
init(void)64 void ShaderConstExprBuiltinTests::init (void)
65 {
66 using namespace gls::ShaderConstExpr;
67
68 // ${T} => final type, ${MT} => final type but with scalar version usable even when T is a vector
69
70 // Trigonometry
71 {
72 const TestParams cases[] =
73 {
74 {"radians", "radians(${T} (90.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatRadians(90.0f) },
75 {"degrees", "degrees(${T} (2.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatDegrees(2.0f) },
76 {"sin", "sin(${T} (3.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatSin(3.0f) },
77 {"cos", "cos(${T} (3.2))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatCos(3.2f) },
78 {"tan", "tan(${T} (1.5))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatTan(1.5f) },
79 {"asin", "asin(${T} (0.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatAsin(0.0f) },
80 {"acos", "acos(${T} (1.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatAcos(1.0f) },
81 {"atan_separate", "atan(${T} (-1.0), ${T} (-1.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatAtan2(-1.0f, -1.0f) },
82 {"atan_combined", "atan(${T} (2.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatAtanOver(2.0f) },
83 };
84
85 addChildGroup("trigonometry", "Trigonometry", cases, DE_LENGTH_OF_ARRAY(cases));
86 }
87 // Exponential
88 {
89 const TestParams cases[] =
90 {
91 {"pow", "pow(${T} (1.7), ${T} (3.5))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatPow(1.7f, 3.5f) },
92 {"exp", "exp(${T} (4.2))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatExp(4.2f) },
93 {"log", "log(${T} (42.12))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatLog(42.12f) },
94 {"exp2", "exp2(${T} (6.7))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatExp2(6.7f) },
95 {"log2", "log2(${T} (100.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatLog2(100.0f) },
96 {"sqrt", "sqrt(${T} (10.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatSqrt(10.0f) },
97 {"inversesqrt", "inversesqrt(${T} (10.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatRsq(10.0f) },
98 };
99
100 addChildGroup("exponential", "Exponential", cases, DE_LENGTH_OF_ARRAY(cases));
101 }
102 // Common
103 {
104 const TestParams cases[] =
105 {
106 {"abs", "abs(${T} (-42.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, 42.0f },
107 {"sign", "sign(${T} (-18.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, -1.0f },
108 {"floor", "floor(${T} (37.3))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatFloor(37.3f) },
109 {"ceil", "ceil(${T} (82.2))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatCeil(82.2f) },
110 {"fract", "fract(${T} (17.75))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatFrac(17.75f) },
111 {"mod", "mod(${T} (87.65), ${MT} (3.7))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, deFloatMod(87.65f, 3.7f) },
112 {"min", "min(${T} (12.3), ${MT} (32.1))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, 12.3f },
113 {"max", "max(${T} (12.3), ${MT} (32.1))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, 32.1f },
114 {"clamp", "clamp(${T} (42.1), ${MT} (10.0), ${MT} (15.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, 15.0f },
115 {"mix", "mix(${T} (10.0), ${T} (20.0), ${MT}(0.75))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, 17.5f },
116 {"step", "step(${MT} (3.2), ${T} (4.2))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, 1.0f },
117 {"smoothstep", "smoothstep(${MT} (3.0), ${MT} (5.0), ${T} (4.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, 0.5f },
118 };
119
120 addChildGroup("common", "Common", cases, DE_LENGTH_OF_ARRAY(cases));
121 }
122 // Geometric
123 {
124 const TestParams cases[] =
125 {
126 {"length_float", "length(1.0)", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, 1.0f },
127 {"length_vec2", "length(vec2(1.0))", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, deFloatSqrt(2.0f) },
128 {"length_vec3", "length(vec3(1.0))", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, deFloatSqrt(3.0f) },
129 {"length_vec4", "length(vec4(1.0))", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, deFloatSqrt(4.0f) },
130
131 {"distance_float", "distance(1.0, 2.0)", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, 1.0f },
132 {"distance_vec2", "distance(vec2(1.0), vec2(2.0))", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, deFloatSqrt(2.0f) },
133 {"distance_vec3", "distance(vec3(1.0), vec3(2.0))", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, deFloatSqrt(3.0f) },
134 {"distance_vec4", "distance(vec4(1.0), vec4(2.0))", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, deFloatSqrt(4.0f) },
135
136 {"dot_float", "dot(1.0, 1.0)", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, 1.0f },
137 {"dot_vec2", "dot(vec2(1.0), vec2(1.0))", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, 2.0f },
138 {"dot_vec3", "dot(vec3(1.0), vec3(1.0))", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, 3.0f },
139 {"dot_vec4", "dot(vec4(1.0), vec4(1.0))", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, 4.0f },
140
141 {"normalize_float", "normalize(1.0)", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, 1.0f },
142 {"normalize_vec2", "normalize(vec2(1.0)).x", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, deFloatRsq(2.0f) },
143 {"normalize_vec3", "normalize(vec3(1.0)).x", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, deFloatRsq(3.0f) },
144 {"normalize_vec4", "normalize(vec4(1.0)).x", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, deFloatRsq(4.0f) },
145
146 {"faceforward", "faceforward(${T} (1.0), ${T} (1.0), ${T} (1.0))", glu::TYPE_FLOAT, 1, 4, glu::TYPE_FLOAT, -1.0f },
147
148 // reflect(I, N) => I - 2*dot(N, I)*N
149 {"reflect_float", "reflect(1.0, 1.0)", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, -1.0f },
150 {"reflect_vec2", "reflect(vec2(1.0), vec2(1.0, 0.0)).x", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, -1.0f },
151 {"reflect_vec3", "reflect(vec3(1.0), vec3(1.0, 0.0, 0.0)).x", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, -1.0f },
152 {"reflect_vec4", "reflect(vec4(1.0), vec4(1.0, 0.0, 0.0, 0.0)).x", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, -1.0f },
153
154 /*
155 genType refract(genType I, genType N, float eta) =>
156 k = 1.0 - (eta^2)*(1.0-dot(N,I)^2)
157 if k < 0 return 0.0
158 else return eta*I - (eta*dot(N,I) + sqrt(k))*N
159 */
160 {"refract_float", "refract(1.0, 1.0, 0.5)", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, -1.0f },
161 {"refract_vec2", "refract(vec2(1.0), vec2(1.0, 0.0), 0.5).x", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, -1.0f },
162 {"refract_vec3", "refract(vec3(1.0), vec3(1.0, 0.0, 0.0), 0.5).x", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, -1.0f },
163 {"refract_vec4", "refract(vec4(1.0), vec4(1.0, 0.0, 0.0, 0.0), 0.5).x", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, -1.0f },
164 };
165
166 addChildGroup("geometric", "Geometric", cases, DE_LENGTH_OF_ARRAY(cases));
167 }
168 // Matrix
169 {
170 const TestParams cases[] =
171 {
172 {"compMult_mat2", "matrixCompMult(mat2(1.0), mat2(1.0))[0][0]", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, 1.0f },
173 {"compMult_mat3", "matrixCompMult(mat3(1.0), mat3(1.0))[0][0]", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, 1.0f },
174 {"compMult_mat4", "matrixCompMult(mat4(1.0), mat4(1.0))[0][0]", glu::TYPE_FLOAT, 1, 1, glu::TYPE_FLOAT, 1.0f },
175 };
176
177 addChildGroup("matrix", "Matrix", cases, DE_LENGTH_OF_ARRAY(cases));
178 }
179 // Vector relational
180 {
181 const TestParams cases[] =
182 {
183 {"lessThan", "lessThan(${T} (1.0), ${T} (2.0))", glu::TYPE_FLOAT, 2, 4, glu::TYPE_BOOL, 1.0f },
184 {"lessThan", "lessThan(${T} (1), ${T} (2))", glu::TYPE_INT, 2, 4, glu::TYPE_BOOL, 1.0f },
185 {"lessThanEqual", "lessThanEqual(${T} (1.0), ${T} (1.0))", glu::TYPE_FLOAT, 2, 4, glu::TYPE_BOOL, 1.0f },
186 {"lessThanEqual", "lessThanEqual(${T} (1), ${T} (1))", glu::TYPE_INT, 2, 4, glu::TYPE_BOOL, 1.0f },
187 {"greaterThan", "greaterThan(${T} (1.0), ${T} (2.0))", glu::TYPE_FLOAT, 2, 4, glu::TYPE_BOOL, 0.0f },
188 {"greaterThan", "greaterThan(${T} (1), ${T} (2))", glu::TYPE_INT, 2, 4, glu::TYPE_BOOL, 0.0f },
189 {"greaterThanEqual","greaterThanEqual(${T} (1.0), ${T} (2.0))", glu::TYPE_FLOAT, 2, 4, glu::TYPE_BOOL, 0.0f },
190 {"greaterThanEqual","greaterThanEqual(${T} (1), ${T} (2))", glu::TYPE_INT, 2, 4, glu::TYPE_BOOL, 0.0f },
191 {"equal", "equal(${T} (1.0), ${T} (1.2))", glu::TYPE_FLOAT, 2, 4, glu::TYPE_BOOL, 0.0f },
192 {"equal", "equal(${T} (1), ${T} (2))", glu::TYPE_INT, 2, 4, glu::TYPE_BOOL, 0.0f },
193 {"equal", "equal(${T} (true), ${T} (false))", glu::TYPE_BOOL, 2, 4, glu::TYPE_BOOL, 0.0f },
194 {"notEqual", "notEqual(${T} (1.0), ${T} (1.2))", glu::TYPE_FLOAT, 2, 4, glu::TYPE_BOOL, 1.0f },
195 {"notEqual", "notEqual(${T} (1), ${T} (2))", glu::TYPE_INT, 2, 4, glu::TYPE_BOOL, 1.0f },
196 {"notEqual", "notEqual(${T} (true), ${T} (false))", glu::TYPE_BOOL, 2, 4, glu::TYPE_BOOL, 1.0f },
197 {"any_bvec2", "any(bvec2(true, false))", glu::TYPE_BOOL, 1, 1, glu::TYPE_BOOL, 1.0f },
198 {"any_bvec3", "any(bvec3(true, false, false))", glu::TYPE_BOOL, 1, 1, glu::TYPE_BOOL, 1.0f },
199 {"any_bvec4", "any(bvec4(true, false, false, false))", glu::TYPE_BOOL, 1, 1, glu::TYPE_BOOL, 1.0f },
200 {"all_bvec2", "all(bvec2(true, false))", glu::TYPE_BOOL, 1, 1, glu::TYPE_BOOL, 0.0f },
201 {"all_bvec3", "all(bvec3(true, false, false))", glu::TYPE_BOOL, 1, 1, glu::TYPE_BOOL, 0.0f },
202 {"all_bvec4", "all(bvec4(true, false, false, false))", glu::TYPE_BOOL, 1, 1, glu::TYPE_BOOL, 0.0f },
203 {"not", "not(${T} (false))", glu::TYPE_BOOL, 2, 4, glu::TYPE_BOOL, 1.0f }
204 };
205
206 addChildGroup("vector_relational", "Vector relational", cases, DE_LENGTH_OF_ARRAY(cases));
207 }
208 }
209
ShaderConstExprTests(Context & context)210 ShaderConstExprTests::ShaderConstExprTests (Context& context)
211 : TestCaseGroup (context, "constant_expressions", "Constant expressions")
212 {
213 }
214
~ShaderConstExprTests(void)215 ShaderConstExprTests::~ShaderConstExprTests (void)
216 {
217 }
218
219 // all
init(void)220 void ShaderConstExprTests::init (void)
221 {
222 const std::vector<tcu::TestNode*> children = gls::ShaderLibrary(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo()).loadShaderFile("shaders/constant_expressions.test");
223
224 for (int i = 0; i < (int)children.size(); i++)
225 addChild(children[i]);
226
227 addChild(new ShaderConstExprBuiltinTests(m_context));
228
229 // Negative cases.
230 {
231 gls::ShaderLibrary library(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo());
232 std::vector<tcu::TestNode*> negativeCases = library.loadShaderFile("shaders/invalid_constant_expressions.test");
233
234 tcu::TestCaseGroup* group = new tcu::TestCaseGroup(m_testCtx, "invalid", "Invalid constant expressions", negativeCases);
235 addChild(group);
236 }
237 }
238
239 } // Functional
240 } // gles2
241 } // deqp
242