shader-varying-packing-restrictions.html (7854B)
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>WebGL varying packing restrictions Conformance Test</title> 12 <link rel="stylesheet" href="../../../resources/js-test-style.css"/> 13 <link rel="stylesheet" href="../../../resources/glsl-feature-tests.css"/> 14 <script src="../../../js/js-test-pre.js"></script> 15 <script src="../../../js/webgl-test-utils.js"></script> 16 <script src="../../../js/glsl-conformance-test.js"></script> 17 </head> 18 <body> 19 <div id="description"></div> 20 <div id="console"></div> 21 <canvas id="example" width="2" height="2"> </canvas> 22 <script id="vshaderArrayTest" type="x-shader/x-vertex"> 23 attribute vec4 a_position; 24 varying $(type) v_varying[$(numTestType)]; 25 void main() 26 { 27 gl_Position = a_position; 28 $(vcode) 29 } 30 </script> 31 <script id="fshaderArrayTest" type="x-shader/x-fragment"> 32 precision mediump float; 33 varying $(type) v_varying[$(numTestType)]; 34 void main() 35 { 36 gl_FragColor = $(fcode); 37 } 38 </script> 39 <script id="vshaderVaryingTest" type="x-shader/x-fragment"> 40 attribute vec4 a_position; 41 $(varyings) 42 void main() 43 { 44 gl_Position = a_position; 45 $(vcode) 46 } 47 </script> 48 <script id="fshaderVaryingTest" type="x-shader/x-fragment"> 49 precision mediump float; 50 $(varyings) 51 void main() 52 { 53 gl_FragColor = $(fcode); 54 } 55 </script> 56 <script> 57 "use strict"; 58 description(); 59 debug(""); 60 var wtu = WebGLTestUtils; 61 var gl = wtu.create3DContext("example"); 62 63 var varyingTypes = [ 64 { type: "float", componentsPerRow: 1, rows: 1, vcode: "v_varying$(id)$(index) = 1.0;", fcode: "vec4(v_varying$(id)$(index), 0, 0, 0)", }, 65 { type: "vec2", componentsPerRow: 2, rows: 1, vcode: "v_varying$(id)$(index) = vec2(0, 0);", fcode: "vec4(v_varying$(id)$(index), 0, 0)", }, 66 { type: "vec3", componentsPerRow: 3, rows: 1, vcode: "v_varying$(id)$(index) = vec3(0, 0, 0);", fcode: "vec4(v_varying$(id)$(index), 0)", }, 67 { type: "vec4", componentsPerRow: 4, rows: 1, vcode: "v_varying$(id)$(index) = vec4(0, 0, 0, 0);", fcode: "vec4(v_varying$(id)$(index))", }, 68 // Yes, the spec says mat2 takes 4 columns, 2 rows. 69 { type: "mat2", componentsPerRow: 4, rows: 2, vcode: "v_varying$(id)$(index) = mat2(1.0);", fcode: "vec4(v_varying$(id)$(index)[0], 0, 0)", }, 70 { type: "mat3", componentsPerRow: 3, rows: 3, vcode: "v_varying$(id)$(index) = mat3(1.0);", fcode: "vec4(v_varying$(id)$(index)[0], 0)", }, 71 { type: "mat4", componentsPerRow: 4, rows: 4, vcode: "v_varying$(id)$(index) = mat4(1.0);", fcode: "vec4(v_varying$(id)$(index)[0])", }, 72 ]; 73 74 var vArrayTestSource = wtu.getScript("vshaderArrayTest"); 75 var fArrayTestSource = wtu.getScript("fshaderArrayTest"); 76 var vVaryingTestSource = wtu.getScript("vshaderVaryingTest"); 77 var fVaryingTestSource = wtu.getScript("fshaderVaryingTest"); 78 79 var minVaryingVectors = 8; 80 var maxVaryingVectors = gl.getParameter(gl.MAX_VARYING_VECTORS); 81 var tests = []; 82 83 for (var ii = 0; ii < varyingTypes.length; ++ii) { 84 var info = varyingTypes[ii]; 85 wtu.log("checking: " + info.type); 86 // Compute the maximum amount of this type allowed in a single array. 87 var numVars = Math.floor(maxVaryingVectors / info.rows); 88 // Compute the minimum required to work in a single array. 89 var minVars = Math.floor(minVaryingVectors / info.rows); 90 // Compute the maximum allowed as single elements 91 var numPerRow = Math.floor(4 / info.componentsPerRow); 92 var numMax = Math.floor(maxVaryingVectors * numPerRow / info.rows); 93 94 // Test array[1] of the type 95 var vcode = wtu.replaceParams(info.vcode, {id: "", index: "[0]"}); 96 var fcode = wtu.replaceParams(info.fcode, {id: "", index: "[0]"}); 97 tests.push({ 98 vShaderSource: wtu.replaceParams(vArrayTestSource, {numTestType: 1, vcode: vcode}, info), 99 vShaderSuccess: true, 100 fShaderSource: wtu.replaceParams(fArrayTestSource, {numTestType: 1, fcode: fcode}, info), 101 fShaderSuccess: true, 102 linkSuccess: true, 103 passMsg: "shaders with varying array of " + info.type + " with 1 element should succeed", 104 }); 105 106 // Test required number of varyings 107 var vcode = wtu.replaceParams(info.vcode, {id: "", index: "[" + (minVars - 1) + "]"}); 108 var fcode = wtu.replaceParams(info.fcode, {id: "", index: "[" + (minVars - 1) + "]"}); 109 tests.push({ 110 vShaderSource: wtu.replaceParams(vArrayTestSource, {numTestType: minVars, vcode: vcode}, info), 111 vShaderSuccess: true, 112 fShaderSource: wtu.replaceParams(fArrayTestSource, {numTestType: minVars, fcode: fcode}, info), 113 fShaderSuccess: true, 114 linkSuccess: true, 115 passMsg: "shaders with varying array of " + info.type + " with " + minVars + " elements (the minimum required) should succeed", 116 }); 117 118 // Test array[max + 1] accessing last element. WebGL requires this to fail. 119 var vcode = wtu.replaceParams(info.vcode, {id: "", index: "[" + numVars + "]"}); 120 var fcode = wtu.replaceParams(info.fcode, {id: "", index: "[" + numVars + "]"}); 121 tests.push({ 122 vShaderSource: wtu.replaceParams(vArrayTestSource, {numTestType: numVars + 1, vcode: vcode}, info), 123 vShaderSuccess: false, 124 fShaderSource: wtu.replaceParams(fArrayTestSource, {numTestType: numVars + 1, fcode: fcode}, info), 125 fShaderSuccess: false, 126 linkSuccess: false, 127 passMsg: "shaders with varying array of " + info.type + " with " + (numVars + 1) + " elements (one past maximum) accessing last element should fail", 128 }); 129 130 // Test array[max + 1] accessing first element. WebGL requires this to fail but ES allows truncating array. 131 var vcode = wtu.replaceParams(info.vcode, {id: "", index: "[0]"}); 132 var fcode = wtu.replaceParams(info.fcode, {id: "", index: "[0]"}); 133 tests.push({ 134 vShaderSource: wtu.replaceParams(vArrayTestSource, {numTestType: numVars + 1, vcode: vcode}, info), 135 vShaderSuccess: false, 136 fShaderSource: wtu.replaceParams(fArrayTestSource, {numTestType: numVars + 1, fcode: fcode}, info), 137 fShaderSuccess: false, 138 linkSuccess: false, 139 passMsg: "shaders with varying array of " + info.type + " with " + (numVars + 1) + " elements (one past maximum) accessing first element should fail", 140 }); 141 142 // Note: We can't test max varyings as actual GL drivers are only required to be able to 143 // do the minimum number. After that it can fail for any reason, for example running out of 144 // instruction space. 145 146 var generateCode = function(numVars) { 147 var varyings = []; 148 var vcodes = []; 149 var fcodes = []; 150 for (var uu = 0; uu < numVars; ++uu) { 151 varyings.push(" varying " + info.type + " v_varying" + uu + ";"); 152 vcodes.push(wtu.replaceParams(info.vcode, {id: uu, index: ""})); 153 fcodes.push(wtu.replaceParams(info.fcode, {id: uu, index: ""})); 154 } 155 return { 156 varyings: varyings.join("\n"), 157 vcode: vcodes.join("\n "), 158 fcode: fcodes.join(" + \n "), 159 }; 160 }; 161 162 // Test max+1 varyings of type. 163 tests.push({ 164 vShaderSource: wtu.replaceParams(vVaryingTestSource, generateCode(numMax + 1), info), 165 vShaderSuccess: false, 166 fShaderSource: wtu.replaceParams(fVaryingTestSource, generateCode(numMax + 1), info), 167 fShaderSuccess: false, 168 linkSuccess: false, 169 passMsg: "shaders with " + (numMax + 1) + " varyings of " + info.type + " (one past maximum) should fail", 170 }); 171 172 // Test required varyings of type. 173 tests.push({ 174 vShaderSource: wtu.replaceParams(vVaryingTestSource, generateCode(minVars), info), 175 vShaderSuccess: true, 176 fShaderSource: wtu.replaceParams(fVaryingTestSource, generateCode(minVars), info), 177 fShaderSuccess: true, 178 linkSuccess: true, 179 passMsg: "shaders with " + minVars + " varyings of " + info.type + " (the minimum required) should succeed", 180 }); 181 } 182 183 GLSLConformanceTester.runTests(tests); 184 var successfullyParsed = true; 185 </script> 186 </body> 187 </html>