1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // DebugShaderPrecision_test.cpp:
7 // Tests for writing the code for shader precision emulation.
8 //
9
10 #include "GLSLANG/ShaderLang.h"
11 #include "angle_gl.h"
12 #include "gtest/gtest.h"
13 #include "tests/test_utils/compiler_test.h"
14
15 using namespace sh;
16
17 class DebugShaderPrecisionTest : public MatchOutputCodeTest
18 {
19 public:
DebugShaderPrecisionTest()20 DebugShaderPrecisionTest() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, 0, SH_ESSL_OUTPUT)
21 {
22 addOutputType(SH_GLSL_COMPATIBILITY_OUTPUT);
23 #if defined(ANGLE_ENABLE_HLSL)
24 addOutputType(SH_HLSL_4_1_OUTPUT);
25 #endif
26 getResources()->WEBGL_debug_shader_precision = 1;
27 }
28
29 protected:
foundInAllGLSLCode(const char * str)30 bool foundInAllGLSLCode(const char *str)
31 {
32 return foundInCode(SH_GLSL_COMPATIBILITY_OUTPUT, str) && foundInCode(SH_ESSL_OUTPUT, str);
33 }
34
foundInHLSLCode(const char * stringToFind) const35 bool foundInHLSLCode(const char *stringToFind) const
36 {
37 #if defined(ANGLE_ENABLE_HLSL)
38 return foundInCode(SH_HLSL_4_1_OUTPUT, stringToFind);
39 #else
40 return true;
41 #endif
42 }
43
foundInHLSLCodeRegex(const char * regexToFind) const44 bool foundInHLSLCodeRegex(const char *regexToFind) const
45 {
46 #if defined(ANGLE_ENABLE_HLSL)
47 return foundInCodeRegex(SH_HLSL_4_1_OUTPUT, std::regex(regexToFind));
48 #else
49 return true;
50 #endif
51 }
52 };
53
54 class NoDebugShaderPrecisionTest : public MatchOutputCodeTest
55 {
56 public:
NoDebugShaderPrecisionTest()57 NoDebugShaderPrecisionTest()
58 : MatchOutputCodeTest(GL_FRAGMENT_SHADER, 0, SH_GLSL_COMPATIBILITY_OUTPUT)
59 {}
60 };
61
TEST_F(DebugShaderPrecisionTest,RoundingFunctionsDefined)62 TEST_F(DebugShaderPrecisionTest, RoundingFunctionsDefined)
63 {
64 const std::string &shaderString =
65 "precision mediump float;\n"
66 "uniform float u;\n"
67 "void main() {\n"
68 " gl_FragColor = vec4(u);\n"
69 "}\n";
70 compile(shaderString);
71 ASSERT_TRUE(foundInESSLCode("highp float angle_frm(in highp float"));
72 ASSERT_TRUE(foundInESSLCode("highp vec2 angle_frm(in highp vec2"));
73 ASSERT_TRUE(foundInESSLCode("highp vec3 angle_frm(in highp vec3"));
74 ASSERT_TRUE(foundInESSLCode("highp vec4 angle_frm(in highp vec4"));
75 ASSERT_TRUE(foundInESSLCode("highp mat2 angle_frm(in highp mat2"));
76 ASSERT_TRUE(foundInESSLCode("highp mat3 angle_frm(in highp mat3"));
77 ASSERT_TRUE(foundInESSLCode("highp mat4 angle_frm(in highp mat4"));
78
79 ASSERT_TRUE(foundInESSLCode("highp float angle_frl(in highp float"));
80 ASSERT_TRUE(foundInESSLCode("highp vec2 angle_frl(in highp vec2"));
81 ASSERT_TRUE(foundInESSLCode("highp vec3 angle_frl(in highp vec3"));
82 ASSERT_TRUE(foundInESSLCode("highp vec4 angle_frl(in highp vec4"));
83 ASSERT_TRUE(foundInESSLCode("highp mat2 angle_frl(in highp mat2"));
84 ASSERT_TRUE(foundInESSLCode("highp mat3 angle_frl(in highp mat3"));
85 ASSERT_TRUE(foundInESSLCode("highp mat4 angle_frl(in highp mat4"));
86
87 ASSERT_TRUE(foundInGLSLCode("float angle_frm(in float"));
88 ASSERT_TRUE(foundInGLSLCode("vec2 angle_frm(in vec2"));
89 ASSERT_TRUE(foundInGLSLCode("vec3 angle_frm(in vec3"));
90 ASSERT_TRUE(foundInGLSLCode("vec4 angle_frm(in vec4"));
91 ASSERT_TRUE(foundInGLSLCode("mat2 angle_frm(in mat2"));
92 ASSERT_TRUE(foundInGLSLCode("mat3 angle_frm(in mat3"));
93 ASSERT_TRUE(foundInGLSLCode("mat4 angle_frm(in mat4"));
94
95 ASSERT_TRUE(foundInGLSLCode("float angle_frl(in float"));
96 ASSERT_TRUE(foundInGLSLCode("vec2 angle_frl(in vec2"));
97 ASSERT_TRUE(foundInGLSLCode("vec3 angle_frl(in vec3"));
98 ASSERT_TRUE(foundInGLSLCode("vec4 angle_frl(in vec4"));
99 ASSERT_TRUE(foundInGLSLCode("mat2 angle_frl(in mat2"));
100 ASSERT_TRUE(foundInGLSLCode("mat3 angle_frl(in mat3"));
101 ASSERT_TRUE(foundInGLSLCode("mat4 angle_frl(in mat4"));
102
103 ASSERT_TRUE(foundInHLSLCode("float1 angle_frm(float1"));
104 ASSERT_TRUE(foundInHLSLCode("float2 angle_frm(float2"));
105 ASSERT_TRUE(foundInHLSLCode("float3 angle_frm(float3"));
106 ASSERT_TRUE(foundInHLSLCode("float4 angle_frm(float4"));
107 ASSERT_TRUE(foundInHLSLCode("float2x2 angle_frm(float2x2"));
108 ASSERT_TRUE(foundInHLSLCode("float3x3 angle_frm(float3x3"));
109 ASSERT_TRUE(foundInHLSLCode("float4x4 angle_frm(float4x4"));
110
111 ASSERT_TRUE(foundInHLSLCode("float1 angle_frl(float1"));
112 ASSERT_TRUE(foundInHLSLCode("float2 angle_frl(float2"));
113 ASSERT_TRUE(foundInHLSLCode("float3 angle_frl(float3"));
114 ASSERT_TRUE(foundInHLSLCode("float4 angle_frl(float4"));
115 ASSERT_TRUE(foundInHLSLCode("float2x2 angle_frl(float2x2"));
116 ASSERT_TRUE(foundInHLSLCode("float3x3 angle_frl(float3x3"));
117 ASSERT_TRUE(foundInHLSLCode("float4x4 angle_frl(float4x4"));
118
119 // Check that ESSL 3.00 rounding functions for non-square matrices are not defined.
120 ASSERT_TRUE(notFoundInCode("mat2x"));
121 ASSERT_TRUE(notFoundInCode("mat3x"));
122 ASSERT_TRUE(notFoundInCode("mat4x"));
123 }
124
125 // Test that all ESSL 3.00 shaders get rounding function definitions for non-square matrices.
TEST_F(DebugShaderPrecisionTest,NonSquareMatrixRoundingFunctionsDefinedES3)126 TEST_F(DebugShaderPrecisionTest, NonSquareMatrixRoundingFunctionsDefinedES3)
127 {
128 const std::string &shaderString =
129 "#version 300 es\n"
130 "precision mediump float;\n"
131 "uniform float u;\n"
132 "out vec4 my_FragColor;\n"
133 "void main() {\n"
134 " my_FragColor = vec4(u);\n"
135 "}\n";
136 compile(shaderString);
137 ASSERT_TRUE(foundInESSLCode("highp mat2x3 angle_frm(in highp mat2x3"));
138 ASSERT_TRUE(foundInESSLCode("highp mat2x4 angle_frm(in highp mat2x4"));
139 ASSERT_TRUE(foundInESSLCode("highp mat3x2 angle_frm(in highp mat3x2"));
140 ASSERT_TRUE(foundInESSLCode("highp mat3x4 angle_frm(in highp mat3x4"));
141 ASSERT_TRUE(foundInESSLCode("highp mat4x2 angle_frm(in highp mat4x2"));
142 ASSERT_TRUE(foundInESSLCode("highp mat4x3 angle_frm(in highp mat4x3"));
143
144 ASSERT_TRUE(foundInESSLCode("highp mat2x3 angle_frl(in highp mat2x3"));
145 ASSERT_TRUE(foundInESSLCode("highp mat2x4 angle_frl(in highp mat2x4"));
146 ASSERT_TRUE(foundInESSLCode("highp mat3x2 angle_frl(in highp mat3x2"));
147 ASSERT_TRUE(foundInESSLCode("highp mat3x4 angle_frl(in highp mat3x4"));
148 ASSERT_TRUE(foundInESSLCode("highp mat4x2 angle_frl(in highp mat4x2"));
149 ASSERT_TRUE(foundInESSLCode("highp mat4x3 angle_frl(in highp mat4x3"));
150
151 ASSERT_TRUE(foundInGLSLCode("mat2x3 angle_frm(in mat2x3"));
152 ASSERT_TRUE(foundInGLSLCode("mat2x4 angle_frm(in mat2x4"));
153 ASSERT_TRUE(foundInGLSLCode("mat3x2 angle_frm(in mat3x2"));
154 ASSERT_TRUE(foundInGLSLCode("mat3x4 angle_frm(in mat3x4"));
155 ASSERT_TRUE(foundInGLSLCode("mat4x2 angle_frm(in mat4x2"));
156 ASSERT_TRUE(foundInGLSLCode("mat4x3 angle_frm(in mat4x3"));
157
158 ASSERT_TRUE(foundInGLSLCode("mat2x3 angle_frl(in mat2x3"));
159 ASSERT_TRUE(foundInGLSLCode("mat2x4 angle_frl(in mat2x4"));
160 ASSERT_TRUE(foundInGLSLCode("mat3x2 angle_frl(in mat3x2"));
161 ASSERT_TRUE(foundInGLSLCode("mat3x4 angle_frl(in mat3x4"));
162 ASSERT_TRUE(foundInGLSLCode("mat4x2 angle_frl(in mat4x2"));
163 ASSERT_TRUE(foundInGLSLCode("mat4x3 angle_frl(in mat4x3"));
164
165 ASSERT_TRUE(foundInHLSLCode("float2x3 angle_frm(float2x3"));
166 ASSERT_TRUE(foundInHLSLCode("float2x4 angle_frm(float2x4"));
167 ASSERT_TRUE(foundInHLSLCode("float3x2 angle_frm(float3x2"));
168 ASSERT_TRUE(foundInHLSLCode("float3x4 angle_frm(float3x4"));
169 ASSERT_TRUE(foundInHLSLCode("float4x2 angle_frm(float4x2"));
170 ASSERT_TRUE(foundInHLSLCode("float4x3 angle_frm(float4x3"));
171
172 ASSERT_TRUE(foundInHLSLCode("float2x3 angle_frl(float2x3"));
173 ASSERT_TRUE(foundInHLSLCode("float2x4 angle_frl(float2x4"));
174 ASSERT_TRUE(foundInHLSLCode("float3x2 angle_frl(float3x2"));
175 ASSERT_TRUE(foundInHLSLCode("float3x4 angle_frl(float3x4"));
176 ASSERT_TRUE(foundInHLSLCode("float4x2 angle_frl(float4x2"));
177 ASSERT_TRUE(foundInHLSLCode("float4x3 angle_frl(float4x3"));
178 }
179
TEST_F(DebugShaderPrecisionTest,PragmaDisablesEmulation)180 TEST_F(DebugShaderPrecisionTest, PragmaDisablesEmulation)
181 {
182 const std::string &shaderString =
183 "#pragma webgl_debug_shader_precision(off)\n"
184 "precision mediump float;\n"
185 "uniform float u;\n"
186 "void main() {\n"
187 " gl_FragColor = vec4(u);\n"
188 "}\n";
189 compile(shaderString);
190 ASSERT_TRUE(notFoundInCode("angle_frm"));
191 const std::string &shaderStringPragmaOn =
192 "#pragma webgl_debug_shader_precision(on)\n"
193 "precision mediump float;\n"
194 "uniform float u;\n"
195 "void main() {\n"
196 " gl_FragColor = vec4(u);\n"
197 "}\n";
198 compile(shaderStringPragmaOn);
199 ASSERT_TRUE(foundInCode("angle_frm"));
200 }
201
202 // Emulation can't be toggled on for only a part of a shader.
203 // Only the last pragma in the shader has an effect.
TEST_F(DebugShaderPrecisionTest,MultiplePragmas)204 TEST_F(DebugShaderPrecisionTest, MultiplePragmas)
205 {
206 const std::string &shaderString =
207 "#pragma webgl_debug_shader_precision(off)\n"
208 "precision mediump float;\n"
209 "uniform float u;\n"
210 "void main() {\n"
211 " gl_FragColor = vec4(u);\n"
212 "}\n"
213 "#pragma webgl_debug_shader_precision(on)\n";
214 compile(shaderString);
215 ASSERT_TRUE(foundInCode("angle_frm"));
216 }
217
TEST_F(NoDebugShaderPrecisionTest,HelpersWrittenOnlyWithExtension)218 TEST_F(NoDebugShaderPrecisionTest, HelpersWrittenOnlyWithExtension)
219 {
220 const std::string &shaderString =
221 "precision mediump float;\n"
222 "uniform float u;\n"
223 "void main() {\n"
224 " gl_FragColor = vec4(u);\n"
225 "}\n";
226 compile(shaderString);
227 ASSERT_FALSE(foundInCode("angle_frm"));
228 }
229
TEST_F(NoDebugShaderPrecisionTest,PragmaHasEffectsOnlyWithExtension)230 TEST_F(NoDebugShaderPrecisionTest, PragmaHasEffectsOnlyWithExtension)
231 {
232 const std::string &shaderString =
233 "#pragma webgl_debug_shader_precision(on)\n"
234 "precision mediump float;\n"
235 "uniform float u;\n"
236 "void main() {\n"
237 " gl_FragColor = vec4(u);\n"
238 "}\n";
239 compile(shaderString);
240 ASSERT_FALSE(foundInCode("angle_frm"));
241 }
242
TEST_F(DebugShaderPrecisionTest,DeclarationsAndConstants)243 TEST_F(DebugShaderPrecisionTest, DeclarationsAndConstants)
244 {
245 const std::string &shaderString =
246 "precision mediump float;\n"
247 "uniform vec4 f;\n"
248 "uniform float uu, uu2;\n"
249 "varying float vv, vv2;\n"
250 "float gg = 0.0, gg2;\n"
251 "void main() {\n"
252 " float aa = 0.0, aa2;\n"
253 " gl_FragColor = f;\n"
254 "}\n";
255 compile(shaderString);
256 // Declarations or constants should not have rounding inserted around them
257 ASSERT_TRUE(notFoundInCode("angle_frm(0"));
258 // GLSL output
259 ASSERT_TRUE(notFoundInCode("angle_frm(_uuu"));
260 ASSERT_TRUE(notFoundInCode("angle_frm(_uvv"));
261 ASSERT_TRUE(notFoundInCode("angle_frm(_ugg"));
262 ASSERT_TRUE(notFoundInCode("angle_frm(_uaa"));
263 // HLSL output
264 ASSERT_TRUE(notFoundInCode("angle_frm(_uu"));
265 ASSERT_TRUE(notFoundInCode("angle_frm(_vv"));
266 ASSERT_TRUE(notFoundInCode("angle_frm(_gg"));
267 ASSERT_TRUE(notFoundInCode("angle_frm(_aa"));
268 }
269
270 // Test that expressions that are part of initialization have rounding.
TEST_F(DebugShaderPrecisionTest,InitializerRounding)271 TEST_F(DebugShaderPrecisionTest, InitializerRounding)
272 {
273 const std::string &shaderString =
274 "precision mediump float;\n"
275 "uniform float u;\n"
276 "void main() {\n"
277 " float a = u;\n"
278 " gl_FragColor = vec4(a);\n"
279 "}\n";
280 compile(shaderString);
281 // An expression that's part of initialization should have rounding
282 ASSERT_TRUE(foundInAllGLSLCode("angle_frm(_uu)"));
283 ASSERT_TRUE(foundInHLSLCode("angle_frm(_u)"));
284 }
285
286 // Test that compound additions have rounding in the GLSL translations.
TEST_F(DebugShaderPrecisionTest,CompoundAddFunction)287 TEST_F(DebugShaderPrecisionTest, CompoundAddFunction)
288 {
289 const std::string &shaderString =
290 "precision mediump float;\n"
291 "uniform vec4 u;\n"
292 "uniform vec4 u2;\n"
293 "void main() {\n"
294 " vec4 v = u;\n"
295 " v += u2;\n"
296 " gl_FragColor = v;\n"
297 "}\n";
298 compile(shaderString);
299 ASSERT_TRUE(
300 foundInESSLCode("highp vec4 angle_compound_add_frm(inout highp vec4 x, in highp vec4 y) {\n"
301 " x = angle_frm(angle_frm(x) + y);"));
302 ASSERT_TRUE(
303 foundInGLSLCode("vec4 angle_compound_add_frm(inout vec4 x, in vec4 y) {\n"
304 " x = angle_frm(angle_frm(x) + y);"));
305 ASSERT_TRUE(
306 foundInHLSLCode("float4 angle_compound_add_frm(inout float4 x, in float4 y) {\n"
307 " x = angle_frm(angle_frm(x) + y);"));
308 ASSERT_TRUE(foundInAllGLSLCode("angle_compound_add_frm(_uv, angle_frm(_uu2));"));
309 ASSERT_TRUE(foundInHLSLCodeRegex(R"(angle_compound_add_frm\(_v(\d)*, angle_frm\(_u2\)\);)"));
310 ASSERT_TRUE(notFoundInCode("+="));
311 }
312
TEST_F(DebugShaderPrecisionTest,CompoundSubFunction)313 TEST_F(DebugShaderPrecisionTest, CompoundSubFunction)
314 {
315 const std::string &shaderString =
316 "precision mediump float;\n"
317 "uniform vec4 u;\n"
318 "uniform vec4 u2;\n"
319 "void main() {\n"
320 " vec4 v = u;\n"
321 " v -= u2;\n"
322 " gl_FragColor = v;\n"
323 "}\n";
324 compile(shaderString);
325 ASSERT_TRUE(
326 foundInESSLCode("highp vec4 angle_compound_sub_frm(inout highp vec4 x, in highp vec4 y) {\n"
327 " x = angle_frm(angle_frm(x) - y);"));
328 ASSERT_TRUE(
329 foundInGLSLCode("vec4 angle_compound_sub_frm(inout vec4 x, in vec4 y) {\n"
330 " x = angle_frm(angle_frm(x) - y);"));
331 ASSERT_TRUE(
332 foundInHLSLCode("float4 angle_compound_sub_frm(inout float4 x, in float4 y) {\n"
333 " x = angle_frm(angle_frm(x) - y);"));
334 ASSERT_TRUE(foundInAllGLSLCode("angle_compound_sub_frm(_uv, angle_frm(_uu2));"));
335 ASSERT_TRUE(foundInHLSLCodeRegex("angle_compound_sub_frm\\(_v(\\d)*, angle_frm\\(_u2\\)\\);"));
336 ASSERT_TRUE(notFoundInCode("-="));
337 }
338
TEST_F(DebugShaderPrecisionTest,CompoundDivFunction)339 TEST_F(DebugShaderPrecisionTest, CompoundDivFunction)
340 {
341 const std::string &shaderString =
342 "precision mediump float;\n"
343 "uniform vec4 u;\n"
344 "uniform vec4 u2;\n"
345 "void main() {\n"
346 " vec4 v = u;\n"
347 " v /= u2;\n"
348 " gl_FragColor = v;\n"
349 "}\n";
350 compile(shaderString);
351 ASSERT_TRUE(
352 foundInESSLCode("highp vec4 angle_compound_div_frm(inout highp vec4 x, in highp vec4 y) {\n"
353 " x = angle_frm(angle_frm(x) / y);"));
354 ASSERT_TRUE(
355 foundInGLSLCode("vec4 angle_compound_div_frm(inout vec4 x, in vec4 y) {\n"
356 " x = angle_frm(angle_frm(x) / y);"));
357 ASSERT_TRUE(
358 foundInHLSLCode("float4 angle_compound_div_frm(inout float4 x, in float4 y) {\n"
359 " x = angle_frm(angle_frm(x) / y);"));
360 ASSERT_TRUE(foundInAllGLSLCode("angle_compound_div_frm(_uv, angle_frm(_uu2));"));
361 ASSERT_TRUE(foundInHLSLCodeRegex("angle_compound_div_frm\\(_v(\\d)*, angle_frm\\(_u2\\)\\);"));
362 ASSERT_TRUE(notFoundInCode("/="));
363 }
364
TEST_F(DebugShaderPrecisionTest,CompoundMulFunction)365 TEST_F(DebugShaderPrecisionTest, CompoundMulFunction)
366 {
367 const std::string &shaderString =
368 "precision mediump float;\n"
369 "uniform vec4 u;\n"
370 "uniform vec4 u2;\n"
371 "void main() {\n"
372 " vec4 v = u;\n"
373 " v *= u2;\n"
374 " gl_FragColor = v;\n"
375 "}\n";
376 compile(shaderString);
377 ASSERT_TRUE(
378 foundInESSLCode("highp vec4 angle_compound_mul_frm(inout highp vec4 x, in highp vec4 y) {\n"
379 " x = angle_frm(angle_frm(x) * y);"));
380 ASSERT_TRUE(
381 foundInGLSLCode("vec4 angle_compound_mul_frm(inout vec4 x, in vec4 y) {\n"
382 " x = angle_frm(angle_frm(x) * y);"));
383 ASSERT_TRUE(
384 foundInHLSLCode("float4 angle_compound_mul_frm(inout float4 x, in float4 y) {\n"
385 " x = angle_frm(angle_frm(x) * y);"));
386 ASSERT_TRUE(foundInAllGLSLCode("angle_compound_mul_frm(_uv, angle_frm(_uu2));"));
387 ASSERT_TRUE(foundInHLSLCodeRegex("angle_compound_mul_frm\\(_v(\\d)*, angle_frm\\(_u2\\)\\);"));
388 ASSERT_TRUE(notFoundInCode("*="));
389 }
390
TEST_F(DebugShaderPrecisionTest,CompoundAddVectorPlusScalarFunction)391 TEST_F(DebugShaderPrecisionTest, CompoundAddVectorPlusScalarFunction)
392 {
393 const std::string &shaderString =
394 "precision mediump float;\n"
395 "uniform vec4 u;\n"
396 "uniform float u2;\n"
397 "void main() {\n"
398 " vec4 v = u;\n"
399 " v += u2;\n"
400 " gl_FragColor = v;\n"
401 "}\n";
402 compile(shaderString);
403 ASSERT_TRUE(foundInESSLCode(
404 "highp vec4 angle_compound_add_frm(inout highp vec4 x, in highp float y) {\n"
405 " x = angle_frm(angle_frm(x) + y);"));
406 ASSERT_TRUE(
407 foundInGLSLCode("vec4 angle_compound_add_frm(inout vec4 x, in float y) {\n"
408 " x = angle_frm(angle_frm(x) + y);"));
409 ASSERT_TRUE(
410 foundInHLSLCode("float4 angle_compound_add_frm(inout float4 x, in float y) {\n"
411 " x = angle_frm(angle_frm(x) + y);"));
412 ASSERT_TRUE(foundInAllGLSLCode("angle_compound_add_frm(_uv, angle_frm(_uu2));"));
413 ASSERT_TRUE(foundInHLSLCodeRegex("angle_compound_add_frm\\(_v(\\d)*, angle_frm\\(_u2\\)\\);"));
414 ASSERT_TRUE(notFoundInCode("+="));
415 }
416
TEST_F(DebugShaderPrecisionTest,CompoundMatrixTimesMatrixFunction)417 TEST_F(DebugShaderPrecisionTest, CompoundMatrixTimesMatrixFunction)
418 {
419 const std::string &shaderString =
420 "precision mediump float;\n"
421 "uniform mat4 u;\n"
422 "uniform mat4 u2;\n"
423 "void main() {\n"
424 " mat4 m = u;\n"
425 " m *= u2;\n"
426 " gl_FragColor = m[0];\n"
427 "}\n";
428 compile(shaderString);
429 ASSERT_TRUE(
430 foundInESSLCode("highp mat4 angle_compound_mul_frm(inout highp mat4 x, in highp mat4 y) {\n"
431 " x = angle_frm(angle_frm(x) * y);"));
432 ASSERT_TRUE(
433 foundInGLSLCode("mat4 angle_compound_mul_frm(inout mat4 x, in mat4 y) {\n"
434 " x = angle_frm(angle_frm(x) * y);"));
435 ASSERT_TRUE(
436 foundInHLSLCode("float4x4 angle_compound_mul_frm(inout float4x4 x, in float4x4 y) {\n"
437 " x = angle_frm(angle_frm(x) * y);"));
438 ASSERT_TRUE(foundInAllGLSLCode("angle_compound_mul_frm(_um, angle_frm(_uu2));"));
439 ASSERT_TRUE(foundInHLSLCodeRegex("angle_compound_mul_frm\\(_m(\\d)*, angle_frm\\(_u2\\)\\);"));
440 ASSERT_TRUE(notFoundInCode("*="));
441 }
442
443 // Test that compound multiplying a non-square matrix with another matrix gets translated into an
444 // angle_compound_mul function call.
TEST_F(DebugShaderPrecisionTest,CompoundNonSquareMatrixTimesMatrixFunction)445 TEST_F(DebugShaderPrecisionTest, CompoundNonSquareMatrixTimesMatrixFunction)
446 {
447 const std::string &shaderString =
448 "#version 300 es\n"
449 "precision mediump float;\n"
450 "uniform mat2x4 u;\n"
451 "uniform mat2 u2;\n"
452 "out vec4 my_FragColor;\n"
453 "void main() {\n"
454 " mat2x4 m = u;\n"
455 " m *= u2;\n"
456 " my_FragColor = m[0];\n"
457 "}\n";
458 compile(shaderString);
459 ASSERT_TRUE(foundInESSLCode(
460 "highp mat2x4 angle_compound_mul_frm(inout highp mat2x4 x, in highp mat2 y) {\n"
461 " x = angle_frm(angle_frm(x) * y);"));
462 ASSERT_TRUE(
463 foundInGLSLCode("mat2x4 angle_compound_mul_frm(inout mat2x4 x, in mat2 y) {\n"
464 " x = angle_frm(angle_frm(x) * y);"));
465 ASSERT_TRUE(
466 foundInHLSLCode("float2x4 angle_compound_mul_frm(inout float2x4 x, in float2x2 y) {\n"
467 " x = angle_frm(angle_frm(x) * y);"));
468 ASSERT_TRUE(foundInAllGLSLCode("angle_compound_mul_frm(_um, angle_frm(_uu2));"));
469 ASSERT_TRUE(foundInHLSLCodeRegex("angle_compound_mul_frm\\(_m(\\d)*, angle_frm\\(_u2\\)\\);"));
470 ASSERT_TRUE(notFoundInCode("*="));
471 }
472
TEST_F(DebugShaderPrecisionTest,CompoundMatrixTimesScalarFunction)473 TEST_F(DebugShaderPrecisionTest, CompoundMatrixTimesScalarFunction)
474 {
475 const std::string &shaderString =
476 "precision mediump float;\n"
477 "uniform mat4 u;\n"
478 "uniform float u2;\n"
479 "void main() {\n"
480 " mat4 m = u;\n"
481 " m *= u2;\n"
482 " gl_FragColor = m[0];\n"
483 "}\n";
484 compile(shaderString);
485 ASSERT_TRUE(foundInESSLCode(
486 "highp mat4 angle_compound_mul_frm(inout highp mat4 x, in highp float y) {\n"
487 " x = angle_frm(angle_frm(x) * y);"));
488 ASSERT_TRUE(
489 foundInGLSLCode("mat4 angle_compound_mul_frm(inout mat4 x, in float y) {\n"
490 " x = angle_frm(angle_frm(x) * y);"));
491 ASSERT_TRUE(
492 foundInHLSLCode("float4x4 angle_compound_mul_frm(inout float4x4 x, in float y) {\n"
493 " x = angle_frm(angle_frm(x) * y);"));
494 ASSERT_TRUE(foundInAllGLSLCode("angle_compound_mul_frm(_um, angle_frm(_uu2));"));
495 ASSERT_TRUE(foundInHLSLCodeRegex("angle_compound_mul_frm\\(_m(\\d)*, angle_frm\\(_u2\\)\\);"));
496 ASSERT_TRUE(notFoundInCode("*="));
497 }
498
TEST_F(DebugShaderPrecisionTest,CompoundVectorTimesMatrixFunction)499 TEST_F(DebugShaderPrecisionTest, CompoundVectorTimesMatrixFunction)
500 {
501 const std::string &shaderString =
502 "precision mediump float;\n"
503 "uniform vec4 u;\n"
504 "uniform mat4 u2;\n"
505 "void main() {\n"
506 " vec4 v = u;\n"
507 " v *= u2;\n"
508 " gl_FragColor = v;\n"
509 "}\n";
510 compile(shaderString);
511 ASSERT_TRUE(
512 foundInESSLCode("highp vec4 angle_compound_mul_frm(inout highp vec4 x, in highp mat4 y) {\n"
513 " x = angle_frm(angle_frm(x) * y);"));
514 ASSERT_TRUE(
515 foundInGLSLCode("vec4 angle_compound_mul_frm(inout vec4 x, in mat4 y) {\n"
516 " x = angle_frm(angle_frm(x) * y);"));
517 ASSERT_TRUE(
518 foundInHLSLCode("float4 angle_compound_mul_frm(inout float4 x, in float4x4 y) {\n"
519 " x = angle_frm(angle_frm(x) * y);"));
520 ASSERT_TRUE(foundInAllGLSLCode("angle_compound_mul_frm(_uv, angle_frm(_uu2));"));
521 ASSERT_TRUE(foundInHLSLCodeRegex("angle_compound_mul_frm\\(_v(\\d)*, angle_frm\\(_u2\\)\\);"));
522 ASSERT_TRUE(notFoundInCode("*="));
523 }
524
TEST_F(DebugShaderPrecisionTest,CompoundVectorTimesScalarFunction)525 TEST_F(DebugShaderPrecisionTest, CompoundVectorTimesScalarFunction)
526 {
527 const std::string &shaderString =
528 "precision mediump float;\n"
529 "uniform vec4 u;\n"
530 "uniform float u2;\n"
531 "void main() {\n"
532 " vec4 v = u;\n"
533 " v *= u2;\n"
534 " gl_FragColor = v;\n"
535 "}\n";
536 compile(shaderString);
537 ASSERT_TRUE(foundInESSLCode(
538 "highp vec4 angle_compound_mul_frm(inout highp vec4 x, in highp float y) {\n"
539 " x = angle_frm(angle_frm(x) * y);"));
540 ASSERT_TRUE(
541 foundInGLSLCode("vec4 angle_compound_mul_frm(inout vec4 x, in float y) {\n"
542 " x = angle_frm(angle_frm(x) * y);"));
543 ASSERT_TRUE(
544 foundInHLSLCode("float4 angle_compound_mul_frm(inout float4 x, in float y) {\n"
545 " x = angle_frm(angle_frm(x) * y);"));
546 ASSERT_TRUE(foundInAllGLSLCode("angle_compound_mul_frm(_uv, angle_frm(_uu2));"));
547 ASSERT_TRUE(foundInHLSLCodeRegex("angle_compound_mul_frm\\(_v(\\d)*, angle_frm\\(_u2\\)\\);"));
548 ASSERT_TRUE(notFoundInCode("*="));
549 }
550
TEST_F(DebugShaderPrecisionTest,BinaryMathRounding)551 TEST_F(DebugShaderPrecisionTest, BinaryMathRounding)
552 {
553 const std::string &shaderString =
554 "precision mediump float;\n"
555 "uniform vec4 u1;\n"
556 "uniform vec4 u2;\n"
557 "uniform vec4 u3;\n"
558 "uniform vec4 u4;\n"
559 "uniform vec4 u5;\n"
560 "void main() {\n"
561 " vec4 v1 = u1 + u2;\n"
562 " vec4 v2 = u2 - u3;\n"
563 " vec4 v3 = u3 * u4;\n"
564 " vec4 v4 = u4 / u5;\n"
565 " vec4 v5;\n"
566 " vec4 v6 = (v5 = u5);\n"
567 " gl_FragColor = v1 + v2 + v3 + v4;\n"
568 "}\n";
569 compile(shaderString);
570 ASSERT_TRUE(foundInAllGLSLCode("v1 = angle_frm((angle_frm(_uu1) + angle_frm(_uu2)))"));
571 ASSERT_TRUE(foundInAllGLSLCode("v2 = angle_frm((angle_frm(_uu2) - angle_frm(_uu3)))"));
572 ASSERT_TRUE(foundInAllGLSLCode("v3 = angle_frm((angle_frm(_uu3) * angle_frm(_uu4)))"));
573 ASSERT_TRUE(foundInAllGLSLCode("v4 = angle_frm((angle_frm(_uu4) / angle_frm(_uu5)))"));
574 ASSERT_TRUE(foundInAllGLSLCode("v6 = angle_frm((_uv5 = angle_frm(_uu5)))"));
575
576 ASSERT_TRUE(foundInHLSLCodeRegex(
577 "v1(\\d)* = angle_frm\\(\\(angle_frm\\(_u1\\) \\+ angle_frm\\(_u2\\)\\)\\)"));
578 ASSERT_TRUE(foundInHLSLCodeRegex(
579 "v2(\\d)* = angle_frm\\(\\(angle_frm\\(_u2\\) - angle_frm\\(_u3\\)\\)\\)"));
580 ASSERT_TRUE(foundInHLSLCodeRegex(
581 "v3(\\d)* = angle_frm\\(\\(angle_frm\\(_u3\\) \\* angle_frm\\(_u4\\)\\)\\)"));
582 ASSERT_TRUE(foundInHLSLCodeRegex(
583 "v4(\\d)* = angle_frm\\(\\(angle_frm\\(_u4\\) / angle_frm\\(_u5\\)\\)\\)"));
584 ASSERT_TRUE(
585 foundInHLSLCodeRegex("v6(\\d)* = angle_frm\\(\\(_v5(\\d)* = angle_frm\\(_u5\\)\\)\\)"));
586 }
587
TEST_F(DebugShaderPrecisionTest,BuiltInMathFunctionRounding)588 TEST_F(DebugShaderPrecisionTest, BuiltInMathFunctionRounding)
589 {
590 const std::string &shaderString =
591 "precision mediump float;\n"
592 "uniform vec4 u1;\n"
593 "uniform vec4 u2;\n"
594 "uniform vec4 u3;\n"
595 "uniform float uf;\n"
596 "uniform float uf2;\n"
597 "uniform vec3 uf31;\n"
598 "uniform vec3 uf32;\n"
599 "uniform mat4 um1;\n"
600 "uniform mat4 um2;\n"
601 "void main() {\n"
602 " vec4 v1 = radians(u1);\n"
603 " vec4 v2 = degrees(u1);\n"
604 " vec4 v3 = sin(u1);\n"
605 " vec4 v4 = cos(u1);\n"
606 " vec4 v5 = tan(u1);\n"
607 " vec4 v6 = asin(u1);\n"
608 " vec4 v7 = acos(u1);\n"
609 " vec4 v8 = atan(u1);\n"
610 " vec4 v9 = atan(u1, u2);\n"
611 " vec4 v10 = pow(u1, u2);\n"
612 " vec4 v11 = exp(u1);\n"
613 " vec4 v12 = log(u1);\n"
614 " vec4 v13 = exp2(u1);\n"
615 " vec4 v14 = log2(u1);\n"
616 " vec4 v15 = sqrt(u1);\n"
617 " vec4 v16 = inversesqrt(u1);\n"
618 " vec4 v17 = abs(u1);\n"
619 " vec4 v18 = sign(u1);\n"
620 " vec4 v19 = floor(u1);\n"
621 " vec4 v20 = ceil(u1);\n"
622 " vec4 v21 = fract(u1);\n"
623 " vec4 v22 = mod(u1, uf);\n"
624 " vec4 v23 = mod(u1, u2);\n"
625 " vec4 v24 = min(u1, uf);\n"
626 " vec4 v25 = min(u1, u2);\n"
627 " vec4 v26 = max(u1, uf);\n"
628 " vec4 v27 = max(u1, u2);\n"
629 " vec4 v28 = clamp(u1, u2, u3);\n"
630 " vec4 v29 = clamp(u1, uf, uf2);\n"
631 " vec4 v30 = mix(u1, u2, u3);\n"
632 " vec4 v31 = mix(u1, u2, uf);\n"
633 " vec4 v32 = step(u1, u2);\n"
634 " vec4 v33 = step(uf, u1);\n"
635 " vec4 v34 = smoothstep(u1, u2, u3);\n"
636 " vec4 v35 = smoothstep(uf, uf2, u1);\n"
637 " vec4 v36 = normalize(u1);\n"
638 " vec4 v37 = faceforward(u1, u2, u3);\n"
639 " vec4 v38 = reflect(u1, u2);\n"
640 " vec4 v39 = refract(u1, u2, uf);\n"
641
642 " float f1 = length(u1);\n"
643 " float f2 = distance(u1, u2);\n"
644 " float f3 = dot(u1, u2);\n"
645 " vec3 vf31 = cross(uf31, uf32);\n"
646 " mat4 m1 = matrixCompMult(um1, um2);\n"
647
648 " gl_FragColor = v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8 + v9 + v10 +"
649 "v11 + v12 + v13 + v14 + v15 + v16 + v17 + v18 + v19 + v20 +"
650 "v21 + v22 + v23 + v24 + v25 + v26 + v27 + v28 + v29 + v30 +"
651 "v31 + v32 + v33 + v34 + v35 + v36 + v37 + v38 + v39 +"
652 "vec4(f1, f2, f3, 0.0) + vec4(vf31, 0.0) + m1[0];\n"
653 "}\n";
654 compile(shaderString);
655 ASSERT_TRUE(foundInAllGLSLCode("v1 = angle_frm(radians(angle_frm(_uu1)))"));
656 ASSERT_TRUE(foundInAllGLSLCode("v2 = angle_frm(degrees(angle_frm(_uu1)))"));
657 ASSERT_TRUE(foundInAllGLSLCode("v3 = angle_frm(sin(angle_frm(_uu1)))"));
658 ASSERT_TRUE(foundInAllGLSLCode("v4 = angle_frm(cos(angle_frm(_uu1)))"));
659 ASSERT_TRUE(foundInAllGLSLCode("v5 = angle_frm(tan(angle_frm(_uu1)))"));
660 ASSERT_TRUE(foundInAllGLSLCode("v6 = angle_frm(asin(angle_frm(_uu1)))"));
661 ASSERT_TRUE(foundInAllGLSLCode("v7 = angle_frm(acos(angle_frm(_uu1)))"));
662 ASSERT_TRUE(foundInAllGLSLCode("v8 = angle_frm(atan(angle_frm(_uu1)))"));
663 ASSERT_TRUE(foundInAllGLSLCode("v9 = angle_frm(atan(angle_frm(_uu1), angle_frm(_uu2)))"));
664 ASSERT_TRUE(foundInAllGLSLCode("v10 = angle_frm(pow(angle_frm(_uu1), angle_frm(_uu2)))"));
665 ASSERT_TRUE(foundInAllGLSLCode("v11 = angle_frm(exp(angle_frm(_uu1)))"));
666 ASSERT_TRUE(foundInAllGLSLCode("v12 = angle_frm(log(angle_frm(_uu1)))"));
667 ASSERT_TRUE(foundInAllGLSLCode("v13 = angle_frm(exp2(angle_frm(_uu1)))"));
668 ASSERT_TRUE(foundInAllGLSLCode("v14 = angle_frm(log2(angle_frm(_uu1)))"));
669 ASSERT_TRUE(foundInAllGLSLCode("v15 = angle_frm(sqrt(angle_frm(_uu1)))"));
670 ASSERT_TRUE(foundInAllGLSLCode("v16 = angle_frm(inversesqrt(angle_frm(_uu1)))"));
671 ASSERT_TRUE(foundInAllGLSLCode("v17 = angle_frm(abs(angle_frm(_uu1)))"));
672 ASSERT_TRUE(foundInAllGLSLCode("v18 = angle_frm(sign(angle_frm(_uu1)))"));
673 ASSERT_TRUE(foundInAllGLSLCode("v19 = angle_frm(floor(angle_frm(_uu1)))"));
674 ASSERT_TRUE(foundInAllGLSLCode("v20 = angle_frm(ceil(angle_frm(_uu1)))"));
675 ASSERT_TRUE(foundInAllGLSLCode("v21 = angle_frm(fract(angle_frm(_uu1)))"));
676 ASSERT_TRUE(foundInAllGLSLCode("v22 = angle_frm(mod(angle_frm(_uu1), angle_frm(_uuf)))"));
677 ASSERT_TRUE(foundInAllGLSLCode("v23 = angle_frm(mod(angle_frm(_uu1), angle_frm(_uu2)))"));
678 ASSERT_TRUE(foundInAllGLSLCode("v24 = angle_frm(min(angle_frm(_uu1), angle_frm(_uuf)))"));
679 ASSERT_TRUE(foundInAllGLSLCode("v25 = angle_frm(min(angle_frm(_uu1), angle_frm(_uu2)))"));
680 ASSERT_TRUE(foundInAllGLSLCode("v26 = angle_frm(max(angle_frm(_uu1), angle_frm(_uuf)))"));
681 ASSERT_TRUE(foundInAllGLSLCode("v27 = angle_frm(max(angle_frm(_uu1), angle_frm(_uu2)))"));
682 ASSERT_TRUE(foundInAllGLSLCode(
683 "v28 = angle_frm(clamp(angle_frm(_uu1), angle_frm(_uu2), angle_frm(_uu3)))"));
684 ASSERT_TRUE(foundInAllGLSLCode(
685 "v29 = angle_frm(clamp(angle_frm(_uu1), angle_frm(_uuf), angle_frm(_uuf2)))"));
686 ASSERT_TRUE(foundInAllGLSLCode(
687 "v30 = angle_frm(mix(angle_frm(_uu1), angle_frm(_uu2), angle_frm(_uu3)))"));
688 ASSERT_TRUE(foundInAllGLSLCode(
689 "v31 = angle_frm(mix(angle_frm(_uu1), angle_frm(_uu2), angle_frm(_uuf)))"));
690 ASSERT_TRUE(foundInAllGLSLCode("v32 = angle_frm(step(angle_frm(_uu1), angle_frm(_uu2)))"));
691 ASSERT_TRUE(foundInAllGLSLCode("v33 = angle_frm(step(angle_frm(_uuf), angle_frm(_uu1)))"));
692 ASSERT_TRUE(foundInAllGLSLCode(
693 "v34 = angle_frm(smoothstep(angle_frm(_uu1), angle_frm(_uu2), angle_frm(_uu3)))"));
694 ASSERT_TRUE(foundInAllGLSLCode(
695 "v35 = angle_frm(smoothstep(angle_frm(_uuf), angle_frm(_uuf2), angle_frm(_uu1)))"));
696 ASSERT_TRUE(foundInAllGLSLCode("v36 = angle_frm(normalize(angle_frm(_uu1)))"));
697 ASSERT_TRUE(foundInAllGLSLCode(
698 "v37 = angle_frm(faceforward(angle_frm(_uu1), angle_frm(_uu2), angle_frm(_uu3)))"));
699 ASSERT_TRUE(foundInAllGLSLCode("v38 = angle_frm(reflect(angle_frm(_uu1), angle_frm(_uu2)))"));
700 ASSERT_TRUE(foundInAllGLSLCode(
701 "v39 = angle_frm(refract(angle_frm(_uu1), angle_frm(_uu2), angle_frm(_uuf)))"));
702
703 ASSERT_TRUE(foundInAllGLSLCode("f1 = angle_frm(length(angle_frm(_uu1)))"));
704 ASSERT_TRUE(foundInAllGLSLCode("f2 = angle_frm(distance(angle_frm(_uu1), angle_frm(_uu2)))"));
705 ASSERT_TRUE(foundInAllGLSLCode("f3 = angle_frm(dot(angle_frm(_uu1), angle_frm(_uu2)))"));
706 ASSERT_TRUE(
707 foundInAllGLSLCode("vf31 = angle_frm(cross(angle_frm(_uuf31), angle_frm(_uuf32)))"));
708 ASSERT_TRUE(
709 foundInAllGLSLCode("m1 = angle_frm(matrixCompMult(angle_frm(_uum1), angle_frm(_uum2)))"));
710
711 ASSERT_TRUE(foundInHLSLCodeRegex("v1(\\d)* = angle_frm\\(radians\\(angle_frm\\(_u1\\)\\)\\)"));
712 ASSERT_TRUE(foundInHLSLCodeRegex("v2(\\d)* = angle_frm\\(degrees\\(angle_frm\\(_u1\\)\\)\\)"));
713 ASSERT_TRUE(foundInHLSLCodeRegex("v3(\\d)* = angle_frm\\(sin\\(angle_frm\\(_u1\\)\\)\\)"));
714 ASSERT_TRUE(foundInHLSLCodeRegex("v4(\\d)* = angle_frm\\(cos\\(angle_frm\\(_u1\\)\\)\\)"));
715 ASSERT_TRUE(foundInHLSLCodeRegex("v5(\\d)* = angle_frm\\(tan\\(angle_frm\\(_u1\\)\\)\\)"));
716 ASSERT_TRUE(foundInHLSLCodeRegex("v6(\\d)* = angle_frm\\(asin\\(angle_frm\\(_u1\\)\\)\\)"));
717 ASSERT_TRUE(foundInHLSLCodeRegex("v7(\\d)* = angle_frm\\(acos\\(angle_frm\\(_u1\\)\\)\\)"));
718 ASSERT_TRUE(foundInHLSLCodeRegex("v8(\\d)* = angle_frm\\(atan\\(angle_frm\\(_u1\\)\\)\\)"));
719 ASSERT_TRUE(foundInHLSLCodeRegex(
720 "v9(\\d)* = angle_frm\\(atan_emu\\(angle_frm\\(_u1\\), angle_frm\\(_u2\\)\\)\\)"));
721 ASSERT_TRUE(foundInHLSLCodeRegex(
722 "v10(\\d)* = angle_frm\\(pow\\(angle_frm\\(_u1\\), angle_frm\\(_u2\\)\\)\\)"));
723 ASSERT_TRUE(foundInHLSLCodeRegex("v11(\\d)* = angle_frm\\(exp\\(angle_frm\\(_u1\\)\\)\\)"));
724 ASSERT_TRUE(foundInHLSLCodeRegex("v12(\\d)* = angle_frm\\(log\\(angle_frm\\(_u1\\)\\)\\)"));
725 ASSERT_TRUE(foundInHLSLCodeRegex("v13(\\d)* = angle_frm\\(exp2\\(angle_frm\\(_u1\\)\\)\\)"));
726 ASSERT_TRUE(foundInHLSLCodeRegex("v14(\\d)* = angle_frm\\(log2\\(angle_frm\\(_u1\\)\\)\\)"));
727 ASSERT_TRUE(foundInHLSLCodeRegex("v15(\\d)* = angle_frm\\(sqrt\\(angle_frm\\(_u1\\)\\)\\)"));
728 ASSERT_TRUE(foundInHLSLCodeRegex("v16(\\d)* = angle_frm\\(rsqrt\\(angle_frm\\(_u1\\)\\)\\)"));
729 ASSERT_TRUE(foundInHLSLCodeRegex("v17(\\d)* = angle_frm\\(abs\\(angle_frm\\(_u1\\)\\)\\)"));
730 ASSERT_TRUE(foundInHLSLCodeRegex("v18(\\d)* = angle_frm\\(sign\\(angle_frm\\(_u1\\)\\)\\)"));
731 ASSERT_TRUE(foundInHLSLCodeRegex("v19(\\d)* = angle_frm\\(floor\\(angle_frm\\(_u1\\)\\)\\)"));
732 ASSERT_TRUE(foundInHLSLCodeRegex("v20(\\d)* = angle_frm\\(ceil\\(angle_frm\\(_u1\\)\\)\\)"));
733 ASSERT_TRUE(foundInHLSLCodeRegex("v21(\\d)* = angle_frm\\(frac\\(angle_frm\\(_u1\\)\\)\\)"));
734 ASSERT_TRUE(foundInHLSLCodeRegex(
735 "v22(\\d)* = angle_frm\\(mod_emu\\(angle_frm\\(_u1\\), angle_frm\\(_uf\\)\\)\\)"));
736 ASSERT_TRUE(foundInHLSLCodeRegex(
737 "v23(\\d)* = angle_frm\\(mod_emu\\(angle_frm\\(_u1\\), angle_frm\\(_u2\\)\\)\\)"));
738 ASSERT_TRUE(foundInHLSLCodeRegex(
739 "v24(\\d)* = angle_frm\\(min\\(angle_frm\\(_u1\\), angle_frm\\(_uf\\)\\)\\)"));
740 ASSERT_TRUE(foundInHLSLCodeRegex(
741 "v25(\\d)* = angle_frm\\(min\\(angle_frm\\(_u1\\), angle_frm\\(_u2\\)\\)\\)"));
742 ASSERT_TRUE(foundInHLSLCodeRegex(
743 "v26(\\d)* = angle_frm\\(max\\(angle_frm\\(_u1\\), angle_frm\\(_uf\\)\\)\\)"));
744 ASSERT_TRUE(foundInHLSLCodeRegex(
745 "v27(\\d)* = angle_frm\\(max\\(angle_frm\\(_u1\\), angle_frm\\(_u2\\)\\)\\)"));
746 ASSERT_TRUE(foundInHLSLCodeRegex(
747 "v28(\\d)* = angle_frm\\(clamp\\(angle_frm\\(_u1\\), angle_frm\\(_u2\\), "
748 "angle_frm\\(_u3\\)\\)\\)"));
749 ASSERT_TRUE(foundInHLSLCodeRegex(
750 "v29(\\d)* = angle_frm\\(clamp\\(angle_frm\\(_u1\\), angle_frm\\(_uf\\), "
751 "angle_frm\\(_uf2\\)\\)\\)"));
752 ASSERT_TRUE(foundInHLSLCodeRegex(
753 "v30(\\d)* = angle_frm\\(lerp\\(angle_frm\\(_u1\\), angle_frm\\(_u2\\), "
754 "angle_frm\\(_u3\\)\\)\\)"));
755 ASSERT_TRUE(foundInHLSLCodeRegex(
756 "v31(\\d)* = angle_frm\\(lerp\\(angle_frm\\(_u1\\), angle_frm\\(_u2\\), "
757 "angle_frm\\(_uf\\)\\)\\)"));
758 ASSERT_TRUE(foundInHLSLCodeRegex(
759 "v32(\\d)* = angle_frm\\(step\\(angle_frm\\(_u1\\), angle_frm\\(_u2\\)\\)\\)"));
760 ASSERT_TRUE(foundInHLSLCodeRegex(
761 "v33(\\d)* = angle_frm\\(step\\(angle_frm\\(_uf\\), angle_frm\\(_u1\\)\\)\\)"));
762 ASSERT_TRUE(
763 foundInHLSLCodeRegex("v34(\\d)* = angle_frm\\(smoothstep\\(angle_frm\\(_u1\\), "
764 "angle_frm\\(_u2\\), angle_frm\\(_u3\\)\\)\\)"));
765 ASSERT_TRUE(
766 foundInHLSLCodeRegex("v35(\\d)* = angle_frm\\(smoothstep\\(angle_frm\\(_uf\\), "
767 "angle_frm\\(_uf2\\), angle_frm\\(_u1\\)\\)\\)"));
768 ASSERT_TRUE(
769 foundInHLSLCodeRegex("v36(\\d)* = angle_frm\\(normalize\\(angle_frm\\(_u1\\)\\)\\)"));
770 ASSERT_TRUE(
771 foundInHLSLCodeRegex("v37(\\d)* = angle_frm\\(faceforward_emu\\(angle_frm\\(_u1\\), "
772 "angle_frm\\(_u2\\), angle_frm\\(_u3\\)\\)\\)"));
773 ASSERT_TRUE(foundInHLSLCodeRegex(
774 "v38(\\d)* = angle_frm\\(reflect\\(angle_frm\\(_u1\\), angle_frm\\(_u2\\)\\)\\)"));
775 ASSERT_TRUE(
776 foundInHLSLCodeRegex("v39(\\d)* = angle_frm\\(refract\\(angle_frm\\(_u1\\), "
777 "angle_frm\\(_u2\\), angle_frm\\(_uf\\)\\)\\)"));
778
779 ASSERT_TRUE(foundInHLSLCodeRegex("f1(\\d)* = angle_frm\\(length\\(angle_frm\\(_u1\\)\\)\\)"));
780 ASSERT_TRUE(foundInHLSLCodeRegex(
781 "f2(\\d)* = angle_frm\\(distance\\(angle_frm\\(_u1\\), angle_frm\\(_u2\\)\\)\\)"));
782 ASSERT_TRUE(foundInHLSLCodeRegex(
783 "f3(\\d)* = angle_frm\\(dot\\(angle_frm\\(_u1\\), angle_frm\\(_u2\\)\\)\\)"));
784 ASSERT_TRUE(foundInHLSLCodeRegex(
785 "vf31(\\d)* = angle_frm\\(cross\\(angle_frm\\(_uf31\\), angle_frm\\(_uf32\\)\\)\\)"));
786 ASSERT_TRUE(foundInHLSLCodeRegex(
787 "m1(\\d)* = angle_frm\\(\\(angle_frm\\(_um1\\) \\* angle_frm\\(_um2\\)\\)\\)"));
788 }
789
TEST_F(DebugShaderPrecisionTest,BuiltInRelationalFunctionRounding)790 TEST_F(DebugShaderPrecisionTest, BuiltInRelationalFunctionRounding)
791 {
792 const std::string &shaderString =
793 "precision mediump float;\n"
794 "uniform vec4 u1;\n"
795 "uniform vec4 u2;\n"
796 "void main() {\n"
797 " bvec4 bv1 = lessThan(u1, u2);\n"
798 " bvec4 bv2 = lessThanEqual(u1, u2);\n"
799 " bvec4 bv3 = greaterThan(u1, u2);\n"
800 " bvec4 bv4 = greaterThanEqual(u1, u2);\n"
801 " bvec4 bv5 = equal(u1, u2);\n"
802 " bvec4 bv6 = notEqual(u1, u2);\n"
803 " gl_FragColor = vec4(bv1) + vec4(bv2) + vec4(bv3) + vec4(bv4) + vec4(bv5) + vec4(bv6);\n"
804 "}\n";
805 compile(shaderString);
806 ASSERT_TRUE(foundInAllGLSLCode("bv1 = lessThan(angle_frm(_uu1), angle_frm(_uu2))"));
807 ASSERT_TRUE(foundInAllGLSLCode("bv2 = lessThanEqual(angle_frm(_uu1), angle_frm(_uu2))"));
808 ASSERT_TRUE(foundInAllGLSLCode("bv3 = greaterThan(angle_frm(_uu1), angle_frm(_uu2))"));
809 ASSERT_TRUE(foundInAllGLSLCode("bv4 = greaterThanEqual(angle_frm(_uu1), angle_frm(_uu2))"));
810 ASSERT_TRUE(foundInAllGLSLCode("bv5 = equal(angle_frm(_uu1), angle_frm(_uu2))"));
811 ASSERT_TRUE(foundInAllGLSLCode("bv6 = notEqual(angle_frm(_uu1), angle_frm(_uu2))"));
812
813 ASSERT_TRUE(foundInHLSLCodeRegex("bv1(\\d)* = \\(angle_frm\\(_u1\\) < angle_frm\\(_u2\\)\\)"));
814 ASSERT_TRUE(foundInHLSLCodeRegex("bv2(\\d)* = \\(angle_frm\\(_u1\\) <= angle_frm\\(_u2\\)\\)"));
815 ASSERT_TRUE(foundInHLSLCodeRegex("bv3(\\d)* = \\(angle_frm\\(_u1\\) > angle_frm\\(_u2\\)\\)"));
816 ASSERT_TRUE(foundInHLSLCodeRegex("bv4(\\d)* = \\(angle_frm\\(_u1\\) >= angle_frm\\(_u2\\)\\)"));
817 ASSERT_TRUE(foundInHLSLCodeRegex("bv5(\\d)* = \\(angle_frm\\(_u1\\) == angle_frm\\(_u2\\)\\)"));
818 ASSERT_TRUE(foundInHLSLCodeRegex("bv6(\\d)* = \\(angle_frm\\(_u1\\) != angle_frm\\(_u2\\)\\)"));
819 }
820
TEST_F(DebugShaderPrecisionTest,ConstructorRounding)821 TEST_F(DebugShaderPrecisionTest, ConstructorRounding)
822 {
823 const std::string &shaderString =
824 "precision mediump float;\n"
825 "precision mediump int;\n"
826 "uniform float u1;\n"
827 "uniform float u2;\n"
828 "uniform lowp float u3;\n"
829 "uniform float u4;\n"
830 "uniform ivec4 uiv;\n"
831 "void main() {\n"
832 " vec4 v1 = vec4(u1, u2, u3, u4);\n"
833 " vec4 v2 = vec4(uiv);\n"
834 " gl_FragColor = v1 + v2;\n"
835 "}\n";
836 compile(shaderString);
837 ASSERT_TRUE(foundInAllGLSLCode("v1 = angle_frm(vec4(_uu1, _uu2, angle_frl(_uu3), _uu4))"));
838 ASSERT_TRUE(foundInAllGLSLCode("v2 = angle_frm(vec4(_uuiv))"));
839
840 ASSERT_TRUE(foundInHLSLCodeRegex(
841 "v1(\\d)* = angle_frm\\(vec4_ctor\\(_u1, _u2, angle_frl\\(_u3\\), _u4\\)\\)"));
842 ASSERT_TRUE(foundInHLSLCodeRegex("v2(\\d)* = angle_frm\\(vec4_ctor\\(_uiv\\)\\)"));
843 }
844
TEST_F(DebugShaderPrecisionTest,StructConstructorNoRounding)845 TEST_F(DebugShaderPrecisionTest, StructConstructorNoRounding)
846 {
847 const std::string &shaderString =
848 "precision mediump float;\n"
849 "struct S { mediump vec4 a; };\n"
850 "uniform vec4 u;\n"
851 "void main() {\n"
852 " S s = S(u);\n"
853 " gl_FragColor = s.a;\n"
854 "}\n";
855 compile(shaderString);
856 ASSERT_TRUE(foundInAllGLSLCode("s = _uS(angle_frm(_uu))"));
857 ASSERT_TRUE(foundInHLSLCodeRegex("s(\\d)* = _S_ctor\\(angle_frm\\(_u\\)\\)"));
858 ASSERT_TRUE(notFoundInCode("angle_frm(_uS")); // GLSL
859 ASSERT_TRUE(notFoundInCode("angle_frm(_S")); // HLSL
860 }
861
TEST_F(DebugShaderPrecisionTest,SwizzleRounding)862 TEST_F(DebugShaderPrecisionTest, SwizzleRounding)
863 {
864 const std::string &shaderString =
865 "precision mediump float;\n"
866 "uniform vec4 u;\n"
867 "void main() {\n"
868 " vec4 v = u.xyxy;"
869 " gl_FragColor = v;\n"
870 "}\n";
871 compile(shaderString);
872 ASSERT_TRUE(foundInAllGLSLCode("v = angle_frm(_uu).xyxy"));
873 ASSERT_TRUE(foundInHLSLCodeRegex("v(\\d)* = angle_frm\\(_u\\)\\.xyxy"));
874 }
875
TEST_F(DebugShaderPrecisionTest,BuiltInTexFunctionRounding)876 TEST_F(DebugShaderPrecisionTest, BuiltInTexFunctionRounding)
877 {
878 const std::string &shaderString =
879 "precision mediump float;\n"
880 "precision lowp sampler2D;\n"
881 "uniform vec2 u;\n"
882 "uniform sampler2D s;\n"
883 "void main() {\n"
884 " lowp vec4 v = texture2D(s, u);\n"
885 " gl_FragColor = v;\n"
886 "}\n";
887 compile(shaderString);
888 ASSERT_TRUE(foundInAllGLSLCode("v = angle_frl(texture2D(_us, angle_frm(_uu)))"));
889 ASSERT_TRUE(
890 foundInHLSLCodeRegex("v(\\d)* = angle_frl\\(gl_texture2D\\(_s, angle_frm\\(_u\\)\\)\\)"));
891 }
892
TEST_F(DebugShaderPrecisionTest,FunctionCallParameterQualifiersFromDefinition)893 TEST_F(DebugShaderPrecisionTest, FunctionCallParameterQualifiersFromDefinition)
894 {
895 const std::string &shaderString =
896 "precision mediump float;\n"
897 "uniform vec4 u1;\n"
898 "uniform vec4 u2;\n"
899 "uniform vec4 u3;\n"
900 "uniform vec4 u4;\n"
901 "uniform vec4 u5;\n"
902 "vec4 add(in vec4 x, in vec4 y) {\n"
903 " return x + y;\n"
904 "}\n"
905 "void compound_add(inout vec4 x, in vec4 y) {\n"
906 " x = x + y;\n"
907 "}\n"
908 "void add_to_last(in vec4 x, in vec4 y, out vec4 z) {\n"
909 " z = x + y;\n"
910 "}\n"
911 "void main() {\n"
912 " vec4 v = add(u1, u2);\n"
913 " compound_add(v, u3);\n"
914 " vec4 v2;\n"
915 " add_to_last(u4, u5, v2);\n"
916 " gl_FragColor = v + v2;\n"
917 "}\n";
918 compile(shaderString);
919 // Note that this is not optimal code, there are redundant frm calls.
920 // However, getting the implementation working when other operations
921 // are nested within function calls would be tricky if to get right
922 // otherwise.
923 // Test in parameters
924 ASSERT_TRUE(foundInAllGLSLCode("v = _uadd(angle_frm(_uu1), angle_frm(_uu2))"));
925 ASSERT_TRUE(foundInHLSLCodeRegex(
926 "v(\\d)* = f_add_float4_float4\\(angle_frm\\(_u1\\), angle_frm\\(_u2\\)\\)"));
927 // Test inout parameter
928 ASSERT_TRUE(foundInAllGLSLCode("_ucompound_add(_uv, angle_frm(_uu3))"));
929 ASSERT_TRUE(
930 foundInHLSLCodeRegex("compound_add_float4_float4\\(_v(\\d)*, angle_frm\\(_u3\\)\\)"));
931 // Test out parameter
932 ASSERT_TRUE(foundInAllGLSLCode("_uadd_to_last(angle_frm(_uu4), angle_frm(_uu5), _uv2)"));
933 ASSERT_TRUE(foundInHLSLCodeRegex(
934 "add_to_last_float4_float4_float4\\(angle_frm\\(_u4\\), angle_frm\\(_u5\\), _v2(\\d)*\\)"));
935 }
936
TEST_F(DebugShaderPrecisionTest,FunctionCallParameterQualifiersFromPrototype)937 TEST_F(DebugShaderPrecisionTest, FunctionCallParameterQualifiersFromPrototype)
938 {
939 const std::string &shaderString =
940 "precision mediump float;\n"
941 "uniform vec4 u1;\n"
942 "uniform vec4 u2;\n"
943 "uniform vec4 u3;\n"
944 "uniform vec4 u4;\n"
945 "uniform vec4 u5;\n"
946 "vec4 add(in vec4 x, in vec4 y);\n"
947 "void compound_add(inout vec4 x, in vec4 y);\n"
948 "void add_to_last(in vec4 x, in vec4 y, out vec4 z);\n"
949 "void main() {\n"
950 " vec4 v = add(u1, u2);\n"
951 " compound_add(v, u3);\n"
952 " vec4 v2;\n"
953 " add_to_last(u4, u5, v2);\n"
954 " gl_FragColor = v + v2;\n"
955 "}\n"
956 "vec4 add(in vec4 x, in vec4 y) {\n"
957 " return x + y;\n"
958 "}\n"
959 "void compound_add(inout vec4 x, in vec4 y) {\n"
960 " x = x + y;\n"
961 "}\n"
962 "void add_to_last(in vec4 x, in vec4 y, out vec4 z) {\n"
963 " z = x + y;\n"
964 "}\n";
965 compile(shaderString);
966 // Test in parameters
967 ASSERT_TRUE(foundInAllGLSLCode("v = _uadd(angle_frm(_uu1), angle_frm(_uu2))"));
968 ASSERT_TRUE(foundInHLSLCodeRegex(
969 "v(\\d)* = f_add_float4_float4\\(angle_frm\\(_u1\\), angle_frm\\(_u2\\)\\)"));
970 // Test inout parameter
971 ASSERT_TRUE(foundInAllGLSLCode("_ucompound_add(_uv, angle_frm(_uu3))"));
972 ASSERT_TRUE(
973 foundInHLSLCodeRegex("compound_add_float4_float4\\(_v(\\d)*, angle_frm\\(_u3\\)\\)"));
974 // Test out parameter
975 ASSERT_TRUE(foundInAllGLSLCode("add_to_last(angle_frm(_uu4), angle_frm(_uu5), _uv2)"));
976 ASSERT_TRUE(foundInHLSLCodeRegex(
977 "add_to_last_float4_float4_float4\\(angle_frm\\(_u4\\), angle_frm\\(_u5\\), _v2(\\d)*\\)"));
978 }
979
TEST_F(DebugShaderPrecisionTest,NestedFunctionCalls)980 TEST_F(DebugShaderPrecisionTest, NestedFunctionCalls)
981 {
982 const std::string &shaderString =
983 "precision mediump float;\n"
984 "uniform vec4 u1;\n"
985 "uniform vec4 u2;\n"
986 "uniform vec4 u3;\n"
987 "vec4 add(in vec4 x, in vec4 y) {\n"
988 " return x + y;\n"
989 "}\n"
990 "vec4 compound_add(inout vec4 x, in vec4 y) {\n"
991 " x = x + y;\n"
992 " return x;\n"
993 "}\n"
994 "void main() {\n"
995 " vec4 v = u1;\n"
996 " vec4 v2 = add(compound_add(v, u2), fract(u3));\n"
997 " gl_FragColor = v + v2;\n"
998 "}\n";
999 compile(shaderString);
1000 // Test nested calls
1001 ASSERT_TRUE(foundInAllGLSLCode(
1002 "v2 = _uadd(_ucompound_add(_uv, angle_frm(_uu2)), angle_frm(fract(angle_frm(_uu3))))"));
1003 ASSERT_TRUE(foundInHLSLCodeRegex(
1004 "v2(\\d)* = f_add_float4_float4\\(f_compound_add_float4_float4\\(_v(\\d)*, "
1005 "angle_frm\\(_u2\\)\\), "
1006 "angle_frm\\(frac\\(angle_frm\\(_u3\\)\\)\\)\\)"));
1007 }
1008
1009 // Test that code inside an index of a function out parameter gets processed.
TEST_F(DebugShaderPrecisionTest,OpInIndexOfFunctionOutParameter)1010 TEST_F(DebugShaderPrecisionTest, OpInIndexOfFunctionOutParameter)
1011 {
1012 const std::string &shaderString =
1013 "precision mediump float;\n"
1014 "void foo(out vec4 f) { f.x = 0.0; }\n"
1015 "uniform float u2;\n"
1016 "void main() {\n"
1017 " vec4 v[2];\n"
1018 " foo(v[int(exp2(u2))]);\n"
1019 " gl_FragColor = v[0];\n"
1020 "}\n";
1021 compile(shaderString);
1022 ASSERT_TRUE(foundInAllGLSLCode("angle_frm(exp2(angle_frm(_uu2)))"));
1023 ASSERT_TRUE(foundInHLSLCode("angle_frm(exp2(angle_frm(_u2)))"));
1024 }
1025
1026 // Test that code inside an index of an l-value gets processed.
TEST_F(DebugShaderPrecisionTest,OpInIndexOfLValue)1027 TEST_F(DebugShaderPrecisionTest, OpInIndexOfLValue)
1028 {
1029 const std::string &shaderString =
1030 "precision mediump float;\n"
1031 "uniform vec4 u1;\n"
1032 "uniform float u2;\n"
1033 "void main() {\n"
1034 " vec4 v[2];\n"
1035 " v[int(exp2(u2))] = u1;\n"
1036 " gl_FragColor = v[0];\n"
1037 "}\n";
1038 compile(shaderString);
1039 ASSERT_TRUE(foundInAllGLSLCode("angle_frm(exp2(angle_frm(_uu2)))"));
1040 ASSERT_TRUE(foundInHLSLCode("angle_frm(exp2(angle_frm(_u2)))"));
1041 }
1042
1043 // Test that the out parameter of modf doesn't get rounded
TEST_F(DebugShaderPrecisionTest,ModfOutParameter)1044 TEST_F(DebugShaderPrecisionTest, ModfOutParameter)
1045 {
1046 const std::string &shaderString =
1047 "#version 300 es\n"
1048 "precision mediump float;\n"
1049 "uniform float u;\n"
1050 "out vec4 my_FragColor;\n"
1051 "void main() {\n"
1052 " float o;\n"
1053 " float f = modf(u, o);\n"
1054 " my_FragColor = vec4(f, o, 0, 1);\n"
1055 "}\n";
1056 compile(shaderString);
1057 ASSERT_TRUE(foundInAllGLSLCode("modf(angle_frm(_uu), _uo)"));
1058 ASSERT_TRUE(foundInHLSLCodeRegex(R"(modf\(angle_frm\(_u\), _o(\d)*)"));
1059 }
1060
1061 #if defined(ANGLE_ENABLE_HLSL)
1062 // Tests precision emulation with HLSL 3.0 output -- should error gracefully.
TEST(DebugShaderPrecisionNegativeTest,HLSL3Unsupported)1063 TEST(DebugShaderPrecisionNegativeTest, HLSL3Unsupported)
1064 {
1065 const std::string &shaderString =
1066 "precision mediump float;\n"
1067 "uniform float u;\n"
1068 "void main() {\n"
1069 " gl_FragColor = vec4(u);\n"
1070 "}\n";
1071 std::string infoLog;
1072 std::string translatedCode;
1073 ShBuiltInResources resources;
1074 sh::InitBuiltInResources(&resources);
1075 resources.WEBGL_debug_shader_precision = 1;
1076 ASSERT_FALSE(compileTestShader(GL_FRAGMENT_SHADER, SH_GLES3_SPEC, SH_HLSL_3_0_OUTPUT,
1077 shaderString, &resources, 0, &translatedCode, &infoLog));
1078 }
1079 #endif // defined(ANGLE_ENABLE_HLSL)
1080
1081 // Test that compound assignment inside an expression compiles correctly. This is a test for a bug
1082 // where incorrect type information on the compound assignment call node caused an assert to trigger
1083 // in the debug build.
TEST_F(DebugShaderPrecisionTest,CompoundAssignmentInsideExpression)1084 TEST_F(DebugShaderPrecisionTest, CompoundAssignmentInsideExpression)
1085 {
1086 const std::string &shaderString =
1087 "#version 300 es\n"
1088 "precision mediump float;\n"
1089 "out vec4 my_FragColor;\n"
1090 "void main() {\n"
1091 " float f = 0.0;\n"
1092 " my_FragColor = vec4(abs(f += 1.0), 0, 0, 1);\n"
1093 "}\n";
1094 compile(shaderString);
1095 ASSERT_TRUE(foundInAllGLSLCode("abs(angle_compound_add_frm(_uf, 1.0))"));
1096 }
1097
1098 // Test that having rounded values inside the right hand side of logical or doesn't trigger asserts
1099 // in HLSL output.
TEST_F(DebugShaderPrecisionTest,RoundedValueOnRightSideOfLogicalOr)1100 TEST_F(DebugShaderPrecisionTest, RoundedValueOnRightSideOfLogicalOr)
1101 {
1102 const std::string &shaderString =
1103 "#version 300 es\n"
1104 "precision mediump float;\n"
1105 "out vec4 my_FragColor;\n"
1106 "uniform float u1, u2;\n"
1107 "void main() {\n"
1108 " my_FragColor = vec4(u1 == 0.0 || u2 == 0.0);\n"
1109 "}\n";
1110 compile(shaderString);
1111 ASSERT_TRUE(foundInHLSLCode("angle_frm(_u2) == 0.0"));
1112 }
1113