constant-precision-qualifier.html (3968B)
1 <!-- 2 Copyright (c) 2019 The Khronos Group Inc. 3 Use of this source code is governed by an MIT-style license that can be 4 found in the LICENSE.txt file. 5 --> 6 7 <!DOCTYPE html> 8 <html> 9 <head> 10 <meta charset="utf-8"> 11 <title>Bug - the precision qualifier of a constant variable should affect the precision of a consuming operation</title> 12 <link rel="stylesheet" href="../../../resources/js-test-style.css"/> 13 <script src="../../../js/js-test-pre.js"></script> 14 <script src="../../../js/webgl-test-utils.js"></script> 15 <script src="../../../js/glsl-conformance-test.js"></script> 16 </head> 17 <body> 18 <div id="description"></div> 19 <div id="console"></div> 20 <script id="fshader" type="x-shader/x-fragment"> 21 // It is assumed that uTest is set to 0. It's here to make the expression not constant. 22 uniform mediump float uTest; 23 24 void main() { 25 // exact representation of 4096.5 requires 13 bits of relative precision. 26 const highp float c = 4096.5; 27 mediump float a = 0.0; 28 // Below, addition should be evaluated at highp, since one of the operands has the highp qualifier. 29 // Thus fract should also be evaluated at highp. 30 // See OpenGL ES Shading Language spec section 4.5.2. 31 // This should make the result 0.5, since highp provides at least 16 bits of relative precision. 32 // (exceptions for operation precision are allowed for a small number of computationally 33 // intensive built-in functions, but it is reasonable to think that fract is not one of those). 34 // However, if fract() is incorrectly evaluated at minimum precision fulfilling mediump criteria, 35 // or at IEEE half float precision, the result is 0.0. 36 a = fract(c + uTest); 37 38 // Multiply by 2.0 to make the color green. 39 gl_FragColor = vec4(0.0, 2.0 * a, 0.0, 1.0); 40 } 41 </script> 42 <script id="fshaderNoConstants" type="x-shader/x-fragment"> 43 // This shader has the same functionality as the one above, but it doesn't contain 44 // operations that can be constant folded at compile-time. 45 // It's here to provide a point of comparison. 46 uniform mediump float uTest; 47 uniform highp float uTestHigh; 48 49 void main() { 50 highp float c = 4096.5 + uTestHigh; 51 mediump float a = 0.0; 52 a = fract(c + uTest); 53 gl_FragColor = vec4(0.0, 2.0 * a, 0.0, 1.0); 54 } 55 </script> 56 <script id="fshaderAllHighp" type="x-shader/x-fragment"> 57 // This shader has the same functionality as the one above, but it only uses highp. 58 // It's here to provide a point of comparison. 59 uniform highp float uTest; 60 61 void main() { 62 highp float c = 4096.5 + uTest; 63 highp float a = 0.0; 64 a = fract(c + uTest); 65 gl_FragColor = vec4(0.0, 2.0 * a, 0.0, 1.0); 66 } 67 </script> 68 <script type="application/javascript"> 69 "use strict"; 70 description(); 71 72 function test() { 73 var wtu = WebGLTestUtils; 74 var gl = wtu.create3DContext(); 75 if (!gl) { 76 testFailed("context does not exist"); 77 finishTest(); 78 return; 79 } 80 if (gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision == 0) { 81 testPassed("highp precision not supported"); 82 finishTest(); 83 } else { 84 GLSLConformanceTester.runRenderTests([ 85 { 86 fShaderId: 'fshader', 87 fShaderSuccess: true, 88 linkSuccess: true, 89 passMsg: 'The precision qualifier of a constant affects built-in function results', 90 uniforms: [{name: "uTest", functionName: "uniform1f", value: 0}] 91 }, 92 { 93 fShaderId: 'fshaderNoConstants', 94 fShaderSuccess: true, 95 linkSuccess: true, 96 passMsg: 'The precision qualifier of a variable affects built-in function results', 97 uniforms: [{name: "uTest", functionName: "uniform1f", value: 0}, 98 {name: "uTestHigh", functionName: "uniform1f", value: 0}] 99 }, 100 { 101 fShaderId: 'fshaderAllHighp', 102 fShaderSuccess: true, 103 linkSuccess: true, 104 passMsg: 'All variables are qualified as highp', 105 uniforms: [{name: "uTest", functionName: "uniform1f", value: 0}] 106 }, 107 ]); 108 } 109 }; 110 111 test(); 112 var successfullyParsed = true; 113 </script> 114 </body> 115 </html>