Backed out changeset b462e7b742d8 (bug 1908261) for causing multiple reftest failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / conformance / attribs / gl-matrix-attributes.html
blobfc7ab56b0f7d5eb538b0ab5ccc0e95509a3a3eb8
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 <!DOCTYPE html>
7 <html>
8 <head>
9 <meta charset="utf-8">
10 <link rel="stylesheet" href="../../resources/js-test-style.css"/>
11 <script src="../../js/js-test-pre.js"></script>
12 <script src="../../js/webgl-test-utils.js"></script>
13 <title>WebGL Matrix Attribute Conformance Test</title>
14 </head>
15 <body>
16 <div id="description"></div>
17 <div id="console"></div>
18 <canvas id="canvas" width="8" height="8" style="width: 8px; height: 8px;"></canvas>
19 <script>
20 "use strict";
21 description("This tests ensures that matrix attribute locations do not clash with other shader attributes.");
23 var wtu = WebGLTestUtils;
24 var canvas = document.getElementById("canvas");
25 var gl = wtu.create3DContext(canvas, {antialias: false});
27 // Make sure we have room for at least a mat4.
28 var maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
29 debug('MAX_VERTEX_ATTRIBUTES is ' + maxAttributes);
30 shouldBeGreaterThanOrEqual('maxAttributes', '4');
32 var glFragmentShader = wtu.loadShader(gl, wtu.simpleColorFragmentShader, gl.FRAGMENT_SHADER);
34 // prepareMatrixProgram creates a program with glFragmentShader as the fragment shader.
35 // The vertex shader has numVector number of vectors and a matrix with numMatrixDimensions
36 // dimensions at location numMatrixPosition in the list of attributes.
37 // Ensures that every vector and matrix is used by the program.
38 // Returns a valid program on successfull link; null on link failure.
39 function prepareMatrixProgram(numVectors, numMatrixDimensions, numMatrixPosition) {
40 // Add the matrix and vector attribute declarations. Declare the vectors
41 // to have the same number of components as the matrix so we can perform
42 // operations on them when we assign to gl_Position later on.
43 var strVertexShader = "";
44 for (var ii = 1; ii <= numVectors; ++ii) {
45 if (numMatrixPosition === ii) {
46 strVertexShader += "attribute mat" + numMatrixDimensions + " matrix;\n";
48 strVertexShader += "attribute vec" + numMatrixDimensions + " vec_" + ii + ";\n";
50 // numMatrixPosition will be one past numVectors if the caller wants it to be
51 // last. Hence, we need this check outside the loop as well as inside.
52 if (numMatrixPosition === ii) {
53 strVertexShader += "attribute mat" + numMatrixDimensions + " matrix;\n";
55 // Add the body of the shader. Add up all of the vectors and multiply by the matrix.
56 // The operations we perform do not matter. We just need to ensure that all the vector and
57 // matrix attributes are used.
58 strVertexShader += "void main(void) { \ngl_Position = vec4((";
59 for (var ii = 1; ii <= numVectors; ++ii) {
60 if (ii > 1) {
61 strVertexShader += "+"
63 strVertexShader += "vec_" + ii;
65 strVertexShader += ")*matrix";
66 // Ensure the vec4 has the correct number of dimensions in order to be assignable
67 // to gl_Position.
68 for (var ii = numMatrixDimensions; ii < 4; ++ii) {
69 strVertexShader += ",0.0";
71 strVertexShader += ");}\n";
72 // Load the shader, attach it to a program, and return the link results
73 var glVertexShader = wtu.loadShader(gl, strVertexShader, gl.VERTEX_SHADER);
74 var strTest = 'Load shader with ' + numVectors + ' vectors and 1 matrix';
75 if (glVertexShader !== null) {
76 testPassed(strTest);
78 var glProgram = gl.createProgram();
79 gl.attachShader(glProgram, glVertexShader);
80 gl.attachShader(glProgram, glFragmentShader);
81 gl.linkProgram(glProgram);
82 if (gl.getProgramParameter(glProgram, gl.LINK_STATUS)) {
83 wtu.glErrorShouldBe(gl, gl.NO_ERROR, 'linkProgram');
84 return glProgram;
86 } else {
87 testFailed(strTest);
89 return null;
92 debug('');
94 // Test mat2, mat3 and mat4.
95 for (var mm = 2; mm <= 4; ++mm) {
96 // Add maxAttribute number of attributes by saving enough room in the attribute
97 // list for a matrix of mm dimensions. All of the other attribute slots will be
98 // filled with vectors.
99 var numVectors = maxAttributes - mm;
100 for (var pp = 1; pp <= numVectors + 1; ++pp) {
101 debug('Test ' + mm + ' dimensional matrix at position ' + pp);
102 var glProgram = prepareMatrixProgram(numVectors, /*numMatrixDimensions*/mm, /*numMatrixPosition*/pp);
103 shouldBeNonNull('glProgram');
104 var attribMatrix = gl.getAttribLocation(glProgram, 'matrix');
105 debug('Matrix is at attribute location ' + attribMatrix);
106 shouldBeTrue('attribMatrix > -1');
107 // Per the spec, when an attribute is a matrix attribute, getAttribLocation
108 // returns the index of the first component of the matrix. The implementation must
109 // leave sufficient room for all the components. Here we ensure none of the vectors
110 // in the shader are assigned attribute locations that belong to the matrix.
111 for (var vv = 1; vv <= numVectors; ++vv) {
112 var strVector = 'vec_' + vv
113 var attribVector = gl.getAttribLocation(glProgram, strVector);
114 debug(strVector + ' is at attribute location ' + attribVector);
115 // Begin with the first attribute location where the matrix begins and ensure
116 // the vector's attribute location is not assigned to the matrix. Loop until
117 // we've checked all of the attribute locations that belong to the matrix.
118 for (var ii = attribMatrix; ii < attribMatrix + mm; ++ii) {
119 var testStr = strVector + ' attribute location: ' + attribVector + '. Should not be ' + ii;
120 if (attribVector !== ii) {
121 testPassed(testStr);
122 } else {
123 testFailed(testStr);
127 debug('');
129 debug('');
132 var successfullyParsed = true;
133 </script>
134 <script src="../../js/js-test-post.js"></script>
135 </body>
136 </html>