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.
22 goog.provide('functional.gles3.es3fTransformFeedbackTests');
23 goog.require('framework.common.tcuImageCompare');
24 goog.require('framework.common.tcuSurface');
25 goog.require('framework.common.tcuTestCase');
26 goog.require('framework.delibs.debase.deMath');
27 goog.require('framework.delibs.debase.deRandom');
28 goog.require('framework.delibs.debase.deString');
29 goog.require('framework.opengl.gluDrawUtil');
30 goog.require('framework.opengl.gluShaderProgram');
31 goog.require('framework.opengl.gluShaderUtil');
32 goog.require('framework.opengl.gluVarType');
33 goog.require('framework.opengl.gluVarTypeUtil');
35 goog.scope(function() {
37 var es3fTransformFeedbackTests = functional.gles3.es3fTransformFeedbackTests;
38 var gluShaderUtil = framework.opengl.gluShaderUtil;
39 var gluDrawUtil = framework.opengl.gluDrawUtil;
40 var gluVarType = framework.opengl.gluVarType;
41 var gluVarTypeUtil = framework.opengl.gluVarTypeUtil;
42 var gluShaderProgram = framework.opengl.gluShaderProgram;
43 var deRandom = framework.delibs.debase.deRandom;
44 var deMath = framework.delibs.debase.deMath;
45 var deString = framework.delibs.debase.deString;
46 var tcuTestCase = framework.common.tcuTestCase;
47 var tcuSurface = framework.common.tcuSurface;
48 var tcuImageCompare = framework.common.tcuImageCompare;
50 /** @type {WebGL2RenderingContext} */ var gl;
52 var setParentClass = function(child, parent) {
53 child.prototype = Object.create(parent.prototype);
54 child.prototype.constructor = child;
60 es3fTransformFeedbackTests.State = {
66 /* Maximum time to wait for query result (in seconds) */
67 /** @const */ es3fTransformFeedbackTests.MAX_VERIFY_WAIT = 5;
69 /** @const @type {number} */ es3fTransformFeedbackTests.VIEWPORT_WIDTH = 128;
70 /** @const @type {number} */ es3fTransformFeedbackTests.VIEWPORT_HEIGHT = 128;
71 /** @const @type {number} */ es3fTransformFeedbackTests.BUFFER_GUARD_MULTIPLIER = 2;
74 * Enums for es3fTransformFeedbackTests.interpolation
77 es3fTransformFeedbackTests.interpolation = {
85 * Returns es3fTransformFeedbackTests.interpolation name: smooth, flat or centroid
86 * @param {number} interpol es3fTransformFeedbackTests.interpolation enum value
89 es3fTransformFeedbackTests.getInterpolationName = function(interpol) {
92 case es3fTransformFeedbackTests.interpolation.SMOOTH: return 'smooth';
93 case es3fTransformFeedbackTests.interpolation.FLAT: return 'flat';
94 case es3fTransformFeedbackTests.interpolation.CENTROID: return 'centroid';
96 throw new Error('Unrecognized es3fTransformFeedbackTests.interpolation name ' + interpol);
103 * @param {string} name
104 * @param {gluVarType.VarType} type
105 * @param {number} interpolation
108 es3fTransformFeedbackTests.Varying = function(name, type, interpolation) {
111 this.interpolation = interpolation;
114 /** es3fTransformFeedbackTests.findAttributeNameEquals
115 * Replaces original implementation of "VaryingNameEquals" and "AttributeNameEquals" in the C++ version
116 * Returns an es3fTransformFeedbackTests.Attribute or es3fTransformFeedbackTests.Varying object which matches its name with the passed string value in the function
117 * @param {(Array<es3fTransformFeedbackTests.Attribute> | Array<es3fTransformFeedbackTests.Varying>)} array
118 * @param {string} name
119 * @return { (es3fTransformFeedbackTests.Attribute | es3fTransformFeedbackTests.Varying | null)}
121 es3fTransformFeedbackTests.findAttributeNameEquals = function(array, name) {
122 for (var pos = 0; pos < array.length; pos++) {
123 if (array[pos].name === name) {
132 * @param {string} name
133 * @param {gluVarType.VarType} type
134 * @param {number} offset
137 es3fTransformFeedbackTests.Attribute = function(name, type, offset) {
140 this.offset = offset;
144 * Constructs an es3fTransformFeedbackTests.Output object
147 es3fTransformFeedbackTests.Output = function() {
148 /** @type {number} */ this.bufferNdx = 0;
149 /** @type {number} */ this.offset = 0;
150 /** @type {string} */ this.name;
151 /** @type {gluVarType.VarType} */ this.type = null;
152 /** @type {Array<es3fTransformFeedbackTests.Attribute>} */ this.inputs = [];
156 * Constructs an object type es3fTransformFeedbackTests.DrawCall.
157 * Contains the number of elements as well as whether the Transform Feedback is enabled or not.
159 * @param {number} numElements
160 * @param {boolean} tfEnabled is Transform Feedback enabled or not
163 es3fTransformFeedbackTests.DrawCall = function(numElements, tfEnabled) {
164 this.numElements = numElements;
165 this.transformFeedbackEnabled = tfEnabled;
171 es3fTransformFeedbackTests.ProgramSpec = function() {
173 /** @type {Array<gluVarType.StructType>} */ var m_structs = [];
174 /** @type {Array<es3fTransformFeedbackTests.Varying>} */ var m_varyings = [];
175 /** @type {Array<string>} */ var m_transformFeedbackVaryings = [];
177 this.createStruct = function(name) {
178 var struct = gluVarType.newStructType(name);
179 m_structs.push(struct);
183 this.addVarying = function(name, type, interp) {
184 m_varyings.push(new es3fTransformFeedbackTests.Varying(name, type, interp));
187 this.addTransformFeedbackVarying = function(name) {
188 m_transformFeedbackVaryings.push(name);
191 this.getStructs = function() {
194 this.getVaryings = function() {
197 this.getTransformFeedbackVaryings = function() {
198 return m_transformFeedbackVaryings;
201 this.isPointSizeUsed = function() {
202 for (var i = 0; i < m_transformFeedbackVaryings.length; ++i) {
203 if (m_transformFeedbackVaryings[i] == 'gl_PointSize') return true;
210 /** Returns if the program is supported or not
211 * @param {es3fTransformFeedbackTests.ProgramSpec} spec
212 * @param {number} tfMode
215 es3fTransformFeedbackTests.isProgramSupported = function(spec, tfMode) {
216 var maxVertexAttribs = Number(gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
217 var maxTfInterleavedComponents = Number(gl.getParameter(gl.MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS));
218 var maxTfSeparateAttribs = Number(gl.getParameter(gl.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS));
219 var maxTfSeparateComponents = Number(gl.getParameter(gl.MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS));
221 // Check vertex attribs.
222 /** @type {number} */ var totalVertexAttribs = (
223 1 /* a_position */ + (spec.isPointSizeUsed() ? 1 : 0)
226 for (var i = 0; i < spec.getVaryings().length; ++i) {
227 for (var v_iter = new gluVarTypeUtil.VectorTypeIterator(spec.getVaryings()[i].type); !v_iter.end(); v_iter.next()) {
228 totalVertexAttribs += 1;
232 if (totalVertexAttribs > maxVertexAttribs)
233 return false; // Vertex attribute es3fTransformFeedbackTests.count exceeded.
236 /** @type {number} */ var totalTfComponents = 0;
237 /** @type {number} */ var totalTfAttribs = 0;
238 /** @type {Object.<number, number>} */ var presetNumComponents = {
242 for (var i = 0; i < spec.getTransformFeedbackVaryings().length; ++i) {
243 var name = spec.getTransformFeedbackVaryings()[i];
244 var numComponents = 0;
246 if (typeof(presetNumComponents[name]) != 'undefined') {
247 numComponents = presetNumComponents[name];
249 var varName = gluVarTypeUtil.parseVariableName(name);
250 // find the varying called varName
251 /** @type {es3fTransformFeedbackTests.Varying} */ var varying = (function(varyings) {
252 for (var i = 0; i < varyings.length; ++i) {
253 if (varyings[i].name == varName) {
258 }(spec.getVaryings()));
260 // glu::TypeComponentVector
261 var varPath = gluVarTypeUtil.parseTypePath(name, varying.type);
262 numComponents = gluVarTypeUtil.getVarType(varying.type, varPath).getScalarSize();
265 if (tfMode == gl.SEPARATE_ATTRIBS && numComponents > maxTfSeparateComponents)
266 return false; // Per-attribute component es3fTransformFeedbackTests.count exceeded.
268 totalTfComponents += numComponents;
272 if (tfMode == gl.SEPARATE_ATTRIBS && totalTfAttribs > maxTfSeparateAttribs)
275 if (tfMode == gl.INTERLEAVED_ATTRIBS && totalTfComponents > maxTfInterleavedComponents)
283 * @param {string} varyingName
284 * @param {Array<gluVarTypeUtil.VarTypeComponent>} path
287 es3fTransformFeedbackTests.getAttributeName = function(varyingName, path) {
288 /** @type {string} */ var str = 'a_' + varyingName.substr(/^v_/.test(varyingName) ? 2 : 0);
290 for (var i = 0; i < path.length; ++i) {
291 /** @type {string} */ var prefix;
293 switch (path[i].type) {
294 case gluVarTypeUtil.VarTypeComponent.s_Type.STRUCT_MEMBER: prefix = '_m'; break;
295 case gluVarTypeUtil.VarTypeComponent.s_Type.ARRAY_ELEMENT: prefix = '_e'; break;
296 case gluVarTypeUtil.VarTypeComponent.s_Type.MATRIX_COLUMN: prefix = '_c'; break;
297 case gluVarTypeUtil.VarTypeComponent.s_Type.VECTOR_COMPONENT: prefix = '_s'; break;
299 throw new Error('invalid type in the component path.');
301 str += prefix + path[i].index;
307 * original definition:
308 * static void es3fTransformFeedbackTests.genShaderSources (const es3fTransformFeedbackTests.ProgramSpec& spec, std::string& vertSource, std::string& fragSource, bool pointSizeRequired)
309 * in place of the std::string references, this function returns those params in an object
311 * @param {es3fTransformFeedbackTests.ProgramSpec} spec
312 * @param {boolean} pointSizeRequired
313 * @return {Object.<string, string>}
315 es3fTransformFeedbackTests.genShaderSources = function(spec, pointSizeRequired) {
317 var vtx = { str: null };
318 var frag = { str: null };
319 var addPointSize = spec.isPointSizeUsed();
321 vtx.str = '#version 300 es\n' +
322 'in highp vec4 a_position;\n';
323 frag.str = '#version 300 es\n' +
324 'layout(location = 0) out mediump vec4 o_color;\n' +
325 'uniform highp vec4 u_scale;\n' +
326 'uniform highp vec4 u_bias;\n';
327 //vtx.str = 'attribute highp vec4 a_position;\n';
328 //frag.str = 'uniform highp vec4 u_scale;\n' +
329 // 'uniform highp vec4 u_bias;\n';
332 vtx.str += 'in highp float a_pointSize;\n';
333 //vtx.str += 'attribute highp float a_pointSize;\n';
336 // Declare attributes.
337 for (var i = 0; i < spec.getVaryings().length; ++i) {
339 /** @type {string} */ var name = spec.getVaryings()[i].name;
340 /** @type {gluVarType.VarType} */ var type = spec.getVaryings()[i].type;
342 for (var vecIter = new gluVarTypeUtil.VectorTypeIterator(type); !vecIter.end(); vecIter.next()) {
344 /** @type {gluVarType.VarType} */
345 var attribType = gluVarTypeUtil.getVarType(type, vecIter.getPath());
347 /** @type {string} */
348 var attribName = es3fTransformFeedbackTests.getAttributeName(name, vecIter.getPath());
349 vtx.str += 'in ' + gluVarType.declareVariable(attribType, attribName) + ';\n';
355 for (var ndx = 0; ndx < 2; ++ndx) {
356 var inout = ndx ? 'in' : 'out';
357 var shader = ndx ? frag : vtx;
359 for (var i = 0; i < spec.getStructs().length; ++i) {
360 var struct = spec.getStructs()[i];
361 if (struct.hasTypeName()) {
362 shader.str += gluVarType.declareStructType(struct) + ';\n';
366 /** @type {Array<es3fTransformFeedbackTests.Varying>} */ var varyings = spec.getVaryings();
367 for (var i = 0; i < varyings.length; ++i) {
368 var varying = varyings[i];
369 shader.str += es3fTransformFeedbackTests.getInterpolationName(varying.interpolation) +
371 gluVarType.declareVariable(varying.type, varying.name) +
376 vtx.str += '\nvoid main (void)\n {\n' +
377 '\tgl_Position = a_position;\n';
378 frag.str += '\nvoid main (void)\n {\n' +
379 '\thighp vec4 res = vec4(0.0);\n';
382 vtx.str += '\tgl_PointSize = a_pointSize;\n';
383 } else if (pointSizeRequired) {
384 vtx.str += '\tgl_PointSize = 1.0;\n';
387 for (var i = 0; i < spec.getVaryings().length; ++i) {
388 var name = spec.getVaryings()[i].name;
389 var type = spec.getVaryings()[i].type;
391 for (var vecIter = new gluVarTypeUtil.VectorTypeIterator(type); !vecIter.end(); vecIter.next()) {
392 /** @type {gluVarType.VarType} */var subType = gluVarTypeUtil.getVarType(type, vecIter.getPath());
393 var attribName = es3fTransformFeedbackTests.getAttributeName(name, vecIter.getPath());
396 subType.isBasicType() &&
397 gluShaderUtil.isDataTypeScalarOrVector(subType.getBasicType())
398 )) throw new Error('Not a scalar or vector.');
400 // Vertex: assign from attribute.
401 vtx.str += '\t' + name + vecIter.toString() + ' = ' + attribName + ';\n';
403 // Fragment: add to res variable.
404 var scalarSize = gluShaderUtil.getDataTypeScalarSize(subType.getBasicType());
406 frag.str += '\tres += ';
407 if (scalarSize == 1) frag.str += 'vec4(' + name + vecIter.toString() + ')';
408 else if (scalarSize == 2) frag.str += 'vec2(' + name + vecIter.toString() + ').xxyy';
409 else if (scalarSize == 3) frag.str += 'vec3(' + name + vecIter.toString() + ').xyzx';
410 else if (scalarSize == 4) frag.str += 'vec4(' + name + vecIter.toString() + ')';
416 frag.str += '\to_color = res * u_scale + u_bias;\n}\n';
417 //frag.str += '\tgl_FragColor = res * u_scale + u_bias;\n}\n';
427 * Returns a Shader program
428 * @param {es3fTransformFeedbackTests.ProgramSpec} spec
429 * @param {number} bufferMode
430 * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
431 * @return {gluShaderProgram.ShaderProgram}
433 es3fTransformFeedbackTests.createVertexCaptureProgram = function(spec, bufferMode, primitiveType) {
435 /** @type {Object.<string, string>} */ var source = es3fTransformFeedbackTests.genShaderSources(spec, primitiveType === gluDrawUtil.primitiveType.POINTS /* Is point size required? */);
437 var programSources = new gluShaderProgram.ProgramSources();
438 programSources.add(new gluShaderProgram.VertexSource(source.vertSource))
439 .add(new gluShaderProgram.FragmentSource(source.fragSource))
440 .add(new gluShaderProgram.TransformFeedbackVaryings(spec.getTransformFeedbackVaryings()))
441 .add(new gluShaderProgram.TransformFeedbackMode(bufferMode));
443 return new gluShaderProgram.ShaderProgram(gl, programSources);
448 * @param {Array<es3fTransformFeedbackTests.Attribute>} attributes
449 * @param {Array<es3fTransformFeedbackTests.Varying>} varyings
450 * @param {boolean} usePointSize
451 * @return {number} input stride
453 es3fTransformFeedbackTests.computeInputLayout = function(attributes, varyings, usePointSize) {
458 var dataTypeVec4 = gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.precision.PRECISION_HIGHP);
459 attributes.push(new es3fTransformFeedbackTests.Attribute('a_position', dataTypeVec4, inputStride));
460 inputStride += 4 * 4; /*sizeof(deUint32)*/
463 var dataTypeFloat = gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT, gluShaderUtil.precision.PRECISION_HIGHP);
464 attributes.push(new es3fTransformFeedbackTests.Attribute('a_pointSize', dataTypeFloat, inputStride));
465 inputStride += 1 * 4; /*sizeof(deUint32)*/
468 for (var i = 0; i < varyings.length; i++) {
469 for (var vecIter = new gluVarTypeUtil.VectorTypeIterator(varyings[i].type); !vecIter.end(); vecIter.next()) {
470 var type = vecIter.getType(); // originally getType() in getVarType() within gluVARTypeUtil.hpp.
471 var name = es3fTransformFeedbackTests.getAttributeName(varyings[i].name, vecIter.getPath());
473 attributes.push(new es3fTransformFeedbackTests.Attribute(name, type, inputStride));
474 inputStride += gluShaderUtil.getDataTypeScalarSize(type.getBasicType()) * 4; /*sizeof(deUint32)*/
482 * @param {Array<es3fTransformFeedbackTests.Output>} transformFeedbackOutputs
483 * @param {Array<es3fTransformFeedbackTests.Attribute>} attributes
484 * @param {Array<es3fTransformFeedbackTests.Varying>} varyings
485 * @param {Array<string>} transformFeedbackVaryings
486 * @param {number} bufferMode
488 es3fTransformFeedbackTests.computeTransformFeedbackOutputs = function(transformFeedbackOutputs, attributes, varyings, transformFeedbackVaryings, bufferMode) {
490 /** @type {number} */ var accumulatedSize = 0;
492 // transformFeedbackOutputs.resize(transformFeedbackVaryings.size());
493 for (var varNdx = 0; varNdx < transformFeedbackVaryings.length; varNdx++) {
494 /** @type {string} */ var name = transformFeedbackVaryings[varNdx];
495 /** @type {number} */ var bufNdx = (bufferMode === gl.SEPARATE_ATTRIBS ? varNdx : 0);
496 /** @type {number} */ var offset = (bufferMode === gl.SEPARATE_ATTRIBS ? 0 : accumulatedSize);
497 /** @type {es3fTransformFeedbackTests.Output} */ var output = new es3fTransformFeedbackTests.Output();
500 output.bufferNdx = bufNdx;
501 output.offset = offset;
503 if (name === 'gl_Position') {
504 var posIn = es3fTransformFeedbackTests.findAttributeNameEquals(attributes, 'a_position');
505 output.type = posIn.type;
506 output.inputs.push(posIn);
507 } else if (name === 'gl_PointSize') {
508 var sizeIn = es3fTransformFeedbackTests.findAttributeNameEquals(attributes, 'a_pointSize');
509 output.type = sizeIn.type;
510 output.inputs.push(sizeIn);
512 var varName = gluVarTypeUtil.parseVariableName(name);
513 var varying = es3fTransformFeedbackTests.findAttributeNameEquals(varyings, varName);
515 var varPath = gluVarTypeUtil.parseTypePath(name, varying.type);
516 output.type = gluVarTypeUtil.getVarType(varying.type, varPath);
518 // Add all vectorized attributes as inputs.
519 for (var iter = new gluVarTypeUtil.VectorTypeIterator(output.type); !iter.end(); iter.next()) {
520 var fullpath = varPath.concat(iter.getPath());
521 var attribName = es3fTransformFeedbackTests.getAttributeName(varName, fullpath);
522 var attrib = es3fTransformFeedbackTests.findAttributeNameEquals(attributes, attribName);
523 output.inputs.push(attrib);
526 transformFeedbackOutputs.push(output);
527 accumulatedSize += output.type.getScalarSize() * 4; /*sizeof(deUint32)*/
532 * @param {es3fTransformFeedbackTests.Attribute} attrib
533 * @param {ArrayBuffer} buffer
534 * @param {number} stride
535 * @param {number} numElements
536 * @param {deRandom.Random} rnd
538 es3fTransformFeedbackTests.genAttributeData = function(attrib, buffer, stride, numElements, rnd) {
540 /** @type {number} */ var elementSize = 4; /*sizeof(deUint32)*/
541 /** @type {boolean} */ var isFloat = gluShaderUtil.isDataTypeFloatOrVec(attrib.type.getBasicType());
542 /** @type {boolean} */ var isInt = gluShaderUtil.isDataTypeIntOrIVec(attrib.type.getBasicType());
543 /** @type {boolean} */ var isUint = gluShaderUtil.isDataTypeUintOrUVec(attrib.type.getBasicType());
545 /** @type {gluShaderUtil.precision} */ var precision = attrib.type.getPrecision();
547 /** @type {number} */ var numComps = gluShaderUtil.getDataTypeScalarSize(attrib.type.getBasicType());
549 for (var elemNdx = 0; elemNdx < numElements; elemNdx++) {
550 for (var compNdx = 0; compNdx < numComps; compNdx++) {
551 /** @type {number} */ var offset = attrib.offset + elemNdx * stride + compNdx * elementSize;
553 var pos = new Float32Array(buffer, offset, 1);
555 case gluShaderUtil.precision.PRECISION_LOWP: pos[0] = 0.25 * rnd.getInt(0, 4); break;
556 case gluShaderUtil.precision.PRECISION_MEDIUMP: pos[0] = rnd.getFloat(-1e3, 1e3); break;
557 case gluShaderUtil.precision.PRECISION_HIGHP: pos[0] = rnd.getFloat(-1e5, 1e5); break;
558 default: throw new Error('Unknown precision: ' + precision);
561 var pos = new Int32Array(buffer, offset, 1);
563 case gluShaderUtil.precision.PRECISION_LOWP: pos[0] = rnd.getInt(-128, 127); break;
564 case gluShaderUtil.precision.PRECISION_MEDIUMP: pos[0] = rnd.getInt(-32768, 32767); break;
565 case gluShaderUtil.precision.PRECISION_HIGHP: pos[0] = rnd.getInt(); break;
566 default: throw new Error('Unknown precision: ' + precision);
569 var pos = new Uint32Array(buffer, offset, 1);
571 case gluShaderUtil.precision.PRECISION_LOWP: pos[0] = rnd.getInt(0, 255); break;
572 case gluShaderUtil.precision.PRECISION_MEDIUMP: pos[0] = rnd.getInt(0, 65535); break;
573 case gluShaderUtil.precision.PRECISION_HIGHP: pos[0] = Math.abs(rnd.getInt()); break;
574 default: throw new Error('Unknown precision: ' + precision);
582 * @param {Array<es3fTransformFeedbackTests.Attribute>} attributes
583 * @param {number} numInputs
584 * @param {number} inputStride
585 * @param {deRandom.Random} rnd
586 * @return {ArrayBuffer}
588 es3fTransformFeedbackTests.genInputData = function(attributes, numInputs, inputStride, rnd) {
589 var buffer = new ArrayBuffer(numInputs * inputStride);
591 var position = es3fTransformFeedbackTests.findAttributeNameEquals(attributes, 'a_position');
593 throw new Error('Position attribute not found.');
595 for (var ndx = 0; ndx < numInputs; ndx++) {
596 var pos = new Float32Array(buffer, position.offset + inputStride * ndx, 4);
597 pos[0] = rnd.getFloat(-1.2, 1.2);
598 pos[1] = rnd.getFloat(-1.2, 1.2);
599 pos[2] = rnd.getFloat(-1.2, 1.2);
600 pos[3] = rnd.getFloat(0.1, 2.0);
603 var pointSizePos = es3fTransformFeedbackTests.findAttributeNameEquals(attributes, 'a_pointSize');
605 for (var ndx = 0; ndx < numInputs; ndx++) {
606 var pos = new Float32Array(buffer, pointSizePos.offset + inputStride * ndx, 1);
607 pos[0] = rnd.getFloat(1, 8);
611 // Random data for rest of components.
612 for (var i = 0; i < attributes.length; i++) {
613 if (attributes[i].name != 'a_position' && attributes[i].name != 'a_pointSize')
614 es3fTransformFeedbackTests.genAttributeData(attributes[i], buffer, inputStride, numInputs, rnd);
621 * Returns the number of outputs with the es3fTransformFeedbackTests.count for the Primitives in the Transform Feedback.
622 * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
623 * @param {number} numElements
626 es3fTransformFeedbackTests.getTransformFeedbackOutputCount = function(primitiveType, numElements) {
628 switch (primitiveType) {
629 case gluDrawUtil.primitiveType.TRIANGLES: return numElements - numElements % 3;
630 case gluDrawUtil.primitiveType.TRIANGLE_STRIP: return Math.max(0, numElements - 2) * 3;
631 case gluDrawUtil.primitiveType.TRIANGLE_FAN: return Math.max(0, numElements - 2) * 3;
632 case gluDrawUtil.primitiveType.LINES: return numElements - numElements % 2;
633 case gluDrawUtil.primitiveType.LINE_STRIP: return Math.max(0, numElements - 1) * 2;
634 case gluDrawUtil.primitiveType.LINE_LOOP: return numElements > 1 ? numElements * 2 : 0;
635 case gluDrawUtil.primitiveType.POINTS: return numElements;
637 throw new Error('Unrecognized primitiveType ' + primitiveType);
643 * Returns a number with the es3fTransformFeedbackTests.count for the Primitives in the Transform Feedback.
644 * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
645 * @param {number} numElements
648 es3fTransformFeedbackTests.getTransformFeedbackPrimitiveCount = function(primitiveType, numElements) {
650 switch (primitiveType) {
651 case gluDrawUtil.primitiveType.TRIANGLES: return Math.floor(numElements / 3);
652 case gluDrawUtil.primitiveType.TRIANGLE_STRIP: return Math.max(0, numElements - 2);
653 case gluDrawUtil.primitiveType.TRIANGLE_FAN: return Math.max(0, numElements - 2);
654 case gluDrawUtil.primitiveType.LINES: return Math.floor(numElements / 2);
655 case gluDrawUtil.primitiveType.LINE_STRIP: return Math.max(0, numElements - 1);
656 case gluDrawUtil.primitiveType.LINE_LOOP: return numElements > 1 ? numElements : 0;
657 case gluDrawUtil.primitiveType.POINTS: return numElements;
659 throw new Error('Unrecognized primitiveType ' + primitiveType);
665 * Returns the type of Primitive Mode: Triangles for all Triangle Primitive's type and same for Line and Points.
666 * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
667 * @return {number} primitiveType
669 es3fTransformFeedbackTests.getTransformFeedbackPrimitiveMode = function(primitiveType) {
671 switch (primitiveType) {
672 case gluDrawUtil.primitiveType.TRIANGLES:
673 case gluDrawUtil.primitiveType.TRIANGLE_STRIP:
674 case gluDrawUtil.primitiveType.TRIANGLE_FAN:
677 case gluDrawUtil.primitiveType.LINES:
678 case gluDrawUtil.primitiveType.LINE_STRIP:
679 case gluDrawUtil.primitiveType.LINE_LOOP:
682 case gluDrawUtil.primitiveType.POINTS:
686 throw new Error('Unrecognized primitiveType ' + primitiveType);
692 * Returns the attribute index for a certain primitive type.
693 * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
694 * @param {number} numInputs
695 * @param {number} outNdx
698 es3fTransformFeedbackTests.getAttributeIndex = function(primitiveType, numInputs, outNdx) {
700 switch (primitiveType) {
702 case gluDrawUtil.primitiveType.TRIANGLES: return outNdx;
703 case gluDrawUtil.primitiveType.LINES: return outNdx;
704 case gluDrawUtil.primitiveType.POINTS: return outNdx;
706 case gluDrawUtil.primitiveType.TRIANGLE_STRIP: {
707 /** @type {number} */ var triNdx = outNdx / 3;
708 /** @type {number} */ var vtxNdx = outNdx % 3;
709 return (triNdx % 2 != 0 && vtxNdx < 2) ? (triNdx + 1 - vtxNdx) : (triNdx + vtxNdx);
712 case gluDrawUtil.primitiveType.TRIANGLE_FAN:
713 return (outNdx % 3 != 0) ? (outNdx / 3 + outNdx % 3) : 0;
715 case gluDrawUtil.primitiveType.LINE_STRIP:
716 return outNdx / 2 + outNdx % 2;
718 case gluDrawUtil.primitiveType.LINE_LOOP: {
719 var inNdx = outNdx / 2 + outNdx % 2;
720 return inNdx < numInputs ? inNdx : 0;
724 throw new Error('Unrecognized primitiveType ' + primitiveType);
730 * @param {gluDrawUtil.primitiveType} primitiveType type number in gluDrawUtil.primitiveType
731 * @param {es3fTransformFeedbackTests.Output} output
732 * @param {number} numInputs
733 * @param {Object} buffers
734 * @return {boolean} isOk
736 es3fTransformFeedbackTests.compareTransformFeedbackOutput = function(primitiveType, output, numInputs, buffers) {
737 /** @type {boolean} */ var isOk = true;
738 /** @type {number} */ var outOffset = output.offset;
740 for (var attrNdx = 0; attrNdx < output.inputs.length; attrNdx++) {
741 /** @type {es3fTransformFeedbackTests.Attribute} */ var attribute = output.inputs[attrNdx];
742 /** @type {gluShaderUtil.DataType} */ var type = attribute.type.getBasicType();
743 /** @type {number} */ var numComponents = gluShaderUtil.getDataTypeScalarSize(type);
745 /** @type {gluShaderUtil.precision} */ var precision = attribute.type.getPrecision();
747 /** @type {string} */ var scalarType = gluShaderUtil.getDataTypeScalarType(type);
748 /** @type {number} */ var numOutputs = es3fTransformFeedbackTests.getTransformFeedbackOutputCount(primitiveType, numInputs);
750 for (var outNdx = 0; outNdx < numOutputs; outNdx++) {
751 /** @type {number} */ var inNdx = es3fTransformFeedbackTests.getAttributeIndex(primitiveType, numInputs, outNdx);
753 for (var compNdx = 0; compNdx < numComponents; compNdx++) {
754 /** @type {boolean} */ var isEqual = false;
756 if (scalarType === 'float') {
757 var outBuffer = new Float32Array(buffers.output.buffer, buffers.output.offset + buffers.output.stride * outNdx + outOffset + compNdx * 4, 1);
758 var inBuffer = new Float32Array(buffers.input.buffer, buffers.input.offset + buffers.input.stride * inNdx + attribute.offset + compNdx * 4, 1);
759 var difInOut = inBuffer[0] - outBuffer[0];
760 /* TODO: Original code used ULP comparison for highp and mediump precision. This could cause failures. */
762 case gluShaderUtil.precision.PRECISION_HIGHP: {
763 isEqual = Math.abs(difInOut) < 0.1;
767 case gluShaderUtil.precision.PRECISION_MEDIUMP: {
768 isEqual = Math.abs(difInOut) < 0.1;
772 case gluShaderUtil.precision.PRECISION_LOWP: {
773 isEqual = Math.abs(difInOut) < 0.1;
777 throw new Error('Unknown precision: ' + precision);
780 var outBuffer = new Uint32Array(buffers.output.buffer, buffers.output.offset + buffers.output.stride * outNdx + outOffset + compNdx * 4, 1);
781 var inBuffer = new Uint32Array(buffers.input.buffer, buffers.input.offset + buffers.input.stride * inNdx + attribute.offset + compNdx * 4, 1);
782 isEqual = (inBuffer[0] == outBuffer[0]); // Bit-exact match required for integer types.
786 bufferedLogToConsole('Mismatch in ' + output.name + ' (' + attribute.name + '), output = ' + outNdx + ', input = ' + inNdx + ', component = ' + compNdx);
799 outOffset += numComponents * 4; /*sizeof(deUint32)*/
806 * Returns (for all the draw calls) the type of Primitive Mode, as it calls "es3fTransformFeedbackTests.getTransformFeedbackPrimitiveCount".
807 * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
808 * @param {Array<es3fTransformFeedbackTests.DrawCall>} array Object.<number, boolean>
809 * @return {number} primCount
811 es3fTransformFeedbackTests.computeTransformFeedbackPrimitiveCount = function(primitiveType, array) {
813 /** @type {number} */ var primCount = 0;
815 for (var i = 0; i < array.length; ++ i) {
817 if (array[i].transformFeedbackEnabled)
818 primCount += es3fTransformFeedbackTests.getTransformFeedbackPrimitiveCount(primitiveType, array[i].numElements);
825 * @param {number} target
826 * @param {number} bufferSize
827 * @param {number} guardSize
829 es3fTransformFeedbackTests.writeBufferGuard = function(target, bufferSize, guardSize) {
830 var buffer = new ArrayBuffer(guardSize);
831 var view = new Uint8Array(buffer);
832 for (var i = 0; i < guardSize; ++i) view[i] = 0xcd;
833 gl.bufferSubData(target, bufferSize, buffer);
838 * @param {ArrayBuffer} buffer
839 * @param {number} start
842 es3fTransformFeedbackTests.verifyGuard = function(buffer, start) {
844 var view = new Uint8Array(buffer, start);
845 for (var i = 0; i < view.length; i++) {
853 * @extends {tcuTestCase.DeqpTest}
854 * @param {string} name
855 * @param {string} desc
856 * @param {number} bufferMode
857 * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
860 es3fTransformFeedbackTests.TransformFeedbackCase = function(name, desc, bufferMode, primitiveType) {
861 tcuTestCase.DeqpTest.call(this, name, desc);
862 this.m_bufferMode = bufferMode;
863 this.m_primitiveType = primitiveType;
864 this.m_progSpec = new es3fTransformFeedbackTests.ProgramSpec();
866 // Derived from es3fTransformFeedbackTests.ProgramSpec in es3fTransformFeedbackTests.init()
867 this.m_inputStride = 0;
868 this.m_attributes = []; // vector<es3fTransformFeedbackTests.Attribute>
869 this.m_transformFeedbackOutputs = []; // vector<es3fTransformFeedbackTests.Output>
870 this.m_bufferStrides = []; // vector<int>
873 this.m_program = null; // glu::ShaderProgram
874 this.m_transformFeedback = null; // glu::TransformFeedback
875 this.m_outputBuffers = []; // vector<deUint32>
877 this.m_iterNdx = 0; // int
878 this.m_testPassed = true;
880 this.m_state = es3fTransformFeedbackTests.State.DRAW;
881 this.m_verifyStart = null;
883 this.m_frameWithTf = null;
884 this.m_frameWithoutTf = null;
886 this.m_viewportW = 0;
887 this.m_viewportH = 0;
888 this.m_viewportX = 0;
889 this.m_viewportY = 0;
891 this.m_primitiveQuery = null;
892 this.m_outputsOk = true;
896 setParentClass(es3fTransformFeedbackTests.TransformFeedbackCase, tcuTestCase.DeqpTest);
898 es3fTransformFeedbackTests.TransformFeedbackCase.prototype.createVerificationResult = function(retry, result) {
899 return { retry: retry, result: result };
902 es3fTransformFeedbackTests.TransformFeedbackCase.prototype.dumpShaderText = function() {
903 var dbgext = gl.getExtension('WEBGL_debug_shaders');
904 for (var ii = 0; ii < this.m_program.shaders.length; ++ii) {
905 debug('Shader source ' + ii + ' before translation:')
906 debug(this.m_program.shaders[ii].info.source);
908 debug('Shader source ' + ii + ' after translation:');
909 debug(dbgext.getTranslatedShaderSource(this.m_program.shaders[ii].shader));
913 es3fTransformFeedbackTests.TransformFeedbackCase.prototype.init = function() {
914 this.m_program = es3fTransformFeedbackTests.createVertexCaptureProgram(
920 if (!this.m_program.isOk()) {
921 // this.dumpShaderText();
923 var linkFail = this.m_program.shadersOK &&
924 !this.m_program.getProgramInfo().linkOk;
927 if (!es3fTransformFeedbackTests.isProgramSupported(this.m_progSpec, this.m_bufferMode)) {
928 var msg = 'Not Supported. Implementation limits exceeded.';
929 checkMessage(false, msg);
930 throw new TestFailedException(msg);
931 } else if (es3fTransformFeedbackTests.hasArraysInTFVaryings(this.m_progSpec)) {
932 msg = 'Capturing arrays is not supported (undefined in specification)';
933 checkMessage(false, msg);
934 throw new TestFailedException(msg);
936 throw new Error('Link failed: ' + this.m_program.getProgramInfo().infoLog);
939 throw new Error('Compile failed');
942 // debug('Program is ' +
943 // (gl.getProgramParameter(this.m_program.getProgram(), gl.LINK_STATUS) ? 'linked' : 'not linked'));
944 // this.dumpShaderText();
947 // bufferedLogToConsole('Transform feedback varyings: ' + tcu.formatArray(this.m_progSpec.getTransformFeedbackVaryings()));
948 bufferedLogToConsole('Transform feedback varyings: ' + this.m_progSpec.getTransformFeedbackVaryings());
950 // Print out transform feedback points reported by GL.
951 // bufferedLogToConsole('Transform feedback varyings reported by compiler:');
952 //logTransformFeedbackVaryings(log, gl, this.m_program.getProgram());
954 // Compute input specification.
955 this.m_inputStride = es3fTransformFeedbackTests.computeInputLayout(this.m_attributes, this.m_progSpec.getVaryings(), this.m_progSpec.isPointSizeUsed());
957 // Build list of varyings used in transform feedback.
958 es3fTransformFeedbackTests.computeTransformFeedbackOutputs(
959 this.m_transformFeedbackOutputs,
961 this.m_progSpec.getVaryings(),
962 this.m_progSpec.getTransformFeedbackVaryings(),
965 if (!this.m_transformFeedbackOutputs.length) {
966 throw new Error('transformFeedbackOutputs cannot be empty.');
969 if (this.m_bufferMode == gl.SEPARATE_ATTRIBS) {
970 for (var i = 0; i < this.m_transformFeedbackOutputs.length; ++i) {
971 this.m_bufferStrides.push(this.m_transformFeedbackOutputs[i].type.getScalarSize() * 4 /*sizeof(deUint32)*/);
975 for (var i = 0; i < this.m_transformFeedbackOutputs.length; ++i) {
976 totalSize += this.m_transformFeedbackOutputs[i].type.getScalarSize() * 4 /*sizeof(deUint32)*/;
978 this.m_bufferStrides.push(totalSize);
981 this.m_outputBuffers.length = this.m_bufferStrides.length;
982 for (var i = 0; i < this.m_outputBuffers.length; i++)
983 this.m_outputBuffers[i] = gl.createBuffer();
985 this.m_transformFeedback = gl.createTransformFeedback();
988 // this.m_testCtx.setTestResult(QP_TEST_RESULT_PASS, 'Pass');
992 es3fTransformFeedbackTests.TransformFeedbackCase.prototype.deinit = function() {
993 for (var i = 0; i < this.m_outputBuffers.length; i++)
994 gl.deleteBuffer(this.m_outputBuffers[i]);
996 // delete this.m_transformFeedback;
997 this.m_transformFeedback = null;
999 // delete this.m_program;
1000 this.m_program = null;
1003 this.m_attributes = [];
1004 this.m_transformFeedbackOutputs = [];
1005 this.m_bufferStrides = [];
1006 this.m_inputStride = 0;
1010 es3fTransformFeedbackTests.TransformFeedbackCase.prototype.iterate = function() {
1011 var s = es3fTransformFeedbackTests.TransformFeedbackCase.s_iterate;
1012 var numIterations = s.iterations.length;
1013 var seed = deMath.deMathHash(this.m_iterNdx);
1014 switch(this.m_state) {
1015 case es3fTransformFeedbackTests.State.DRAW:
1016 bufferedLogToConsole('Testing ' +
1017 s.testCases[s.iterations[this.m_iterNdx]].length +
1018 ' draw calls, (element es3fTransformFeedbackTests.count, TF state): ' +
1019 s.testCases[s.iterations[this.m_iterNdx]]
1021 this.draw(s.testCases[s.iterations[this.m_iterNdx]], seed);
1022 this.m_state = es3fTransformFeedbackTests.State.VERIFY;
1024 case es3fTransformFeedbackTests.State.VERIFY:
1025 var verifyResult = this.verify(s.testCases[s.iterations[this.m_iterNdx]]);
1026 if (verifyResult.retry) {
1029 this.m_testPassed = verifyResult.result;
1030 this.m_iterNdx += 1;
1031 if (this.m_testPassed && this.m_iterNdx < numIterations) {
1032 this.m_state = es3fTransformFeedbackTests.State.DRAW;
1036 case es3fTransformFeedbackTests.State.FINISH:
1037 if (!this.m_testPassed) testFailedOptions('Result comparison failed for iteration ' + s.iterations[this.m_iterNdx - 1], false);
1038 else testPassedOptions('Result comparison succeeded', true);
1039 return tcuTestCase.IterateResult.STOP;
1042 return tcuTestCase.IterateResult.CONTINUE;
1046 es3fTransformFeedbackTests.TransformFeedbackCase.prototype.draw = function(calls, seed) {
1047 var _min = function(x, y) { return x < y ? x : y; };
1049 var rnd = new deRandom.Random(seed);
1052 var width = gl.drawingBufferWidth;
1053 var height = gl.drawingBufferHeight;
1054 this.m_viewportW = _min(es3fTransformFeedbackTests.VIEWPORT_WIDTH, width);
1055 this.m_viewportH = _min(es3fTransformFeedbackTests.VIEWPORT_HEIGHT, height);
1056 this.m_viewportX = rnd.getInt(0, width - this.m_viewportW);
1057 this.m_viewportY = rnd.getInt(0, height - this.m_viewportH);
1058 this.m_frameWithTf = new tcuSurface.Surface(this.m_viewportW, this.m_viewportH); // tcu::Surface
1059 this.m_frameWithoutTf = new tcuSurface.Surface(this.m_viewportW, this.m_viewportH); // tcu::Surface
1060 this.m_primitiveQuery = gl.createQuery();
1061 this.m_outputsOk = true;
1064 for (var i = 0; i < calls.length; ++i) {
1065 var call = calls[i];
1066 numInputs += call.numElements;
1067 numOutputs += call.transformFeedbackEnabled ? es3fTransformFeedbackTests.getTransformFeedbackOutputCount(this.m_primitiveType, call.numElements) : 0;
1071 var inputData = es3fTransformFeedbackTests.genInputData(this.m_attributes, numInputs, this.m_inputStride, rnd);
1073 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, this.m_transformFeedback);
1075 // Allocate storage for transform feedback output buffers and bind to targets.
1076 for (var bufNdx = 0; bufNdx < this.m_outputBuffers.length; ++bufNdx) {
1077 var buffer = this.m_outputBuffers[bufNdx]; // deUint32
1078 var stride = this.m_bufferStrides[bufNdx]; // int
1079 var target = bufNdx; // int
1080 var size = stride * numOutputs; // int
1081 var guardSize = stride * es3fTransformFeedbackTests.BUFFER_GUARD_MULTIPLIER; // int
1082 var usage = gl.DYNAMIC_READ; // const deUint32
1084 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buffer);
1085 gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, size + guardSize, usage);
1086 es3fTransformFeedbackTests.writeBufferGuard(gl.TRANSFORM_FEEDBACK_BUFFER, size, guardSize);
1088 // \todo [2012-07-30 pyry] glBindBufferRange()?
1089 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, target, buffer);
1092 var attribBuffer = gl.createBuffer();
1093 gl.bindBuffer(gl.ARRAY_BUFFER, attribBuffer);
1094 gl.bufferData(gl.ARRAY_BUFFER, inputData, gl.STATIC_DRAW);
1096 // Setup attributes.
1097 for (var i = 0; i < this.m_attributes.length; ++i) {
1098 var attrib = this.m_attributes[i];
1099 var loc = gl.getAttribLocation(this.m_program.getProgram(), attrib.name);
1100 /** @type {string} */
1101 var scalarType = gluShaderUtil.getDataTypeScalarType(attrib.type.getBasicType());
1102 /** @type {number} */
1103 var numComponents = gluShaderUtil.getDataTypeScalarSize(attrib.type.getBasicType());
1106 gl.enableVertexAttribArray(loc);
1107 switch (scalarType) {
1109 gl.vertexAttribPointer(loc, numComponents, gl.FLOAT, false, this.m_inputStride, attrib.offset); break;
1111 gl.vertexAttribIPointer(loc, numComponents, gl.INT, this.m_inputStride, attrib.offset); break;
1113 gl.vertexAttribIPointer(loc, numComponents, gl.UNSIGNED_INT, this.m_inputStride, attrib.offset); break;
1119 gl.viewport(this.m_viewportX, this.m_viewportY, this.m_viewportW, this.m_viewportH);
1122 gl.useProgram(this.m_program.getProgram());
1125 gl.getUniformLocation(this.m_program.getProgram(), 'u_scale'),
1126 [0.01, 0.01, 0.01, 0.01]
1129 gl.getUniformLocation(this.m_program.getProgram(), 'u_bias'),
1130 [0.5, 0.5, 0.5, 0.5]
1134 gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, this.m_primitiveQuery);
1138 var tfEnabled = true;
1140 gl.clear(gl.COLOR_BUFFER_BIT);
1142 var tfPrimitiveMode = es3fTransformFeedbackTests.getTransformFeedbackPrimitiveMode(this.m_primitiveType);
1143 gl.beginTransformFeedback(tfPrimitiveMode);
1145 for (var i = 0; i < calls.length; ++i) {
1146 var call = calls[i];
1148 // Pause or resume transform feedback if necessary.
1149 if (call.transformFeedbackEnabled != tfEnabled) {
1150 if (call.transformFeedbackEnabled)
1151 gl.resumeTransformFeedback();
1153 gl.pauseTransformFeedback();
1154 tfEnabled = call.transformFeedbackEnabled;
1157 gl.drawArrays(gluDrawUtil.getPrimitiveGLType(gl, this.m_primitiveType), offset, call.numElements);
1158 offset += call.numElements;
1161 // Resume feedback before finishing it.
1163 gl.resumeTransformFeedback();
1165 gl.endTransformFeedback();
1167 gl.endQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
1169 // Check and log query status right after submit
1170 var query = this.m_primitiveQuery;
1172 var available = gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE);
1175 this.m_testPassed = false;
1176 this.m_state = es3fTransformFeedbackTests.State.FINISH;
1177 testFailedOptions('Transform feedback query result must not be available the same frame as they are issued.', true);
1180 // Compare result buffers.
1181 for (var bufferNdx = 0; bufferNdx < this.m_outputBuffers.length; ++bufferNdx) {
1182 var stride = this.m_bufferStrides[bufferNdx]; // int
1183 var size = stride * numOutputs; // int
1184 var guardSize = stride * es3fTransformFeedbackTests.BUFFER_GUARD_MULTIPLIER; // int
1185 var buffer = new ArrayBuffer(size + guardSize); // const void*
1187 // Bind buffer for reading.
1188 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, this.m_outputBuffers[bufferNdx]);
1190 gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, new Uint8Array(buffer));
1192 // Verify all output variables that are written to this buffer.
1193 for (var i = 0; i < this.m_transformFeedbackOutputs.length; ++i) {
1194 var out = this.m_transformFeedbackOutputs[i];
1196 if (out.bufferNdx != bufferNdx)
1199 var inputOffset = 0;
1200 var outputOffset = 0;
1202 // Process all draw calls and check ones with transform feedback enabled
1203 for (var callNdx = 0; callNdx < calls.length; ++callNdx) {
1204 var call = calls[callNdx];
1206 if (call.transformFeedbackEnabled) {
1207 var inputPtr = inputData[0] + inputOffset * this.m_inputStride; // const deUint8*
1208 var outputPtr = outputOffset * stride; // const deUint8*
1210 if (!es3fTransformFeedbackTests.compareTransformFeedbackOutput(this.m_primitiveType, out, call.numElements, {
1213 offset: inputOffset * this.m_inputStride,
1214 stride: this.m_inputStride
1218 offset: outputOffset * stride,
1222 this.m_outputsOk = false;
1227 inputOffset += call.numElements;
1228 outputOffset += call.transformFeedbackEnabled ? es3fTransformFeedbackTests.getTransformFeedbackOutputCount(this.m_primitiveType, call.numElements) : 0;
1232 // Verify guardband.
1233 if (!es3fTransformFeedbackTests.verifyGuard(buffer, size)) {
1234 bufferedLogToConsole('Error: Transform feedback buffer overrun detected');
1235 this.m_outputsOk = false;
1240 es3fTransformFeedbackTests.TransformFeedbackCase.prototype.verify = function(calls) {
1241 // Check status after mapping buffers.
1242 var mustBeReady = this.m_outputBuffers.length > 0; // Mapping buffer forces synchronization. // const bool
1243 var expectedCount = es3fTransformFeedbackTests.computeTransformFeedbackPrimitiveCount(this.m_primitiveType, calls); // const int
1244 var available = /** @type {boolean} */ (gl.getQueryParameter(this.m_primitiveQuery, gl.QUERY_RESULT_AVAILABLE));
1245 var verify_offset = 0;
1248 if (!this.m_verifyStart)
1249 this.m_verifyStart = new Date();
1251 var current = new Date();
1252 var elapsedTime = 0.001 * (current.getTime() - this.m_verifyStart.getTime());
1253 if (elapsedTime > es3fTransformFeedbackTests.MAX_VERIFY_WAIT) {
1254 testFailed('Query result not available after ' + elapsedTime + ' seconds.');
1255 this.m_state = es3fTransformFeedbackTests.State.FINISH;
1256 return this.createVerificationResult(false, false);
1259 return this.createVerificationResult(true, false);
1262 var numPrimitives = /** @type {number} */ (gl.getQueryParameter(this.m_primitiveQuery, gl.QUERY_RESULT));
1264 if (!mustBeReady && available == false)
1265 bufferedLogToConsole('ERROR: gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN result not available after mapping buffers!');
1267 bufferedLogToConsole('gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = ' + numPrimitives);
1269 if (numPrimitives != expectedCount) {
1271 bufferedLogToConsole('ERROR: Expected ' + expectedCount + ' primitives!');
1274 // Clear transform feedback state.
1275 gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
1276 for (var bufNdx = 0; bufNdx < this.m_outputBuffers.length; ++bufNdx) {
1277 gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, null);
1278 gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, bufNdx, null);
1281 gl.bindBuffer(gl.ARRAY_BUFFER, null);
1283 // Read back rendered image.
1284 this.m_frameWithTf.readViewport(gl, [this.m_viewportX, this.m_viewportY, this.m_viewportW, this.m_viewportH]);
1286 // Render without transform feedback.
1288 gl.clear(gl.COLOR_BUFFER_BIT);
1290 for (var i = 0; i < calls.length; ++i) {
1291 var call = calls[i];
1292 gl.drawArrays(gluDrawUtil.getPrimitiveGLType(gl, this.m_primitiveType), verify_offset, call.numElements);
1293 verify_offset += call.numElements;
1295 this.m_frameWithoutTf.readViewport(gl, [this.m_viewportX, this.m_viewportY, this.m_viewportW, this.m_viewportH]);
1297 // Compare images with and without transform feedback.
1298 var imagesOk = tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', this.m_frameWithoutTf, this.m_frameWithTf, [1, 1, 1, 1], tcuImageCompare.CompareLogMode.ON_ERROR);
1301 bufferedLogToConsole('Rendering result comparison between TF enabled and TF disabled passed.');
1303 bufferedLogToConsole('ERROR: Rendering result comparison between TF enabled and TF disabled failed!');
1305 return this.createVerificationResult(false, this.m_outputsOk && imagesOk && queryOk);
1309 es3fTransformFeedbackTests.dc = function(numElements, tfEnabled) {
1310 return new es3fTransformFeedbackTests.DrawCall(numElements, tfEnabled);
1314 es3fTransformFeedbackTests.TransformFeedbackCase.s_iterate = {
1317 elemCount1: [es3fTransformFeedbackTests.dc(1, true)],
1318 elemCount2: [es3fTransformFeedbackTests.dc(2, true)],
1319 elemCount3: [es3fTransformFeedbackTests.dc(3, true)],
1320 elemCount4: [es3fTransformFeedbackTests.dc(4, true)],
1321 elemCount123: [es3fTransformFeedbackTests.dc(123, true)],
1322 basicPause1: [es3fTransformFeedbackTests.dc(64, true), es3fTransformFeedbackTests.dc(64, false), es3fTransformFeedbackTests.dc(64, true)],
1323 basicPause2: [es3fTransformFeedbackTests.dc(13, true), es3fTransformFeedbackTests.dc(5, true), es3fTransformFeedbackTests.dc(17, false),
1324 es3fTransformFeedbackTests.dc(3, true), es3fTransformFeedbackTests.dc(7, false)],
1325 startPaused: [es3fTransformFeedbackTests.dc(123, false), es3fTransformFeedbackTests.dc(123, true)],
1326 random1: [es3fTransformFeedbackTests.dc(65, true), es3fTransformFeedbackTests.dc(135, false), es3fTransformFeedbackTests.dc(74, true),
1327 es3fTransformFeedbackTests.dc(16, false), es3fTransformFeedbackTests.dc(226, false), es3fTransformFeedbackTests.dc(9, true),
1328 es3fTransformFeedbackTests.dc(174, false)],
1329 random2: [es3fTransformFeedbackTests.dc(217, true), es3fTransformFeedbackTests.dc(171, true), es3fTransformFeedbackTests.dc(147, true),
1330 es3fTransformFeedbackTests.dc(152, false), es3fTransformFeedbackTests.dc(55, true)]
1333 'elemCount1', 'elemCount2', 'elemCount3', 'elemCount4', 'elemCount123',
1334 'basicPause1', 'basicPause2', 'startPaused',
1335 'random1', 'random2'
1339 es3fTransformFeedbackTests.hasArraysInTFVaryings = function(spec) {
1341 for (var i = 0; i < spec.getTransformFeedbackVaryings().length; ++i) {
1342 var tfVar = spec.getTransformFeedbackVaryings()[i];
1343 var varName = gluVarTypeUtil.parseVariableName(tfVar);
1345 var attr = es3fTransformFeedbackTests.findAttributeNameEquals(spec.getVaryings(), varName);
1346 if (attr && attr.type.isArrayType())
1353 /** es3fTransformFeedbackTests.PositionCase
1354 * @extends {es3fTransformFeedbackTests.TransformFeedbackCase}
1355 * @param {string} name
1356 * @param {string} desc
1357 * @param {number} bufferMode
1358 * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
1361 es3fTransformFeedbackTests.PositionCase = function(name, desc, bufferMode, primitiveType) {
1362 es3fTransformFeedbackTests.TransformFeedbackCase.call(this, name, desc, bufferMode, primitiveType);
1363 this.m_progSpec.addTransformFeedbackVarying('gl_Position');
1366 setParentClass(es3fTransformFeedbackTests.PositionCase, es3fTransformFeedbackTests.TransformFeedbackCase);
1368 /** es3fTransformFeedbackTests.PointSizeCase
1369 * @extends {es3fTransformFeedbackTests.TransformFeedbackCase}
1370 * @param {string} name
1371 * @param {string} desc
1372 * @param {number} bufferMode
1373 * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
1376 es3fTransformFeedbackTests.PointSizeCase = function(name, desc, bufferMode, primitiveType) {
1377 es3fTransformFeedbackTests.TransformFeedbackCase.call(this, name, desc, bufferMode, primitiveType);
1378 this.m_progSpec.addTransformFeedbackVarying('gl_PointSize');
1382 setParentClass(es3fTransformFeedbackTests.PointSizeCase, es3fTransformFeedbackTests.TransformFeedbackCase);
1384 /** es3fTransformFeedbackTests.BasicTypeCase
1385 * @extends {es3fTransformFeedbackTests.TransformFeedbackCase}
1386 * @param {string} name
1387 * @param {string} desc
1388 * @param {number} bufferMode
1389 * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
1390 * @param {gluShaderUtil.DataType} type
1391 * @param {gluShaderUtil.precision} precision
1392 * @param {es3fTransformFeedbackTests.interpolation} interpolation enum number in this javascript
1395 es3fTransformFeedbackTests.BasicTypeCase = function(name, desc, bufferMode, primitiveType, type, precision, interpolation) {
1396 es3fTransformFeedbackTests.TransformFeedbackCase.call(this, name, desc, bufferMode, primitiveType);
1398 this.m_progSpec.addVarying('v_varA', gluVarType.newTypeBasic(type, precision), interpolation);
1399 this.m_progSpec.addVarying('v_varB', gluVarType.newTypeBasic(type, precision), interpolation);
1401 this.m_progSpec.addTransformFeedbackVarying('v_varA');
1402 this.m_progSpec.addTransformFeedbackVarying('v_varB');
1406 setParentClass(es3fTransformFeedbackTests.BasicTypeCase, es3fTransformFeedbackTests.TransformFeedbackCase);
1408 /** es3fTransformFeedbackTests.BasicArrayCase
1409 * @extends {es3fTransformFeedbackTests.TransformFeedbackCase}
1410 * @param {string} name
1411 * @param {string} desc
1412 * @param {number} bufferMode
1413 * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
1414 * @param {gluShaderUtil.DataType} type
1415 * @param {gluShaderUtil.precision} precision
1416 * @param {es3fTransformFeedbackTests.interpolation} interpolation enum number in this javascript
1419 es3fTransformFeedbackTests.BasicArrayCase = function(name, desc, bufferMode, primitiveType, type, precision, interpolation) {
1420 es3fTransformFeedbackTests.TransformFeedbackCase.call(this, name, desc, bufferMode, primitiveType);
1422 if (gluShaderUtil.isDataTypeMatrix(type) || this.m_bufferMode === gl.SEPARATE_ATTRIBS) {
1423 // note For matrix types we need to use reduced array sizes or otherwise we will exceed maximum attribute (16)
1424 // or transform feedback component es3fTransformFeedbackTests.count (64).
1425 // On separate attribs mode maximum component es3fTransformFeedbackTests.count per varying is 4.
1426 this.m_progSpec.addVarying('v_varA', gluVarType.newTypeArray(gluVarType.newTypeBasic(type, precision), 1), interpolation);
1427 this.m_progSpec.addVarying('v_varB', gluVarType.newTypeArray(gluVarType.newTypeBasic(type, precision), 2), interpolation);
1429 this.m_progSpec.addVarying('v_varA', gluVarType.newTypeArray(gluVarType.newTypeBasic(type, precision), 3), interpolation);
1430 this.m_progSpec.addVarying('v_varB', gluVarType.newTypeArray(gluVarType.newTypeBasic(type, precision), 4), interpolation);
1433 this.m_progSpec.addTransformFeedbackVarying('v_varA');
1434 this.m_progSpec.addTransformFeedbackVarying('v_varB');
1438 setParentClass(es3fTransformFeedbackTests.BasicArrayCase, es3fTransformFeedbackTests.TransformFeedbackCase);
1440 /** es3fTransformFeedbackTests.ArrayElementCase
1441 * @extends {es3fTransformFeedbackTests.TransformFeedbackCase}
1442 * @param {string} name
1443 * @param {string} desc
1444 * @param {number} bufferMode
1445 * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
1446 * @param {gluShaderUtil.DataType} type
1447 * @param {gluShaderUtil.precision} precision
1448 * @param {es3fTransformFeedbackTests.interpolation} interpolation enum number in this javascript
1451 es3fTransformFeedbackTests.ArrayElementCase = function(name, desc, bufferMode, primitiveType, type, precision, interpolation) {
1453 es3fTransformFeedbackTests.TransformFeedbackCase.call(this, name, desc, bufferMode, primitiveType);
1455 this.m_progSpec.addVarying('v_varA', gluVarType.newTypeArray(gluVarType.newTypeBasic(type, precision), 3), interpolation);
1456 this.m_progSpec.addVarying('v_varB', gluVarType.newTypeArray(gluVarType.newTypeBasic(type, precision), 4), interpolation);
1458 this.m_progSpec.addTransformFeedbackVarying('v_varA[1]');
1459 this.m_progSpec.addTransformFeedbackVarying('v_varB[0]');
1460 this.m_progSpec.addTransformFeedbackVarying('v_varB[3]');
1464 setParentClass(es3fTransformFeedbackTests.ArrayElementCase, es3fTransformFeedbackTests.TransformFeedbackCase);
1466 /** es3fTransformFeedbackTests.RandomCase
1467 * @extends {es3fTransformFeedbackTests.TransformFeedbackCase}
1468 * @param {string} name
1469 * @param {string} desc
1470 * @param {number} bufferMode
1471 * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
1472 * @param {number} seed
1475 es3fTransformFeedbackTests.RandomCase = function(name, desc, bufferMode, primitiveType, seed) {
1476 es3fTransformFeedbackTests.TransformFeedbackCase.call(this, name, desc, bufferMode, primitiveType);
1480 setParentClass(es3fTransformFeedbackTests.RandomCase, es3fTransformFeedbackTests.TransformFeedbackCase);
1482 es3fTransformFeedbackTests.RandomCase.prototype.init = function() {
1484 /** @type {number} */
1485 var seed = /*deString.deStringHash(getName()) ^ */ deMath.deMathHash(this.m_iterNdx);
1487 /** @type {Array<gluShaderUtil.DataType>} */
1488 var typeCandidates = [
1489 gluShaderUtil.DataType.FLOAT,
1490 gluShaderUtil.DataType.FLOAT_VEC2,
1491 gluShaderUtil.DataType.FLOAT_VEC3,
1492 gluShaderUtil.DataType.FLOAT_VEC4,
1493 gluShaderUtil.DataType.INT,
1494 gluShaderUtil.DataType.INT_VEC2,
1495 gluShaderUtil.DataType.INT_VEC3,
1496 gluShaderUtil.DataType.INT_VEC4,
1497 gluShaderUtil.DataType.UINT,
1498 gluShaderUtil.DataType.UINT_VEC2,
1499 gluShaderUtil.DataType.UINT_VEC3,
1500 gluShaderUtil.DataType.UINT_VEC4,
1502 gluShaderUtil.DataType.FLOAT_MAT2,
1503 gluShaderUtil.DataType.FLOAT_MAT2X3,
1504 gluShaderUtil.DataType.FLOAT_MAT2X4,
1506 gluShaderUtil.DataType.FLOAT_MAT3X2,
1507 gluShaderUtil.DataType.FLOAT_MAT3,
1508 gluShaderUtil.DataType.FLOAT_MAT3X4,
1510 gluShaderUtil.DataType.FLOAT_MAT4X2,
1511 gluShaderUtil.DataType.FLOAT_MAT4X3,
1512 gluShaderUtil.DataType.FLOAT_MAT4
1515 /** @type {Array<gluShaderUtil.precision>} */
1517 gluShaderUtil.precision.PRECISION_LOWP,
1518 gluShaderUtil.precision.PRECISION_MEDIUMP,
1519 gluShaderUtil.precision.PRECISION_HIGHP
1522 var interpModes = [{name: 'smooth', interp: es3fTransformFeedbackTests.interpolation.SMOOTH}, {name: 'flat', interp: es3fTransformFeedbackTests.interpolation.FLAT}, {name: 'centroid', interp: es3fTransformFeedbackTests.interpolation.CENTROID}
1525 /** @type {number} */ var maxAttributeVectors = 16;
1526 //** @type {number} */ var maxTransformFeedbackComponents = 64; // note It is enough to limit attribute set size.
1527 /** @type {boolean} */ var isSeparateMode = (this.m_bufferMode === gl.SEPARATE_ATTRIBS);
1528 /** @type {number} */ var maxTransformFeedbackVars = isSeparateMode ? 4 : maxAttributeVectors;
1529 /** @type {number} */ var arrayWeight = 0.3;
1530 /** @type {number} */ var positionWeight = 0.7;
1531 /** @type {number} */ var pointSizeWeight = 0.1;
1532 /** @type {number} */ var captureFullArrayWeight = 0.5;
1534 /** @type {deRandom.Random} */
1535 var rnd = new deRandom.Random(seed);
1536 /** @type {boolean} */ var usePosition = rnd.getFloat() < positionWeight;
1537 /** @type {boolean} */ var usePointSize = rnd.getFloat() < pointSizeWeight;
1538 /** @type {number} */ var numAttribVectorsToUse = rnd.getInt(
1539 1, maxAttributeVectors - 1/*position*/ - (usePointSize ? 1 : 0)
1542 /** @type {number} */ var numAttributeVectors = 0;
1543 /** @type {number} */ var varNdx = 0;
1545 // Generate varyings.
1546 while (numAttributeVectors < numAttribVectorsToUse) {
1547 /** @type {number} */
1548 var maxVecs = isSeparateMode ? Math.min(2 /*at most 2*mat2*/, numAttribVectorsToUse - numAttributeVectors) : numAttribVectorsToUse - numAttributeVectors;
1549 /** @type {gluShaderUtil.DataType} */
1550 var begin = typeCandidates[0];
1551 /** @type {number} */
1552 var endCandidates = begin + (
1553 maxVecs >= 4 ? 21 : (
1554 maxVecs >= 3 ? 18 : (
1555 maxVecs >= 2 ? (isSeparateMode ? 13 : 15) : 12
1559 /** @type {gluShaderUtil.DataType} */
1560 var end = typeCandidates[endCandidates];
1562 /** @type {gluShaderUtil.DataType} */
1563 var type = rnd.choose(typeCandidates)[0];
1565 /** @type {gluShaderUtil.precision} */
1566 var precision = rnd.choose(precisions)[0];
1568 /** @type {es3fTransformFeedbackTests.interpolation} */
1569 var interp = (type === gluShaderUtil.DataType.FLOAT) ?
1570 rnd.choose(interpModes)[0].interp :
1571 es3fTransformFeedbackTests.interpolation.FLAT;
1573 /** @type {number} */
1574 var numVecs = gluShaderUtil.isDataTypeMatrix(type) ? gluShaderUtil.getDataTypeMatrixNumColumns(type) : 1;
1575 /** @type {number} */
1576 var numComps = gluShaderUtil.getDataTypeScalarSize(type);
1577 /** @type {number} */
1578 var maxArrayLen = Math.max(1, isSeparateMode ? (4 / numComps) : (maxVecs / numVecs));
1579 /** @type {boolean} */
1580 var useArray = rnd.getFloat() < arrayWeight;
1581 /** @type {number} */
1582 var arrayLen = useArray ? rnd.getInt(1, maxArrayLen) : 1;
1583 /** @type {string} */
1584 var name = 'v_var' + varNdx;
1587 this.m_progSpec.addVarying(name, gluVarType.newTypeArray(gluVarType.newTypeBasic(type, precision), arrayLen), interp);
1589 this.m_progSpec.addVarying(name, gluVarType.newTypeBasic(type, precision), interp);
1591 numAttributeVectors += arrayLen * numVecs;
1595 // Generate transform feedback candidate set.
1596 /** @type {Array<string>} */ var tfCandidates = [];
1598 if (usePosition) tfCandidates.push('gl_Position');
1599 if (usePointSize) tfCandidates.push('gl_PointSize');
1601 for (var ndx = 0; ndx < varNdx; ndx++) {
1602 /** @type {es3fTransformFeedbackTests.Varying} */
1603 var varying = this.m_progSpec.getVaryings()[ndx];
1605 if (varying.type.isArrayType()) {
1606 /** @type {boolean} */
1607 var captureFull = rnd.getFloat() < captureFullArrayWeight;
1610 tfCandidates.push(varying.name);
1612 /** @type {number} */
1613 var numElem = varying.type.getArraySize();
1614 for (var elemNdx = 0; elemNdx < numElem; elemNdx++)
1615 tfCandidates.push(varying.name + '[' + elemNdx + ']');
1618 tfCandidates.push(varying.name);
1621 // Pick random selection.
1622 var tfVaryings = [];
1623 rnd.choose(tfCandidates, tfVaryings, Math.min(tfCandidates.length, maxTransformFeedbackVars));
1624 rnd.shuffle(tfVaryings);
1625 for (var i = 0; i < tfVaryings.length; i++)
1626 this.m_progSpec.addTransformFeedbackVarying(tfVaryings[i]);
1628 es3fTransformFeedbackTests.TransformFeedbackCase.prototype.init.call(this);
1633 * Creates the test in order to be executed
1635 es3fTransformFeedbackTests.init = function() {
1637 /** @const @type {tcuTestCase.DeqpTest} */
1638 var testGroup = tcuTestCase.runner.testCases;
1640 var bufferModes = [{name: 'separate', mode: gl.SEPARATE_ATTRIBS}, {name: 'interleaved', mode: gl.INTERLEAVED_ATTRIBS}
1643 var primitiveTypes = [{name: 'points', type: gluDrawUtil.primitiveType.POINTS}, {name: 'lines', type: gluDrawUtil.primitiveType.LINES}, {name: 'triangles', type: gluDrawUtil.primitiveType.TRIANGLES}
1646 /** @type {Array<gluShaderUtil.DataType>} */
1648 gluShaderUtil.DataType.FLOAT,
1649 gluShaderUtil.DataType.FLOAT_VEC2,
1650 gluShaderUtil.DataType.FLOAT_VEC3,
1651 gluShaderUtil.DataType.FLOAT_VEC4,
1652 gluShaderUtil.DataType.FLOAT_MAT2,
1653 gluShaderUtil.DataType.FLOAT_MAT2X3,
1654 gluShaderUtil.DataType.FLOAT_MAT2X4,
1655 gluShaderUtil.DataType.FLOAT_MAT3X2,
1656 gluShaderUtil.DataType.FLOAT_MAT3,
1657 gluShaderUtil.DataType.FLOAT_MAT3X4,
1658 gluShaderUtil.DataType.FLOAT_MAT4X2,
1659 gluShaderUtil.DataType.FLOAT_MAT4X3,
1660 gluShaderUtil.DataType.FLOAT_MAT4,
1661 gluShaderUtil.DataType.INT,
1662 gluShaderUtil.DataType.INT_VEC2,
1663 gluShaderUtil.DataType.INT_VEC3,
1664 gluShaderUtil.DataType.INT_VEC4,
1665 gluShaderUtil.DataType.UINT,
1666 gluShaderUtil.DataType.UINT_VEC2,
1667 gluShaderUtil.DataType.UINT_VEC3,
1668 gluShaderUtil.DataType.UINT_VEC4
1671 /** @type {Array<gluShaderUtil.precision>} */
1674 gluShaderUtil.precision.PRECISION_LOWP,
1675 gluShaderUtil.precision.PRECISION_MEDIUMP,
1676 gluShaderUtil.precision.PRECISION_HIGHP
1678 // glsUBC.UniformFlags.PRECISION_LOW,
1679 // glsUBC.UniformFlags.PRECISION_MEDIUM,
1680 // glsUBC.UniformFlags.PRECISION_HIGH
1683 var interpModes = [{name: 'smooth', interp: es3fTransformFeedbackTests.interpolation.SMOOTH}, {name: 'flat', interp: es3fTransformFeedbackTests.interpolation.FLAT}, {name: 'centroid', interp: es3fTransformFeedbackTests.interpolation.CENTROID}
1687 /** @type {tcuTestCase.DeqpTest} */
1688 var positionGroup = tcuTestCase.newTest('position', 'gl_Position capture using transform feedback');
1689 testGroup.addChild(positionGroup);
1691 for (var primitiveType = 0; primitiveType < primitiveTypes.length; primitiveType++) {
1692 for (var bufferMode = 0; bufferMode < bufferModes.length; bufferMode++) {
1693 /** @type {string} */
1694 var name = primitiveTypes[primitiveType].name + '_' + bufferModes[bufferMode].name;
1696 positionGroup.addChild(new es3fTransformFeedbackTests.PositionCase(
1699 bufferModes[bufferMode].mode,
1700 primitiveTypes[primitiveType].type
1706 /** @type {tcuTestCase.DeqpTest} */ var pointSizeGroup = tcuTestCase.newTest('point_size', 'gl_PointSize capture using transform feedback');
1707 testGroup.addChild(pointSizeGroup);
1709 for (var primitiveType = 0; primitiveType < primitiveTypes.length; primitiveType++) {
1710 for (var bufferMode = 0; bufferMode < bufferModes.length; bufferMode++) {
1711 var name = primitiveTypes[primitiveType].name + '_' + bufferModes[bufferMode].name;
1713 pointSizeGroup.addChild(new es3fTransformFeedbackTests.PointSizeCase(
1716 bufferModes[bufferMode].mode,
1717 primitiveTypes[primitiveType].type
1723 for (var bufferModeNdx = 0; bufferModeNdx < bufferModes.length; bufferModeNdx++) {
1724 /** @type {number} */
1725 var bufferMode = bufferModes[bufferModeNdx].mode;
1726 for (var primitiveTypeNdx = 0; primitiveTypeNdx < primitiveTypes.length; primitiveTypeNdx++) {
1727 /** @type {tcuTestCase.DeqpTest} */
1728 var primitiveGroup = tcuTestCase.newTest(
1729 'basic_types.' + bufferModes[bufferModeNdx].name + '.' + primitiveTypes[primitiveTypeNdx].name,
1730 'Basic types in transform feedback');
1731 /** @type {number} */
1732 var primitiveType = primitiveTypes[primitiveTypeNdx].type;
1733 testGroup.addChild(primitiveGroup);
1735 for (var typeNdx = 0; typeNdx < basicTypes.length; typeNdx++) {
1736 /** @type {gluShaderUtil.DataType} */
1737 var type = basicTypes[typeNdx];
1738 /** @type {boolean} */
1739 var isFloat = gluShaderUtil.getDataTypeScalarType(type) == gluShaderUtil.DataType.FLOAT;
1741 for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
1742 /** @type {gluShaderUtil.precision} */
1743 var precision = precisions[precNdx];
1744 var name = gluShaderUtil.getPrecisionName(precision) + '_' + gluShaderUtil.getDataTypeName(type);
1746 primitiveGroup.addChild(new es3fTransformFeedbackTests.BasicTypeCase(
1753 isFloat ? es3fTransformFeedbackTests.interpolation.SMOOTH : es3fTransformFeedbackTests.interpolation.FLAT
1761 for (var bufferModeNdx = 0; bufferModeNdx < bufferModes.length; bufferModeNdx++) {
1762 var bufferMode = bufferModes[bufferModeNdx].mode;
1763 for (var primitiveTypeNdx = 0; primitiveTypeNdx < primitiveTypes.length; primitiveTypeNdx++) {
1764 var primitiveGroup = tcuTestCase.newTest(
1765 'array.' + bufferModes[bufferModeNdx].name + '.' + primitiveTypes[primitiveTypeNdx].name,
1766 'Capturing whole array in TF');
1767 /** @type {number} */
1768 var primitiveType = primitiveTypes[primitiveTypeNdx].type;
1769 testGroup.addChild(primitiveGroup);
1771 for (var typeNdx = 0; typeNdx < basicTypes.length; typeNdx++) {
1772 var type = basicTypes[typeNdx];
1773 var isFloat = gluShaderUtil.getDataTypeScalarType(type) == gluShaderUtil.DataType.FLOAT;
1775 for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
1776 var precision = precisions[precNdx];
1777 var name = gluShaderUtil.getPrecisionName(precision) + '_' + gluShaderUtil.getDataTypeName(type);
1779 primitiveGroup.addChild(new es3fTransformFeedbackTests.BasicArrayCase(
1786 isFloat ? es3fTransformFeedbackTests.interpolation.SMOOTH : es3fTransformFeedbackTests.interpolation.FLAT
1794 for (var bufferModeNdx = 0; bufferModeNdx < bufferModes.length; bufferModeNdx++) {
1795 var bufferMode = bufferModes[bufferModeNdx].mode;
1796 for (var primitiveTypeNdx = 0; primitiveTypeNdx < primitiveTypes.length; primitiveTypeNdx++) {
1797 var primitiveGroup = tcuTestCase.newTest(
1798 'array_element.' + bufferModes[bufferModeNdx].name + '.' + primitiveTypes[primitiveTypeNdx].name,
1799 'Capturing single array element in TF');
1800 var primitiveType = primitiveTypes[primitiveTypeNdx].type;
1801 testGroup.addChild(primitiveGroup);
1803 for (var typeNdx = 0; typeNdx < basicTypes.length; typeNdx++) {
1804 var type = basicTypes[typeNdx];
1805 var isFloat = gluShaderUtil.getDataTypeScalarType(type) == gluShaderUtil.DataType.FLOAT;
1807 for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
1808 var precision = precisions[precNdx];
1809 var name = gluShaderUtil.getPrecisionName(precision) + '_' + gluShaderUtil.getDataTypeName(type);
1811 primitiveGroup.addChild(new es3fTransformFeedbackTests.ArrayElementCase(
1818 isFloat ? es3fTransformFeedbackTests.interpolation.SMOOTH : es3fTransformFeedbackTests.interpolation.FLAT
1826 for (var modeNdx = 0; modeNdx < interpModes.length; modeNdx++) {
1827 var interp = interpModes[modeNdx].interp;
1828 var modeGroup = tcuTestCase.newTest(
1829 'interpolation.' + interpModes[modeNdx].name,
1830 'Different interpolation modes in transform feedback varyings');
1831 testGroup.addChild(modeGroup);
1833 for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
1834 var precision = precisions[precNdx];
1836 for (var primitiveType = 0; primitiveType < primitiveTypes.length; primitiveType++) {
1837 for (var bufferMode = 0; bufferMode < bufferModes.length; bufferMode++) {
1839 gluShaderUtil.getPrecisionName(precision) +
1840 '_vec4_' + primitiveTypes[primitiveType].name +
1841 '_' + bufferModes[bufferMode].name
1844 modeGroup.addChild(new es3fTransformFeedbackTests.BasicTypeCase(
1847 bufferModes[bufferMode].mode,
1848 primitiveTypes[primitiveType].type,
1849 gluShaderUtil.DataType.FLOAT_VEC4,
1859 for (var bufferModeNdx = 0; bufferModeNdx < bufferModes.length; bufferModeNdx++) {
1860 /** @type {number} */
1861 var bufferMode = bufferModes[bufferModeNdx].mode;
1862 for (var primitiveTypeNdx = 0; primitiveTypeNdx < primitiveTypes.length; primitiveTypeNdx++) {
1863 var primitiveGroup = tcuTestCase.newTest(
1864 'random.' + bufferModes[bufferModeNdx].name + '.' + primitiveTypes[primitiveTypeNdx].name,
1865 'Randomized transform feedback cases');
1866 /** @type {number} */
1867 var primitiveType = primitiveTypes[primitiveTypeNdx].type;
1868 testGroup.addChild(primitiveGroup);
1870 for (var ndx = 0; ndx < 10; ndx++) {
1871 /** @type {number} */
1872 var seed = deMath.deMathHash(bufferMode) ^ deMath.deMathHash(primitiveType) ^ deMath.deMathHash(ndx);
1874 primitiveGroup.addChild(new es3fTransformFeedbackTests.RandomCase(
1875 (ndx + 1).toString(),
1888 * Create and execute the test cases
1890 es3fTransformFeedbackTests.run = function(context, range) {
1892 var testName = 'transform_feedback';
1893 var testDescription = 'Transform Feedback Tests';
1894 var state = tcuTestCase.runner;
1896 state.testName = testName;
1897 state.testCases = tcuTestCase.newTest(testName, testDescription, null);
1899 //Set up name and description of this test series.
1900 setCurrentTestName(testName);
1901 description(testDescription);
1903 es3fTransformFeedbackTests.init();
1905 state.setRange(range);
1906 tcuTestCase.runTestCases();
1908 bufferedLogToConsole(err);
1909 tcuTestCase.runner.terminate();