gl-uniform-arrays-sub-source.html (13626B)
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 uniform array Conformance Tests</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 </head> 16 <body> 17 <div id="description"></div> 18 <div id="console"></div> 19 <canvas id="example" width="2" height="2"> </canvas> 20 <script id="vshader" type="x-shader/x-vertex">#version 300 es 21 in vec4 a_position; 22 void main() { 23 gl_Position = a_position; 24 } 25 </script> 26 27 <script id="fshader" type="x-shader/x-fragment">#version 300 es 28 precision mediump float; 29 uniform $(type) color[3]; 30 out vec4 myFragColor; 31 void main() { 32 myFragColor = vec4(color[0]$(elem), color[1]$(elem), color[2]$(elem), 1); 33 } 34 </script> 35 <script> 36 "use strict"; 37 description(); 38 debug(""); 39 var wtu = WebGLTestUtils; 40 var gl = wtu.create3DContext("example", undefined, 2); 41 42 var vSrc = wtu.getScript("vshader"); 43 var fTemplate = wtu.getScript("fshader"); 44 45 // |color| is defined in fragment shader as an array of 3 elements. 46 var uniformArraySize = 3; 47 var initialUniformValue = 99; 48 49 var typeInfos = [ 50 { type: 'float', 51 setter: 'uniform1fv', 52 elem: '', 53 numElementsPerType: 1, 54 srcValues: [16, 15], 55 srcValuesWithOffset: [0, 0, 16, 15], 56 srcValuesWithOffsetAndLength: [0, 0, 16, 15, 0], 57 srcOffset: 2, 58 }, 59 { type: 'int', 60 setter: 'uniform1iv', 61 elem: '', 62 numElementsPerType: 1, 63 srcValues: [16, 15], 64 srcValuesWithOffset: [0, 0, 16, 15], 65 srcValuesWithOffsetAndLength: [0, 0, 16, 15, 0], 66 srcOffset: 2, 67 }, 68 { type: 'uint', 69 setter: 'uniform1uiv', 70 elem: '', 71 numElementsPerType: 1, 72 srcValues: [16, 15], 73 srcValuesWithOffset: [0, 0, 16, 15], 74 srcValuesWithOffsetAndLength: [0, 0, 16, 15, 0], 75 srcOffset: 2, 76 }, 77 { type: 'vec2', 78 setter: 'uniform2fv', 79 elem: '[1]', 80 numElementsPerType: 2, 81 srcValues: [16, 15, 14, 13], 82 srcValuesWithOffset: [0, 16, 15, 14, 13], 83 srcValuesWithOffsetAndLength: [0, 16, 15, 14, 13, 0], 84 srcOffset: 1, 85 }, 86 { type: 'ivec2', 87 setter: 'uniform2iv', 88 elem: '[1]', 89 numElementsPerType: 2, 90 srcValues: [16, 15, 14, 13], 91 srcValuesWithOffset: [0, 16, 15, 14, 13], 92 srcValuesWithOffsetAndLength: [0, 16, 15, 14, 13, 0], 93 srcOffset: 1, 94 }, 95 { type: 'uvec2', 96 setter: 'uniform2uiv', 97 elem: '[1]', 98 numElementsPerType: 2, 99 srcValues: [16, 15, 14, 13], 100 srcValuesWithOffset: [0, 16, 15, 14, 13], 101 srcValuesWithOffsetAndLength: [0, 16, 15, 14, 13, 0], 102 srcOffset: 1, 103 }, 104 { type: 'vec3', 105 setter: 'uniform3fv', 106 elem: '[2]', 107 numElementsPerType: 3, 108 srcValues: [16, 15, 14, 13, 12, 11], 109 srcValuesWithOffset: [0, 16, 15, 14, 13, 12, 11], 110 srcValuesWithOffsetAndLength: [0, 16, 15, 14, 13, 12, 11, 0, 0], 111 srcOffset: 1, 112 }, 113 { type: 'ivec3', 114 setter: 'uniform3iv', 115 elem: '[2]', 116 numElementsPerType: 3, 117 srcValues: [16, 15, 14, 13, 12, 11], 118 srcValuesWithOffset: [0, 16, 15, 14, 13, 12, 11], 119 srcValuesWithOffsetAndLength: [0, 16, 15, 14, 13, 12, 11, 0, 0], 120 srcOffset: 1, 121 }, 122 { type: 'uvec3', 123 setter: 'uniform3uiv', 124 elem: '[2]', 125 numElementsPerType: 3, 126 srcValues: [16, 15, 14, 13, 12, 11], 127 srcValuesWithOffset: [0, 16, 15, 14, 13, 12, 11], 128 srcValuesWithOffsetAndLength: [0, 16, 15, 14, 13, 12, 11, 0, 0], 129 srcOffset: 1, 130 }, 131 { type: 'vec4', 132 setter: 'uniform4fv', 133 elem: '[3]', 134 numElementsPerType: 4, 135 srcValues: [16, 15, 14, 13, 12, 11, 10, 9], 136 srcValuesWithOffset: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9], 137 srcValuesWithOffsetAndLength: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 0], 138 srcOffset: 3, 139 }, 140 { type: 'ivec4', 141 setter: 'uniform4iv', 142 elem: '[3]', 143 numElementsPerType: 4, 144 srcValues: [16, 15, 14, 13, 12, 11, 10, 9], 145 srcValuesWithOffset: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9], 146 srcValuesWithOffsetAndLength: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 0], 147 srcOffset: 3, 148 }, 149 { type: 'uvec4', 150 setter: 'uniform4uiv', 151 elem: '[3]', 152 numElementsPerType: 4, 153 srcValues: [16, 15, 14, 13, 12, 11, 10, 9], 154 srcValuesWithOffset: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9], 155 srcValuesWithOffsetAndLength: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 0], 156 srcOffset: 3, 157 }, 158 159 // Matrix 160 { type: 'mat2', 161 setter: 'uniformMatrix2fv', 162 elem: '[1][1]', 163 numElementsPerType: 4, 164 srcValues: [16, 15, 14, 13, 12, 11, 10, 9], 165 srcValuesWithOffset: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9], 166 srcValuesWithOffsetAndLength: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 0], 167 srcOffset: 3, 168 }, 169 { type: 'mat3', 170 setter: 'uniformMatrix3fv', 171 elem: '[2][2]', 172 numElementsPerType: 9, 173 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8], 174 srcValuesWithOffset: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8], 175 srcValuesWithOffsetAndLength: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 0], 176 srcOffset: 3, 177 }, 178 { type: 'mat4', 179 setter: 'uniformMatrix4fv', 180 elem: '[3][3]', 181 numElementsPerType: 16, 182 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], 183 srcValuesWithOffset: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], 184 srcValuesWithOffsetAndLength: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0], 185 srcOffset: 2, 186 }, 187 { type: 'mat2x3', 188 setter: 'uniformMatrix2x3fv', 189 elem: '[1][2]', 190 numElementsPerType: 6, 191 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5], 192 srcValuesWithOffset: [0, 0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5], 193 srcValuesWithOffsetAndLength: [0, 0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 0, 0], 194 srcOffset: 4, 195 }, 196 { type: 'mat3x2', 197 setter: 'uniformMatrix3x2fv', 198 elem: '[2][1]', 199 numElementsPerType: 6, 200 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5], 201 srcValuesWithOffset: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5], 202 srcValuesWithOffsetAndLength: [0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 0, 0, 0], 203 srcOffset: 3, 204 }, 205 { type: 'mat2x4', 206 setter: 'uniformMatrix2x4fv', 207 elem: '[1][3]', 208 numElementsPerType: 8, 209 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], 210 srcValuesWithOffset: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], 211 srcValuesWithOffsetAndLength: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0], 212 srcOffset: 2, 213 }, 214 { type: 'mat4x2', 215 setter: 'uniformMatrix4x2fv', 216 elem: '[3][1]', 217 numElementsPerType: 8, 218 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], 219 srcValuesWithOffset: [0, 0, 0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], 220 srcValuesWithOffsetAndLength: [0, 0, 0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0], 221 srcOffset: 5, 222 }, 223 { type: 'mat3x4', 224 setter: 'uniformMatrix3x4fv', 225 elem: '[2][3]', 226 numElementsPerType: 12, 227 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5], 228 srcValuesWithOffset: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5], 229 srcValuesWithOffsetAndLength: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 0, 0, 0, 0], 230 srcOffset: 2, 231 }, 232 { type: 'mat4x3', 233 setter: 'uniformMatrix4x3fv', 234 elem: '[3][2]', 235 numElementsPerType: 12, 236 srcValues: [16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5], 237 srcValuesWithOffset: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5], 238 srcValuesWithOffsetAndLength: [0, 0, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 0, 0, 0, 0], 239 srcOffset: 2, 240 }, 241 242 ]; 243 244 function checkUniformValues(program, typeInfo, useInitialValues) { 245 var numSrcValues = typeInfo.srcValues.length / typeInfo.numElementsPerType; 246 for (var ii = 0; ii < uniformArraySize; ++ii) { 247 var expectedValues; 248 if (useInitialValues || ii >= numSrcValues) { 249 expectedValues = new Array(typeInfo.numElementsPerType); 250 for (var jj = 0; jj < typeInfo.numElementsPerType; ++jj) { 251 expectedValues[jj] = initialUniformValue; 252 } 253 } else { 254 expectedValues = typeInfo.srcValues.slice( 255 typeInfo.numElementsPerType * ii, typeInfo.numElementsPerType * (ii + 1)); 256 } 257 var elemLoc = gl.getUniformLocation(program, "color[" + ii + "]"); 258 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 259 "can get location of element " + ii + " of array from gl.getUniformLocation"); 260 var value = gl.getUniform(program, elemLoc); 261 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 262 "can get value of element " + ii + " of array from gl.getUniform"); 263 var equal = true; 264 if (value === null) { 265 equal = false; 266 } else if (typeInfo.numElementsPerType == 1) { 267 if (value != expectedValues[0]) { 268 equal = false; 269 } 270 } else { 271 for (var jj = 0; jj < typeInfo.numElementsPerType; ++jj) { 272 if (value[jj] != expectedValues[jj]) { 273 equal = false; 274 break; 275 } 276 } 277 } 278 assertMsg(equal, 279 "value put in (" + expectedValues + ") matches value pulled out (" + 280 (value === null ? "null" : value) + ")"); 281 } 282 } 283 284 for (var tt = 0; tt < typeInfos.length; ++tt) { 285 var typeInfo = typeInfos[tt]; 286 debug(""); 287 debug("check " + typeInfo.type); 288 var srcLength = typeInfo.srcValues.length; 289 var fSrc = wtu.replaceParams(fTemplate, typeInfo); 290 var program = wtu.loadProgram(gl, vSrc, fSrc); 291 if (!program) { 292 testFailed("Failed to create the program"); 293 continue; 294 } 295 gl.useProgram(program); 296 297 var loc = gl.getUniformLocation(program, "color[0]"); 298 if (!loc) { 299 testFailed("Failed to obtain the location of the uniform"); 300 continue; 301 } 302 303 function setter(loc, array, srcOffset, srcLength) { 304 var isMatrix = (typeInfo.setter.indexOf("Matrix") == 7); 305 if (typeof(srcOffset) != 'undefined') { 306 if (isMatrix) { 307 gl[typeInfo.setter](loc, gl.FALSE, array, srcOffset, srcLength); 308 } else { 309 gl[typeInfo.setter](loc, array, srcOffset, srcLength); 310 } 311 } else if (typeof(srcLength) != 'undefined') { 312 if (isMatrix) { 313 gl[typeInfo.setter](loc, gl.FALSE, array, srcOffset); 314 } else { 315 gl[typeInfo.setter](loc, array, srcOffset); 316 } 317 } else { 318 if (isMatrix) { 319 gl[typeInfo.setter](loc, gl.FALSE, array); 320 } else { 321 gl[typeInfo.setter](loc, array); 322 } 323 } 324 } 325 326 // Initialize uniforms to value 99 and verify it. 327 var initValues = new Array(typeInfo.numElementsPerType * uniformArraySize); 328 for (var ii = 0; ii < typeInfo.numElementsPerType * uniformArraySize; ++ii) { 329 initValues[ii] = initialUniformValue; 330 } 331 setter(loc, initValues); 332 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 333 "no error from initializing uniforms to 99"); 334 checkUniformValues(program, typeInfo, true); 335 336 setter(loc, typeInfo.srcValues); 337 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 338 "can set an array of uniforms with gl." + typeInfo.setter + 339 " without srcOffset / srcLength"); 340 checkUniformValues(program, typeInfo); 341 342 setter(loc, typeInfo.srcValues, 0); 343 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 344 "can set an array of uniforms with gl." + typeInfo.setter + 345 " with srcOffset = 0"); 346 checkUniformValues(program, typeInfo); 347 348 setter(loc, typeInfo.srcValues, 0, 0); 349 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 350 "can set an array of uniforms with gl." + typeInfo.setter + 351 " with srcOffset = 0 / srcLength = 0"); 352 checkUniformValues(program, typeInfo); 353 354 setter(loc, typeInfo.srcValuesWithOffset, typeInfo.srcOffset); 355 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 356 "can set an array of uniforms with gl." + typeInfo.setter + 357 " with srcOffset = " + typeInfo.srcOffset); 358 checkUniformValues(program, typeInfo); 359 360 setter(loc, typeInfo.srcValuesWithOffset, typeInfo.srcOffset, 0); 361 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 362 "can set an array of uniforms with gl." + typeInfo.setter + 363 " with srcOffset = " + typeInfo.srcOffset + " / srcLength = 0"); 364 checkUniformValues(program, typeInfo); 365 366 setter(loc, typeInfo.srcValuesWithOffsetAndLength, typeInfo.srcOffset, srcLength); 367 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 368 "can set an array of uniforms with gl." + typeInfo.setter + 369 " with srcOffset = " + typeInfo.srcOffset + " / srcLength = " + srcLength); 370 checkUniformValues(program, typeInfo); 371 372 wtu.glErrorShouldBe(gl, gl.NO_ERROR, "no errors"); 373 374 // Negative tests 375 setter(loc, typeInfo.srcValues, typeInfo.srcValues.length + 1); 376 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, 377 "gl." + typeInfo.setter + " with srcOffset out-of-bounds"); 378 379 setter(loc, typeInfo.srcValues, 0, typeInfo.srcValues.length + 1); 380 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, 381 "gl." + typeInfo.setter + " with srcLength out-of-bounds"); 382 383 setter(loc, typeInfo.srcValues, typeInfo.srcOffset, srcLength); 384 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, 385 "gl." + typeInfo.setter + " with srcOffset + srcLength out-of-bounds"); 386 387 setter(loc, typeInfo.srcValues, typeInfo.srcValues.length); 388 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, 389 "gl." + typeInfo.setter + " with 0 data"); 390 391 if (typeInfo.numElementsPerType > 1) { 392 setter(loc, typeInfo.srcValuesWithOffsetAndLength, typeInfo.srcOffset); 393 wtu.glErrorShouldBe(gl, gl.INVALID_VALUE, 394 "gl." + typeInfo.setter + " with array length minus srcOffset not multiple of " + typeInfo.type); 395 } 396 } 397 398 debug(""); 399 var successfullyParsed = true; 400 401 </script> 402 <script src="../../js/js-test-post.js"></script> 403 </body> 404 </html>