Bug 1945965 – remove new tab April Fools logo. r=home-newtab-reviewers,reemhamz
[gecko.git] / dom / canvas / test / webgl-conf / checkout / deqp / modules / shared / glsShaderRenderCase.js
blob31f59de1f6b2d18f850301597d3e2d6876036ed8
1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES Utilities
3 * ------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 'use strict';
22 goog.provide('modules.shared.glsShaderRenderCase');
23 goog.require('framework.common.tcuImageCompare');
24 goog.require('framework.common.tcuMatrix');
25 goog.require('framework.common.tcuRGBA');
26 goog.require('framework.common.tcuSurface');
27 goog.require('framework.common.tcuTestCase');
28 goog.require('framework.common.tcuTexture');
29 goog.require('framework.delibs.debase.deMath');
30 goog.require('framework.delibs.debase.deString');
31 goog.require('framework.delibs.debase.deRandom');
32 goog.require('framework.opengl.gluDrawUtil');
33 goog.require('framework.opengl.gluTexture');
34 goog.require('framework.opengl.gluTextureUtil');
35 goog.require('framework.opengl.gluShaderProgram');
37 goog.scope(function() {
38 var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
40 var deMath = framework.delibs.debase.deMath;
41 var deString = framework.delibs.debase.deString;
42 var deRandom = framework.delibs.debase.deRandom;
43 var gluTextureUtil = framework.opengl.gluTextureUtil;
44 var gluTexture = framework.opengl.gluTexture;
45 var gluDrawUtil = framework.opengl.gluDrawUtil;
46 var tcuImageCompare = framework.common.tcuImageCompare;
47 var tcuTexture = framework.common.tcuTexture;
48 var tcuMatrix = framework.common.tcuMatrix;
49 var tcuRGBA = framework.common.tcuRGBA;
50 var tcuTestCase = framework.common.tcuTestCase;
51 var tcuSurface = framework.common.tcuSurface;
52 var gluShaderProgram = framework.opengl.gluShaderProgram;
54 /** @typedef {function(glsShaderRenderCase.ShaderEvalContext)} */ glsShaderRenderCase.ShaderEvalFunc;
56 /** @const {number} */ glsShaderRenderCase.GRID_SIZE = 64;
57 /** @const {number} */ glsShaderRenderCase.MAX_RENDER_WIDTH = 128;
58 /** @const {number} */ glsShaderRenderCase.MAX_RENDER_HEIGHT = 112;
59 /** @const {Array<number>} */ glsShaderRenderCase.DEFAULT_CLEAR_COLOR = [0.125, 0.25, 0.5, 1.0];
60 /** @const {number} */ glsShaderRenderCase.MAX_USER_ATTRIBS = 4;
61 /** @const {number} */ glsShaderRenderCase.MAX_TEXTURES = 4;
63 /**
64 * @param {Array<number>} a
65 * @return {tcuRGBA.RGBA}
67 glsShaderRenderCase.toRGBA = function(a) {
68 return tcuRGBA.newRGBAComponents(
69 deMath.clamp(Math.round(a[0] * 255.0), 0, 255),
70 deMath.clamp(Math.round(a[1] * 255.0), 0, 255),
71 deMath.clamp(Math.round(a[2] * 255.0), 0, 255),
72 deMath.clamp(Math.round(a[3] * 255.0), 0, 255));
75 /**
76 * Helper function
77 * @param {?(gluTexture.Texture2D|gluTexture.TextureCube|gluTexture.Texture2DArray|gluTexture.Texture3D)} tex
78 * @return {gluTexture.Type}
80 glsShaderRenderCase.getTextureType = function(tex) {
81 if (tex === null || tex.getType() <= 0)
82 return gluTexture.Type.TYPE_NONE;
83 else
84 return tex.getType();
87 /**
88 * @constructor
89 * @param {number=} indent
91 glsShaderRenderCase.LineStream = function(indent) {
92 indent = indent === undefined ? 0 : indent;
93 /** @type {number} */ this.m_indent = indent;
94 /** @type {string} */ this.m_stream;
95 /** @type {string} */ this.m_string;
98 /**
99 * @return {string}
101 glsShaderRenderCase.LineStream.prototype.str = function() {
102 this.m_string = this.m_stream;
103 return this.m_string;
107 * @constructor
108 * @param {(gluTexture.Texture2D|gluTexture.TextureCube|gluTexture.Texture2DArray|gluTexture.Texture3D)=} tex
109 * @param {tcuTexture.Sampler=} sampler
111 glsShaderRenderCase.TextureBinding = function(tex, sampler) {
112 tex = tex === undefined ? null : tex;
113 sampler = sampler === undefined ? null : sampler;
114 /** @type {gluTexture.Type} */ this.m_type = glsShaderRenderCase.getTextureType(tex);
115 /** @type {tcuTexture.Sampler} */ this.m_sampler = sampler;
116 /** @type {(gluTexture.Texture2D|gluTexture.TextureCube|gluTexture.Texture2DArray|gluTexture.Texture3D)} */
117 this.m_binding = tex;
121 * @param {tcuTexture.Sampler} sampler
123 glsShaderRenderCase.TextureBinding.prototype.setSampler = function(sampler) {
124 this.m_sampler = sampler;
128 * @param {(gluTexture.Texture2D|gluTexture.TextureCube|gluTexture.Texture2DArray|gluTexture.Texture3D)} tex
130 glsShaderRenderCase.TextureBinding.prototype.setTexture = function(tex) {
131 this.m_type = glsShaderRenderCase.getTextureType(tex);
132 this.m_binding = tex;
135 /** @return {gluTexture.Type} */
136 glsShaderRenderCase.TextureBinding.prototype.getType = function() {
137 return this.m_type;
140 /** @return {tcuTexture.Sampler} */
141 glsShaderRenderCase.TextureBinding.prototype.getSampler = function() {
142 return this.m_sampler;
145 /** @return {(gluTexture.Texture2D|gluTexture.TextureCube|gluTexture.Texture2DArray|gluTexture.Texture3D)} */
146 glsShaderRenderCase.TextureBinding.prototype.getBinding = function() {
147 return this.m_binding;
151 * @constructor
152 * @param {number} gridSize
153 * @param {number} width
154 * @param {number} height
155 * @param {Array<number>} constCoords
156 * @param {Array<tcuMatrix.Matrix>} userAttribTransforms
157 * @param {Array<glsShaderRenderCase.TextureBinding>} textures
159 glsShaderRenderCase.QuadGrid = function(gridSize, width, height, constCoords, userAttribTransforms, textures) {
160 /** @type {number} */ this.m_gridSize = gridSize;
161 /** @type {number} */ this.m_numVertices = (gridSize + 1) * (gridSize + 1);
162 /** @type {number} */ this.m_numTriangles = (gridSize * gridSize *2);
163 /** @type {Array<number>} */ this.m_constCoords = constCoords;
164 /** @type {Array<tcuMatrix.Matrix>} */ this.m_userAttribTransforms = userAttribTransforms;
165 /** @type {Array<glsShaderRenderCase.TextureBinding>} */ this.m_textures = textures;
166 /** @type {Array<Array<number>>} */ this.m_screenPos = [];
167 /** @type {Array<Array<number>>} */ this.m_positions = [];
168 /** @type {Array<Array<number>>} */ this.m_coords = []; //!< Near-unit coordinates, roughly [-2.0 .. 2.0].
169 /** @type {Array<Array<number>>} */ this.m_unitCoords = []; //!< Positive-only coordinates [0.0 .. 1.5].
170 /** @type {Array<number>} */ this.m_attribOne = [];
171 /** @type {Array<Array<number>>} */ this.m_userAttribs = [];
172 for (var attribNdx = 0; attribNdx < this.getNumUserAttribs(); attribNdx++)
173 this.m_userAttribs[attribNdx] = [];
174 /** @type {Array<number>} */ this.m_indices = [];
176 /** @type Array<number>} */ var viewportScale = [width, height, 0, 0];
177 for (var y = 0; y < gridSize + 1; y++)
178 for (var x = 0; x < gridSize + 1; x++) {
179 /** @type {number} */ var sx = x / gridSize;
180 /** @type {number} */ var sy = y / gridSize;
181 /** @type {number} */ var fx = 2.0 * sx - 1.0;
182 /** @type {number} */ var fy = 2.0 * sy - 1.0;
183 /** @type {number} */ var vtxNdx = ((y * (gridSize + 1)) + x);
185 this.m_positions[vtxNdx] = [fx, fy, 0.0, 1.0];
186 this.m_attribOne[vtxNdx] = 1.0;
187 this.m_screenPos[vtxNdx] = deMath.multiply([sx, sy, 0.0, 1.0], viewportScale);
188 this.m_coords[vtxNdx] = this.getCoords(sx, sy);
189 this.m_unitCoords[vtxNdx] = this.getUnitCoords(sx, sy);
191 for (var attribNdx = 0; attribNdx < this.getNumUserAttribs(); attribNdx++)
192 this.m_userAttribs[attribNdx][vtxNdx] = this.getUserAttrib(attribNdx, sx, sy);
195 // Compute indices.
196 for (var y = 0; y < gridSize; y++)
197 for (var x = 0; x < gridSize; x++) {
198 /** @type {number} */ var stride = gridSize + 1;
199 /** @type {number} */ var v00 = (y * stride) + x;
200 /** @type {number} */ var v01 = (y * stride) + x + 1;
201 /** @type {number} */ var v10 = ((y + 1) * stride) + x;
202 /** @type {number} */ var v11 = ((y + 1) * stride) + x + 1;
204 /** @type {number} */ var baseNdx = ((y * gridSize) + x) * 6;
205 this.m_indices[baseNdx + 0] = v10;
206 this.m_indices[baseNdx + 1] = v00;
207 this.m_indices[baseNdx + 2] = v01;
209 this.m_indices[baseNdx + 3] = v10;
210 this.m_indices[baseNdx + 4] = v01;
211 this.m_indices[baseNdx + 5] = v11;
215 /** @return {number} */
216 glsShaderRenderCase.QuadGrid.prototype.getGridSize = function() {
217 return this.m_gridSize;
220 /** @return {number} */
221 glsShaderRenderCase.QuadGrid.prototype.getNumVertices = function() {
222 return this.m_numVertices;
225 /** @return {number} */
226 glsShaderRenderCase.QuadGrid.prototype.getNumTriangles = function() {
227 return this.m_numTriangles;
230 /** @return {Array<number>} */
231 glsShaderRenderCase.QuadGrid.prototype.getConstCoords = function() {
232 return this.m_constCoords;
235 /** @return {Array<tcuMatrix.Matrix>} */
236 glsShaderRenderCase.QuadGrid.prototype.getUserAttribTransforms = function() {
237 return this.m_userAttribTransforms;
240 /** @return {Array<glsShaderRenderCase.TextureBinding>} */
241 glsShaderRenderCase.QuadGrid.prototype.getTextures = function() {
242 return this.m_textures;
245 /** @return {Array<Array<number>>} */
246 glsShaderRenderCase.QuadGrid.prototype.getPositions = function() {
247 return this.m_positions;
250 /** @return {Array<number>} */
251 glsShaderRenderCase.QuadGrid.prototype.getAttribOne = function() {
252 return this.m_attribOne;
255 /** @return {Array<Array<number>>} */
256 glsShaderRenderCase.QuadGrid.prototype.getCoordsArray = function() {
257 return this.m_coords;
260 /** @return {Array<Array<number>>} */
261 glsShaderRenderCase.QuadGrid.prototype.getUnitCoordsArray = function() {
262 return this.m_unitCoords;
266 * @param {number} attribNdx
267 * @return {Array<number>}
269 glsShaderRenderCase.QuadGrid.prototype.getUserAttribByIndex = function(attribNdx) {
270 return this.m_userAttribs[attribNdx];
273 /** @return {Array<number>} */
274 glsShaderRenderCase.QuadGrid.prototype.getIndices = function() {
275 return this.m_indices;
279 * @param {number} sx
280 * @param {number} sy
281 * @return {Array<number>}
283 glsShaderRenderCase.QuadGrid.prototype.getCoords = function(sx, sy) {
284 /** @type {number} */ var fx = 2.0 * sx - 1.0;
285 /** @type {number} */ var fy = 2.0 * sy - 1.0;
286 return [fx, fy, -fx + 0.33 * fy, -0.275 * fx - fy];
290 * @param {number} sx
291 * @param {number} sy
292 * @return {Array<number>}
294 glsShaderRenderCase.QuadGrid.prototype.getUnitCoords = function(sx, sy) {
295 return [sx, sy, 0.33 * sx + 0.5 * sy, 0.5 * sx + 0.25 * sy];
299 * @return {number}
301 glsShaderRenderCase.QuadGrid.prototype.getNumUserAttribs = function() {
302 return this.m_userAttribTransforms.length;
306 * @param {number} attribNdx
307 * @param {number} sx
308 * @param {number} sy
309 * @return {Array<number>}
311 glsShaderRenderCase.QuadGrid.prototype.getUserAttrib = function(attribNdx, sx, sy) {
312 // homogeneous normalized screen-space coordinates
313 return tcuMatrix.multiplyMatVec(this.m_userAttribTransforms[attribNdx], [sx, sy, 0.0, 1.0]);
317 * @constructor
318 * @struct
320 glsShaderRenderCase.ShaderSampler = function() {
321 /** @type {tcuTexture.Sampler} */ this.sampler;
322 /** @type {tcuTexture.Texture2D} */ this.tex2D = null;
323 /** @type {tcuTexture.TextureCube} */ this.texCube = null;
324 /** @type {tcuTexture.Texture2DArray} */ this.tex2DArray = null;
325 /** @type {tcuTexture.Texture3D} */ this.tex3D = null;
329 * @constructor
330 * @param {glsShaderRenderCase.QuadGrid} quadGrid_
332 glsShaderRenderCase.ShaderEvalContext = function(quadGrid_) {
333 /** @type {Array<number>} */ this.coords = [0, 0, 0, 0]
334 /** @type {Array<number>} */ this.unitCoords = [0, 0, 0, 0]
335 /** @type {Array<number>} */ this.constCoords = quadGrid_.getConstCoords();
336 /** @type {Array<Array<number>>} */ this.in_ = [];
337 /** @type {Array<glsShaderRenderCase.ShaderSampler>} */ this.textures = [];
338 /** @type {Array<number>} */ this.color = [0, 0, 0, 0.0];
339 /** @type {boolean} */ this.isDiscarded = false;
340 /** @type {glsShaderRenderCase.QuadGrid} */ this.quadGrid = quadGrid_;
342 /** @type {Array<glsShaderRenderCase.TextureBinding>} */ var bindings = this.quadGrid.getTextures();
343 assertMsgOptions(bindings.length <= glsShaderRenderCase.MAX_TEXTURES, 'Too many bindings.', false, true);
345 // Fill in texture array.
346 for (var ndx = 0; ndx < bindings.length; ndx++) {
347 /** @type {glsShaderRenderCase.TextureBinding} */ var binding = bindings[ndx];
349 this.textures[ndx] = new glsShaderRenderCase.ShaderSampler();
351 if (binding.getType() == gluTexture.Type.TYPE_NONE)
352 continue;
354 this.textures[ndx].sampler = binding.getSampler();
356 switch (binding.getType()) {
357 case gluTexture.Type.TYPE_2D:
358 this.textures[ndx].tex2D = binding.getBinding().getRefTexture();
359 break;
360 case gluTexture.Type.TYPE_CUBE_MAP:
361 this.textures[ndx].texCube = binding.getBinding().getRefTexture();
362 break;
363 case gluTexture.Type.TYPE_2D_ARRAY:
364 this.textures[ndx].tex2DArray = binding.getBinding().getRefTexture();
365 break;
366 case gluTexture.Type.TYPE_3D:
367 this.textures[ndx].tex3D = binding.getBinding().getRefTexture();
368 break;
369 default:
370 throw new Error("Binding type not supported");
376 * @param {number} sx
377 * @param {number} sy
379 glsShaderRenderCase.ShaderEvalContext.prototype.reset = function(sx, sy) {
380 // Clear old values
381 this.color = [0.0, 0.0, 0.0, 1.0];
382 this.isDiscarded = false;
384 // Compute coords
385 this.coords = this.quadGrid.getCoords(sx, sy);
386 this.unitCoords = this.quadGrid.getUnitCoords(sx, sy);
388 // Compute user attributes.
389 /** @type {number} */ var numAttribs = this.quadGrid.getNumUserAttribs();
390 assertMsgOptions(numAttribs <= glsShaderRenderCase.MAX_USER_ATTRIBS, 'numAttribs out of range', false, true);
391 for (var attribNdx = 0; attribNdx < numAttribs; attribNdx++)
392 this.in_[attribNdx] = this.quadGrid.getUserAttrib(attribNdx, sx, sy);
395 glsShaderRenderCase.ShaderEvalContext.prototype.discard = function() {
396 this.isDiscarded = true;
400 * @param {number} unitNdx
401 * @param {Array<number>} coords
403 glsShaderRenderCase.ShaderEvalContext.prototype.texture2D = function(unitNdx, coords) {
404 if (this.textures.length > 0 && this.textures[unitNdx].tex2D)
405 return this.textures[unitNdx].tex2D.getView().sample(this.textures[unitNdx].sampler, coords, 0.0);
406 else
407 return [0.0, 0.0, 0.0, 1.0];
410 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
411 glsShaderRenderCase.evalCoordsPassthroughX = function(c) {
412 c.color[0] = c.coords[0];
415 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
416 glsShaderRenderCase.evalCoordsPassthroughXY = function(c) {
417 var swizzle01 = deMath.swizzle(c.coords, [0, 1]);
418 c.color[0] = swizzle01[0];
419 c.color[1] = swizzle01[1];
422 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
423 glsShaderRenderCase.evalCoordsPassthroughXYZ = function(c) {
424 var swizzle012 = deMath.swizzle(c.coords, [0, 1, 2]);
425 c.color[0] = swizzle012[0];
426 c.color[1] = swizzle012[1];
427 c.color[2] = swizzle012[2];
430 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
431 glsShaderRenderCase.evalCoordsPassthrough = function(c) {
432 c.color = c.coords;
435 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
436 glsShaderRenderCase.evalCoordsSwizzleWZYX = function(c) {
437 c.color = deMath.swizzle(c.coords, [3, 2, 1, 0]);
441 * @constructor
442 * @param {?glsShaderRenderCase.ShaderEvalFunc=} evalFunc
444 glsShaderRenderCase.ShaderEvaluator = function(evalFunc) {
445 /** @type {?glsShaderRenderCase.ShaderEvalFunc} */ this.m_evalFunc = evalFunc || null;
449 * @param {glsShaderRenderCase.ShaderEvalContext} ctx
451 glsShaderRenderCase.ShaderEvaluator.prototype.evaluate = function(ctx) {
452 assertMsgOptions(this.m_evalFunc !== null, 'No evaluation function specified.', false, true);
453 this.m_evalFunc(ctx);
457 * @constructor
458 * @extends {tcuTestCase.DeqpTest}
459 * @param {string} name
460 * @param {string} description
461 * @param {boolean} isVertexCase
462 * @param {glsShaderRenderCase.ShaderEvalFunc=} evalFunc
464 glsShaderRenderCase.ShaderRenderCase = function(name, description, isVertexCase, evalFunc) {
465 tcuTestCase.DeqpTest.call(this, name, description);
466 // evalFunc = evalFunc || null;
467 /** @type {boolean} */ this.m_isVertexCase = isVertexCase;
468 /** @type {?glsShaderRenderCase.ShaderEvalFunc} */ this.m_defaultEvaluator = evalFunc || null;
469 /** @type {glsShaderRenderCase.ShaderEvaluator} */ this.m_evaluator = new glsShaderRenderCase.ShaderEvaluator(this.m_defaultEvaluator);
470 /** @type {string} */ this.m_vertShaderSource = '';
471 /** @type {string} */ this.m_fragShaderSource = '';
472 /** @type {Array<number>} */ this.m_clearColor = glsShaderRenderCase.DEFAULT_CLEAR_COLOR;
473 /** @type {Array<tcuMatrix.Matrix>} */ this.m_userAttribTransforms = [];
474 /** @type {Array<glsShaderRenderCase.TextureBinding>} */ this.m_textures = [];
475 /** @type {?gluShaderProgram.ShaderProgram} */ this.m_program = null;
479 * @param {string} name
480 * @param {string} description
481 * @param {boolean} isVertexCase
482 * @param {glsShaderRenderCase.ShaderEvaluator} evaluator
483 * @return {glsShaderRenderCase.ShaderRenderCase}
485 glsShaderRenderCase.ShaderRenderCase.newWithEvaluator = function(name, description, isVertexCase, evaluator) {
486 var renderCase = new glsShaderRenderCase.ShaderRenderCase(name, description, isVertexCase);
487 renderCase.m_evaluator = evaluator;
488 return renderCase;
491 glsShaderRenderCase.ShaderRenderCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
492 glsShaderRenderCase.ShaderRenderCase.prototype.constructor = glsShaderRenderCase.ShaderRenderCase;
494 glsShaderRenderCase.ShaderRenderCase.prototype.deinit = function() {
495 this.m_program = null;
498 glsShaderRenderCase.ShaderRenderCase.prototype.init = function() {
499 this.postinit();
502 glsShaderRenderCase.ShaderRenderCase.prototype.postinit = function() {
503 if (this.m_vertShaderSource.length === 0 || this.m_fragShaderSource.length === 0) {
504 assertMsgOptions(this.m_vertShaderSource.length === 0 && this.m_fragShaderSource.length === 0, 'No shader source.', false, true);
505 this.setupShaderData();
508 assertMsgOptions(!this.m_program, 'Program defined.', false, true);
509 this.m_program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(this.m_vertShaderSource, this.m_fragShaderSource));
511 try {
512 bufferedLogToConsole(this.m_program.program.info.infoLog); // Always log shader program.
514 if (!this.m_program.isOk())
515 throw new Error("Shader compile error.");
517 catch (exception) {
518 // Clean up.
519 this.deinit();
520 throw exception;
525 * @return {tcuTestCase.IterateResult}
527 glsShaderRenderCase.ShaderRenderCase.prototype.postiterate = function() {
528 assertMsgOptions(this.m_program !== null, 'Program not specified.', false, true);
529 /** @type {?WebGLProgram} */ var programID = this.m_program.getProgram();
530 gl.useProgram(programID);
532 // Create quad grid.
533 /** @type {Array<number>} */ var viewportSize = this.getViewportSize();
534 /** @type {number} */ var width = viewportSize[0];
535 /** @type {number} */ var height = viewportSize[1];
537 // \todo [petri] Better handling of constCoords (render in multiple chunks, vary coords).
538 /** @type {glsShaderRenderCase.QuadGrid} */
539 var quadGrid = new glsShaderRenderCase.QuadGrid(
540 this.m_isVertexCase ? glsShaderRenderCase.GRID_SIZE : 4, width, height,
541 [0.125, 0.25, 0.5, 1.0], this.m_userAttribTransforms, this.m_textures);
543 // Render result.
544 /** @type {tcuSurface.Surface} */ var resImage = new tcuSurface.Surface(width, height);
545 this.render(resImage, programID, quadGrid);
547 // Compute reference.
548 /** @type {tcuSurface.Surface} */ var refImage = new tcuSurface.Surface(width, height);
549 if (this.m_isVertexCase)
550 this.computeVertexReference(refImage, quadGrid);
551 else
552 this.computeFragmentReference(refImage, quadGrid);
554 // Compare.
555 /** @type {boolean} */ var testOk = this.compareImages(resImage, refImage, 0.05);
557 // De-initialize.
558 gl.useProgram(null);
560 if (!testOk)
561 testFailedOptions("Fail", false);
562 else
563 testPassedOptions("Pass", true);
565 return tcuTestCase.IterateResult.STOP;
569 * @return {tcuTestCase.IterateResult}
571 glsShaderRenderCase.ShaderRenderCase.prototype.iterate = function() {
572 return this.postiterate();
575 glsShaderRenderCase.ShaderRenderCase.prototype.setupShaderData = function() {};
578 * @param {?WebGLProgram} programId
580 glsShaderRenderCase.ShaderRenderCase.prototype.setup = function(programId) {};
583 * @param {?WebGLProgram} programId
584 * @param {Array<number>} constCoords
586 glsShaderRenderCase.ShaderRenderCase.prototype.setupUniforms = function(programId, constCoords) {};
589 * @return {Array<number>}
591 glsShaderRenderCase.ShaderRenderCase.prototype.getViewportSize = function() {
592 return [Math.min(gl.canvas.width, glsShaderRenderCase.MAX_RENDER_WIDTH),
593 Math.min(gl.canvas.height, glsShaderRenderCase.MAX_RENDER_HEIGHT)];
597 * @param {?WebGLProgram} programId
599 glsShaderRenderCase.ShaderRenderCase.prototype.setupDefaultInputs = function(programId) {
600 // SETUP UNIFORMS.
601 glsShaderRenderCase.setupDefaultUniforms(programId);
603 // SETUP TEXTURES.
604 for (var ndx = 0; ndx < this.m_textures.length; ndx++) {
605 /** @type {glsShaderRenderCase.TextureBinding} */ var tex = this.m_textures[ndx];
606 /** @type {tcuTexture.Sampler} */ var sampler = tex.getSampler();
607 /** @type {number} */ var texTarget = gl.NONE;
608 /** @type {number} */ var texObj = 0;
610 if (tex.getType() === gluTexture.Type.TYPE_NONE)
611 continue;
613 switch (tex.getType()) {
614 case gluTexture.Type.TYPE_2D:
615 texTarget = gl.TEXTURE_2D;
616 texObj = tex.getBinding().getGLTexture();
617 break;
618 case gluTexture.Type.TYPE_CUBE_MAP:
619 texTarget = gl.TEXTURE_CUBE_MAP;
620 texObj = tex.getBinding().getGLTexture();
621 break;
622 case gluTexture.Type.TYPE_2D_ARRAY:
623 texTarget = gl.TEXTURE_2D_ARRAY;
624 texObj = tex.getBinding().getGLTexture();
625 break;
626 case gluTexture.Type.TYPE_3D:
627 texTarget = gl.TEXTURE_3D;
628 texObj = tex.getBinding().getGLTexture();
629 break;
630 default:
631 throw new Error("Type not supported");
634 gl.activeTexture(gl.TEXTURE0+ ndx);
635 gl.bindTexture(texTarget, texObj);
636 gl.texParameteri(texTarget, gl.TEXTURE_WRAP_S, gluTextureUtil.getGLWrapMode(sampler.wrapS));
637 gl.texParameteri(texTarget, gl.TEXTURE_WRAP_T, gluTextureUtil.getGLWrapMode(sampler.wrapT));
638 gl.texParameteri(texTarget, gl.TEXTURE_MIN_FILTER, gluTextureUtil.getGLFilterMode(sampler.minFilter));
639 gl.texParameteri(texTarget, gl.TEXTURE_MAG_FILTER, gluTextureUtil.getGLFilterMode(sampler.magFilter));
641 if (texTarget === gl.TEXTURE_3D)
642 gl.texParameteri(texTarget, gl.TEXTURE_WRAP_R, gluTextureUtil.getGLWrapMode(sampler.wrapR));
644 if (sampler.compare != tcuTexture.CompareMode.COMPAREMODE_NONE)
646 gl.texParameteri(texTarget, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
647 gl.texParameteri(texTarget, gl.TEXTURE_COMPARE_FUNC, gluTextureUtil.getGLCompareFunc(sampler.compare));
653 * @param {tcuSurface.Surface} result
654 * @param {?WebGLProgram} programId
655 * @param {glsShaderRenderCase.QuadGrid} quadGrid
657 glsShaderRenderCase.ShaderRenderCase.prototype.render = function(result, programId, quadGrid) {
658 // Buffer info.
659 /** @type {number} */ var width = result.getWidth();
660 /** @type {number} */ var height = result.getHeight();
662 /** @type {number} */ var xOffsetMax = gl.drawingBufferWidth - width;
663 /** @type {number} */ var yOffsetMax = gl.drawingBufferHeight - height;
665 /** @type {number} */ var hash = deString.deStringHash(this.m_vertShaderSource) + deString.deStringHash(this.m_fragShaderSource);
666 /** @type {deRandom.Random} */ var rnd = new deRandom.Random(hash);
668 /** @type {number} */ var xOffset = rnd.getInt(0, xOffsetMax);
669 /** @type {number} */ var yOffset = rnd.getInt(0, yOffsetMax);
671 gl.viewport(xOffset, yOffset, width, height);
673 // Setup program.
674 this.setupUniforms(programId, quadGrid.getConstCoords());
675 this.setupDefaultInputs(programId);
677 // Clear.
678 gl.clearColor(this.m_clearColor[0], this.m_clearColor[1], this.m_clearColor[2], this.m_clearColor[3]);
679 gl.clear(gl.COLOR_BUFFER_BIT);
681 // Draw.
682 /** @type {Array<gluDrawUtil.VertexArrayBinding>} */ var vertexArrays = [];
683 /** @type {number} */ var numElements = quadGrid.getNumTriangles()*3;
685 glsShaderRenderCase.getDefaultVertexArrays(quadGrid, programId, vertexArrays);
687 gluDrawUtil.draw(gl, programId, vertexArrays, gluDrawUtil.triangles(quadGrid.getIndices()));
689 // Read back results.
690 result.readViewport(gl, [xOffset, yOffset, width, height]);
695 * @param {tcuSurface.Surface} result
696 * @param {glsShaderRenderCase.QuadGrid} quadGrid
698 glsShaderRenderCase.ShaderRenderCase.prototype.computeVertexReference = function(result, quadGrid) {
699 // Buffer info.
700 /** @type {number} */ var width = result.getWidth();
701 /** @type {number} */ var height = result.getHeight();
702 /** @type {number} */ var gridSize = quadGrid.getGridSize();
703 /** @type {number} */ var stride = gridSize + 1;
704 /** @type {boolean} */ var hasAlpha = gl.getContextAttributes().alpha;
705 /** @type {glsShaderRenderCase.ShaderEvalContext} */
706 var evalCtx = new glsShaderRenderCase.ShaderEvalContext(quadGrid);
707 /** @type {Array<number>} */ var color = [];
708 // Evaluate color for each vertex.
709 /** @type {Array<Array<number>>} */ var colors = [];
710 for (var y = 0; y < gridSize + 1; y++)
711 for (var x = 0; x < gridSize + 1; x++) {
712 /** @type {number} */ var sx = x / gridSize;
713 /** @type {number} */ var sy = y / gridSize;
714 /** @type {number} */ var vtxNdx = ((y * (gridSize+ 1 )) + x);
716 evalCtx.reset(sx, sy);
717 this.m_evaluator.evaluate(evalCtx);
718 assertMsgOptions(!evalCtx.isDiscarded, 'Discard is not available in vertex shader.', false, true);
719 color = evalCtx.color;
721 if (!hasAlpha)
722 color[3] = 1.0;
724 colors[vtxNdx] = color;
726 // Render quads.
727 for (var y = 0; y < gridSize; y++)
728 for (var x = 0; x < gridSize; x++) {
729 /** @type {number} */ var x0 = x / gridSize;
730 /** @type {number} */ var x1 = (x + 1) / gridSize;
731 /** @type {number} */ var y0 = y / gridSize;
732 /** @type {number} */ var y1 = (y + 1) / gridSize;
734 /** @type {number} */ var sx0 = x0 * width;
735 /** @type {number} */ var sx1 = x1 * width;
736 /** @type {number} */ var sy0 = y0 * height;
737 /** @type {number} */ var sy1 = y1 * height;
738 /** @type {number} */ var oosx = 1.0 / (sx1 - sx0);
739 /** @type {number} */ var oosy = 1.0 / (sy1 - sy0);
741 /** @type {number} */ var ix0 = Math.ceil(sx0 - 0.5);
742 /** @type {number} */ var ix1 = Math.ceil(sx1 - 0.5);
743 /** @type {number} */ var iy0 = Math.ceil(sy0 - 0.5);
744 /** @type {number} */ var iy1 = Math.ceil(sy1 - 0.5);
746 /** @type {number} */ var v00 = (y * stride) + x;
747 /** @type {number} */ var v01 = (y * stride) + x + 1;
748 /** @type {number} */ var v10 = ((y + 1) * stride) + x;
749 /** @type {number} */ var v11 = ((y + 1) * stride) + x + 1;
750 /** @type {Array<number>} */ var c00 = colors[v00];
751 /** @type {Array<number>} */ var c01 = colors[v01];
752 /** @type {Array<number>} */ var c10 = colors[v10];
753 /** @type {Array<number>} */ var c11 = colors[v11];
755 for (var iy = iy0; iy < iy1; iy++)
756 for (var ix = ix0; ix < ix1; ix++) {
757 assertMsgOptions(deMath.deInBounds32(ix, 0, width), 'Out of bounds.', false, true);
758 assertMsgOptions(deMath.deInBounds32(iy, 0, height), 'Out of bounds.', false, true);
760 /** @type {number} */ var sfx = ix + 0.5;
761 /** @type {number} */ var sfy = iy + 0.5;
762 /** @type {number} */ var fx1 = deMath.clamp((sfx - sx0) * oosx, 0.0, 1.0);
763 /** @type {number} */ var fy1 = deMath.clamp((sfy - sy0) * oosy, 0.0, 1.0);
765 // Triangle quad interpolation.
766 /** @type {boolean} */ var tri = fx1 + fy1 <= 1.0;
767 /** @type {number} */ var tx = tri ? fx1 : (1.0 - fx1);
768 /** @type {number} */ var ty = tri ? fy1 : (1.0 - fy1);
769 /** @type {Array<number>} */ var t0 = tri ? c00 : c11;
770 /** @type {Array<number>} */ var t1 = tri ? c01 : c10;
771 /** @type {Array<number>} */ var t2 = tri ? c10 : c01;
772 color = deMath.add(t0, deMath.add(deMath.scale(deMath.subtract(t1, t0), tx), deMath.scale(deMath.subtract(t2, t0), ty)));
774 result.setPixel(ix, iy, glsShaderRenderCase.toRGBA(color).toIVec());
780 * @param {tcuSurface.Surface} result
781 * @param {glsShaderRenderCase.QuadGrid} quadGrid
783 glsShaderRenderCase.ShaderRenderCase.prototype.computeFragmentReference = function(result, quadGrid) {
784 // Buffer info.
785 /** @type {number} */ var width = result.getWidth();
786 /** @type {number} */ var height = result.getHeight();
787 /** @type {boolean} */ var hasAlpha = gl.getContextAttributes().alpha;
788 /** @type {glsShaderRenderCase.ShaderEvalContext} */ var evalCtx = new glsShaderRenderCase.ShaderEvalContext(quadGrid);
790 // Render.
791 for (var y = 0; y < height; y++)
792 for (var x = 0; x < width; x++) {
793 /** @type {number} */ var sx = (x + 0.5) / width;
794 /** @type {number} */ var sy = (y + 0.5) / height;
796 evalCtx.reset(sx, sy);
797 this.m_evaluator.evaluate(evalCtx);
798 // Select either clear color or computed color based on discarded bit.
799 /** @type {Array<number>} */ var color = evalCtx.isDiscarded ? this.m_clearColor : evalCtx.color;
801 if (!hasAlpha)
802 color[3] = 1.0;
804 result.setPixel(x, y, glsShaderRenderCase.toRGBA(color).toIVec());
809 * @param {tcuSurface.Surface} resImage
810 * @param {tcuSurface.Surface} refImage
811 * @param {number} errorThreshold
812 * @return {boolean}
814 glsShaderRenderCase.ShaderRenderCase.prototype.compareImages = function(resImage, refImage, errorThreshold) {
815 return tcuImageCompare.fuzzyCompare("ComparisonResult", "Image comparison result", refImage.getAccess(), resImage.getAccess(), errorThreshold);
819 * @param {number} number
820 * @return {string} */
821 glsShaderRenderCase.getIntUniformName = function(number) {
822 switch (number) {
823 case 0: return "ui_zero";
824 case 1: return "ui_one";
825 case 2: return "ui_two";
826 case 3: return "ui_three";
827 case 4: return "ui_four";
828 case 5: return "ui_five";
829 case 6: return "ui_six";
830 case 7: return "ui_seven";
831 case 8: return "ui_eight";
832 case 101: return "ui_oneHundredOne";
833 default:
834 throw new Error("Uniform not supported.");
839 * @param {number} number
840 * @return {string} */
841 glsShaderRenderCase.getFloatUniformName = function(number) {
842 switch (number) {
843 case 0: return "uf_zero";
844 case 1: return "uf_one";
845 case 2: return "uf_two";
846 case 3: return "uf_three";
847 case 4: return "uf_four";
848 case 5: return "uf_five";
849 case 6: return "uf_six";
850 case 7: return "uf_seven";
851 case 8: return "uf_eight";
852 default:
853 throw new Error("Uniform not supported.");
858 * @param {number} number
859 * @return {string} */
860 glsShaderRenderCase.getFloatFractionUniformName = function(number) {
861 switch (number) {
862 case 1: return "uf_one";
863 case 2: return "uf_half";
864 case 3: return "uf_third";
865 case 4: return "uf_fourth";
866 case 5: return "uf_fifth";
867 case 6: return "uf_sixth";
868 case 7: return "uf_seventh";
869 case 8: return "uf_eighth";
870 default:
871 throw new Error("Uniform not supported.");
876 * @param {?WebGLProgram} programID
878 glsShaderRenderCase.setupDefaultUniforms = function(programID) {
879 /** @type {?WebGLUniformLocation} */ var uniLoc;
880 // Bool.
882 * @constructor
883 * @struct
885 var BoolUniform = function(name, value) {
886 /** @type {string} */ this.name = name;
887 /** @type {boolean} */ this.value = value;
890 /** @type {Array<BoolUniform>} */ var s_boolUniforms = [
891 new BoolUniform("ub_true", true),
892 new BoolUniform("ub_false", false)
895 for (var i = 0; i < s_boolUniforms.length; i++) {
896 uniLoc = gl.getUniformLocation(programID, s_boolUniforms[i].name);
897 if (uniLoc != null)
898 gl.uniform1i(uniLoc, s_boolUniforms[i].value ? 1 : 0);
901 // BVec4.
903 * @constructor
904 * @struct
906 var BVec4Uniform = function(name, value) {
907 /** @type {string} */ this.name = name;
908 /** @type {Array<boolean>} */ this.value = value;
911 /** @type {Array<BVec4Uniform>} */ var s_bvec4Uniforms = [
912 new BVec4Uniform("ub4_true", [true, true, true, true]),
913 new BVec4Uniform("ub4_false", [false, false, false, false])
916 for (var i = 0; i < s_bvec4Uniforms.length; i++) {
917 /** @type {BVec4Uniform} */ var uni = s_bvec4Uniforms[i];
918 /** @type {Array<number>} */ var arr = [];
919 arr[0] = uni.value[0] ? 1 : 0;
920 arr[1] = uni.value[1] ? 1 : 0;
921 arr[2] = uni.value[2] ? 1 : 0;
922 arr[3] = uni.value[3] ? 1 : 0;
923 uniLoc = gl.getUniformLocation(programID, uni.name);
924 if (uniLoc != null)
925 gl.uniform4iv(uniLoc, new Int32Array(arr));
928 // Int.
930 * @constructor
931 * @struct
933 var IntUniform = function(name, value) {
934 /** @type {string} */ this.name = name;
935 /** @type {number} */ this.value = value;
938 /** @type {Array<IntUniform>} */ var s_intUniforms = [
939 new IntUniform("ui_minusOne", -1),
940 new IntUniform("ui_zero", 0),
941 new IntUniform("ui_one", 1),
942 new IntUniform("ui_two", 2),
943 new IntUniform("ui_three", 3),
944 new IntUniform("ui_four", 4),
945 new IntUniform("ui_five", 5),
946 new IntUniform("ui_six", 6),
947 new IntUniform("ui_seven", 7),
948 new IntUniform("ui_eight", 8),
949 new IntUniform("ui_oneHundredOne", 101)
952 for (var i = 0; i < s_intUniforms.length; i++) {
953 uniLoc = gl.getUniformLocation(programID, s_intUniforms[i].name);
954 if (uniLoc != null)
955 gl.uniform1i(uniLoc, s_intUniforms[i].value);
958 // IVec2.
960 * @constructor
961 * @struct
963 var IVec2Uniform = function(name, value) {
964 /** @type {string} */ this.name = name;
965 /** @type {Array<number>} */ this.value = value;
968 /** @type {Array<IVec2Uniform>} */ var s_ivec2Uniforms = [
969 new IVec2Uniform("ui2_minusOne", [-1, -1]),
970 new IVec2Uniform("ui2_zero", [0, 0]),
971 new IVec2Uniform("ui2_one", [1, 1]),
972 new IVec2Uniform("ui2_two", [2, 2]),
973 new IVec2Uniform("ui2_four", [4, 4]),
974 new IVec2Uniform("ui2_five", [5, 5])
977 for (var i = 0; i < s_ivec2Uniforms.length; i++) {
978 uniLoc = gl.getUniformLocation(programID, s_ivec2Uniforms[i].name);
979 if (uniLoc != null)
980 gl.uniform2iv(uniLoc, new Int32Array(s_ivec2Uniforms[i].value));
983 // IVec3.
985 * @constructor
986 * @struct
988 var IVec3Uniform = function(name, value) {
989 /** @type {string} */ this.name = name;
990 /** @type {Array<number>} */ this.value = value;
993 /** @type {Array<IVec3Uniform>} */ var s_ivec3Uniforms = [
994 new IVec3Uniform("ui3_minusOne", [-1, -1, -1]),
995 new IVec3Uniform("ui3_zero", [0, 0, 0]),
996 new IVec3Uniform("ui3_one", [1, 1, 1]),
997 new IVec3Uniform("ui3_two", [2, 2, 2]),
998 new IVec3Uniform("ui3_four", [4, 4, 4]),
999 new IVec3Uniform("ui3_five", [5, 5, 5])
1002 for (var i = 0; i < s_ivec3Uniforms.length; i++) {
1003 uniLoc = gl.getUniformLocation(programID, s_ivec3Uniforms[i].name);
1004 if (uniLoc != null)
1005 gl.uniform3iv(uniLoc, new Int32Array(s_ivec3Uniforms[i].value));
1008 // IVec4.
1010 * @constructor
1011 * @struct
1013 var IVec4Uniform = function(name, value) {
1014 /** @type {string} */ this.name = name;
1015 /** @type {Array<number>} */ this.value = value;
1017 /** @type {Array<IVec4Uniform>} */ var s_ivec4Uniforms = [
1018 new IVec4Uniform("ui4_minusOne", [-1, -1, -1, -1]),
1019 new IVec4Uniform("ui4_zero", [0, 0, 0, 0]),
1020 new IVec4Uniform("ui4_one", [1, 1, 1, 1]),
1021 new IVec4Uniform("ui4_two", [2, 2, 2, 2]),
1022 new IVec4Uniform("ui4_four", [4, 4, 4, 4]),
1023 new IVec4Uniform("ui4_five", [5, 5, 5, 5])
1026 for (var i = 0; i < s_ivec4Uniforms.length; i++) {
1027 uniLoc = gl.getUniformLocation(programID, s_ivec4Uniforms[i].name);
1028 if (uniLoc != null)
1029 gl.uniform4iv(uniLoc, new Int32Array(s_ivec4Uniforms[i].value));
1032 // Float.
1034 * @constructor
1035 * @struct
1037 var FloatUniform = function(name, value) {
1038 /** @type {string} */ this.name = name;
1039 /** @type {number} */ this.value = value;
1041 /** @type {Array<FloatUniform>} */ var s_floatUniforms = [
1042 new FloatUniform("uf_zero", 0.0),
1043 new FloatUniform("uf_one", 1.0),
1044 new FloatUniform("uf_two", 2.0),
1045 new FloatUniform("uf_three", 3.0),
1046 new FloatUniform("uf_four", 4.0),
1047 new FloatUniform("uf_five", 5.0),
1048 new FloatUniform("uf_six", 6.0),
1049 new FloatUniform("uf_seven", 7.0),
1050 new FloatUniform("uf_eight", 8.0),
1051 new FloatUniform("uf_half", 1.0 / 2.0),
1052 new FloatUniform("uf_third", 1.0 / 3.0),
1053 new FloatUniform("uf_fourth", 1.0 / 4.0),
1054 new FloatUniform("uf_fifth", 1.0 / 5.0),
1055 new FloatUniform("uf_sixth", 1.0 / 6.0),
1056 new FloatUniform("uf_seventh", 1.0 / 7.0),
1057 new FloatUniform("uf_eighth", 1.0 / 8.0)
1060 for (var i = 0; i < s_floatUniforms.length; i++) {
1061 uniLoc = gl.getUniformLocation(programID, s_floatUniforms[i].name);
1062 if (uniLoc != null)
1063 gl.uniform1f(uniLoc, s_floatUniforms[i].value);
1066 // Vec2.
1068 * @constructor
1069 * @struct
1071 var Vec2Uniform = function(name, value) {
1072 /** @type {string} */ this.name = name;
1073 /** @type {Array<number>} */ this.value = value;
1075 /** @type {Array<Vec2Uniform>} */ var s_vec2Uniforms = [
1076 new Vec2Uniform("uv2_minusOne", [-1.0, -1.0]),
1077 new Vec2Uniform("uv2_zero", [0.0, 0.0]),
1078 new Vec2Uniform("uv2_half", [0.5, 0.5]),
1079 new Vec2Uniform("uv2_one", [1.0, 1.0]),
1080 new Vec2Uniform("uv2_two", [2.0, 2.0])
1083 for (var i = 0; i < s_vec2Uniforms.length; i++) {
1084 uniLoc = gl.getUniformLocation(programID, s_vec2Uniforms[i].name);
1085 if (uniLoc != null)
1086 gl.uniform2fv(uniLoc, new Float32Array(s_vec2Uniforms[i].value));
1089 // Vec3.
1091 * @constructor
1092 * @struct
1094 var Vec3Uniform = function(name, value) {
1095 /** @type {string} */ this.name = name;
1096 /** @type {Array<number>} */ this.value = value;
1098 /** @type {Array<Vec3Uniform>} */ var s_vec3Uniforms = [
1099 new Vec3Uniform("uv3_minusOne", [-1.0, -1.0, -1.0]),
1100 new Vec3Uniform("uv3_zero", [0.0, 0.0, 0.0]),
1101 new Vec3Uniform("uv3_half", [0.5, 0.5, 0.5]),
1102 new Vec3Uniform("uv3_one", [1.0, 1.0, 1.0]),
1103 new Vec3Uniform("uv3_two", [2.0, 2.0, 2.0])
1106 for (var i = 0; i < s_vec3Uniforms.length; i++) {
1107 uniLoc = gl.getUniformLocation(programID, s_vec3Uniforms[i].name);
1108 if (uniLoc != null)
1109 gl.uniform3fv(uniLoc, new Float32Array(s_vec3Uniforms[i].value));
1112 // Vec4.
1114 * @constructor
1115 * @struct
1117 var Vec4Uniform = function(name, value) {
1118 /** @type {string} */ this.name = name;
1119 /** @type {Array<number>} */ this.value = value;
1121 /** @type {Array<Vec4Uniform>} */ var s_vec4Uniforms = [
1122 new Vec4Uniform("uv4_minusOne", [-1.0, -1.0, -1.0, -1.0]),
1123 new Vec4Uniform("uv4_zero", [0.0, 0.0, 0.0, 0.0]),
1124 new Vec4Uniform("uv4_half", [0.5, 0.5, 0.5, 0.5]),
1125 new Vec4Uniform("uv4_one", [1.0, 1.0, 1.0, 1.0]),
1126 new Vec4Uniform("uv4_two", [2.0, 2.0, 2.0, 2.0]),
1127 new Vec4Uniform("uv4_black", [0.0, 0.0, 0.0, 1.0]),
1128 new Vec4Uniform("uv4_gray", [0.5, 0.5, 0.5, 1.0]),
1129 new Vec4Uniform("uv4_white", [1.0, 1.0, 1.0, 1.0])
1132 for (var i = 0; i < s_vec4Uniforms.length; i++) {
1133 uniLoc = gl.getUniformLocation(programID, s_vec4Uniforms[i].name);
1134 if (uniLoc != null)
1135 gl.uniform4fv(uniLoc, new Float32Array(s_vec4Uniforms[i].value));
1140 * @param {glsShaderRenderCase.QuadGrid} quadGrid
1141 * @param {?WebGLProgram} program
1142 * @param {Array<gluDrawUtil.VertexArrayBinding>} vertexArrays
1144 glsShaderRenderCase.getDefaultVertexArrays = function(quadGrid, program, vertexArrays) {
1145 /** @type {number} */ var numElements = quadGrid.getNumVertices();
1146 var posArray = [].concat.apply([], quadGrid.getPositions());
1147 var coordsArray = [].concat.apply([], quadGrid.getCoordsArray());
1148 var unitCoordsArray = [].concat.apply([], quadGrid.getUnitCoordsArray());
1150 vertexArrays.push(gluDrawUtil.newFloatVertexArrayBinding("a_position", 4, numElements, 0, posArray));
1151 vertexArrays.push(gluDrawUtil.newFloatVertexArrayBinding("a_coords", 4, numElements, 0, coordsArray));
1152 vertexArrays.push(gluDrawUtil.newFloatVertexArrayBinding("a_unitCoords", 4, numElements, 0, unitCoordsArray));
1153 vertexArrays.push(gluDrawUtil.newFloatVertexArrayBinding("a_one", 1, numElements, 0, quadGrid.getAttribOne()));
1155 // a_inN.
1156 for (var userNdx = 0; userNdx < quadGrid.getNumUserAttribs(); userNdx++) {
1157 /** @type {string} */ var name = "a_in" + userNdx;
1158 var userAttribArray = [].concat.apply([], quadGrid.getUserAttribByIndex(userNdx));
1159 vertexArrays.push(gluDrawUtil.newFloatVertexArrayBinding(name, 4, numElements, 0, userAttribArray));
1162 // Matrix attributes - these are set by location
1164 * @constructor
1165 * @struct
1167 var Matrix = function(name, cols, rows) {
1168 this.name = name;
1169 this.numCols = cols;
1170 this.numRows = rows;
1173 /** @type {Array<Matrix>} */ var matrices = [
1174 new Matrix('a_mat2', 2, 2),
1175 new Matrix('a_mat2x3', 2, 3),
1176 new Matrix('a_mat2x4', 2, 4),
1177 new Matrix('a_mat3x2', 3, 2),
1178 new Matrix('a_mat3', 3, 3),
1179 new Matrix('a_mat3x4', 3, 4),
1180 new Matrix('a_mat4x2', 4, 2),
1181 new Matrix('a_mat4x3', 4, 3),
1182 new Matrix('a_mat4', 4, 4)
1185 for (var matNdx = 0; matNdx < matrices.length; matNdx++) {
1186 /** @type {number} */ var loc = gl.getAttribLocation(program, matrices[matNdx].name);
1188 if (loc < 0)
1189 continue; // Not used in shader.
1191 /** @type {number} */ var numRows = matrices[matNdx].numRows;
1192 /** @type {number} */ var numCols = matrices[matNdx].numCols;
1194 for (var colNdx = 0; colNdx < numCols; colNdx++) {
1195 var data = [].concat.apply([], quadGrid.getUserAttribByIndex(colNdx));
1196 vertexArrays.push(gluDrawUtil.newFloatColumnVertexArrayBinding(matrices[matNdx].name, colNdx, numRows, numElements, 4 * 4, data));