Backed out changeset 7272b7396c78 (bug 1932758) for causing fenix debug failures...
[gecko.git] / dom / canvas / test / webgl-conf / checkout / deqp / functional / gles3 / es3fDrawTests.js
blobdf42ac8193ee0e672fc4e0d3652d6ab7d4169021
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES Utilities
3  * ------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  */
21 'use strict';
22 goog.provide('functional.gles3.es3fDrawTests');
23 goog.require('framework.common.tcuLogImage');
24 goog.require('framework.common.tcuRGBA');
25 goog.require('framework.common.tcuSurface');
26 goog.require('framework.common.tcuTestCase');
27 goog.require('framework.common.tcuTexture');
28 goog.require('framework.delibs.debase.deMath');
29 goog.require('framework.delibs.debase.deRandom');
30 goog.require('framework.delibs.debase.deString');
31 goog.require('framework.delibs.debase.deUtil');
32 goog.require('framework.opengl.gluDrawUtil');
33 goog.require('framework.opengl.gluShaderProgram');
34 goog.require('framework.opengl.gluShaderUtil');
35 goog.require('framework.opengl.gluTexture');
36 goog.require('framework.opengl.gluVarType');
37 goog.require('framework.opengl.simplereference.sglrGLContext');
38 goog.require('framework.opengl.simplereference.sglrShaderProgram');
39 goog.require('framework.referencerenderer.rrFragmentOperations');
40 goog.require('framework.referencerenderer.rrGenericVector');
41 goog.require('framework.referencerenderer.rrShadingContext');
42 goog.require('framework.referencerenderer.rrVertexAttrib');
43 goog.require('framework.referencerenderer.rrVertexPacket');
44 goog.require('modules.shared.glsDrawTests');
46 goog.scope(function() {
48     var es3fDrawTests = functional.gles3.es3fDrawTests;
49     var gluDrawUtil = framework.opengl.gluDrawUtil;
50     var gluShaderUtil = framework.opengl.gluShaderUtil;
51     var gluShaderProgram = framework.opengl.gluShaderProgram;
52     var gluTexture = framework.opengl.gluTexture;
53     var gluVarType = framework.opengl.gluVarType;
54     var tcuLogImage = framework.common.tcuLogImage;
55     var tcuRGBA = framework.common.tcuRGBA;
56     var tcuTestCase = framework.common.tcuTestCase;
57     var tcuSurface = framework.common.tcuSurface;
58     var tcuTexture = framework.common.tcuTexture;
59     var deMath = framework.delibs.debase.deMath;
60     var deString = framework.delibs.debase.deString;
61     var deRandom = framework.delibs.debase.deRandom;
62     var deUtil = framework.delibs.debase.deUtil;
63     var glsDrawTests = modules.shared.glsDrawTests;
64     var sglrShaderProgram = framework.opengl.simplereference.sglrShaderProgram;
65     var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
66     var rrFragmentOperations = framework.referencerenderer.rrFragmentOperations;
67     var rrGenericVector = framework.referencerenderer.rrGenericVector;
68     var rrShadingContext = framework.referencerenderer.rrShadingContext;
69     var rrVertexAttrib = framework.referencerenderer.rrVertexAttrib;
70     var rrVertexPacket = framework.referencerenderer.rrVertexPacket;
72     /** @type {WebGL2RenderingContext}*/ var gl;
74     /**
75      * @enum
76      */
77     es3fDrawTests.TestIterationType = {
78         DRAW_COUNT: 0, // !< test with 2, 6, and 26 primitives
79         INSTANCE_COUNT: 1, // !< test with 2, 4, and 12 instances
80         INDEX_RANGE: 2
81     };
83     /**
84      * @param {glsDrawTests.DrawTest} test
85      * @param {glsDrawTests.DrawTestSpec} baseSpec
86      * @param {?es3fDrawTests.TestIterationType} type
87      */
88     es3fDrawTests.addTestIterations = function(test, baseSpec, type) {
89         var spec = /** @type {glsDrawTests.DrawTestSpec} */ (deUtil.clone(baseSpec));
91         if (type == es3fDrawTests.TestIterationType.DRAW_COUNT) {
92             spec.primitiveCount = 1;
93             test.addIteration(spec, 'draw count = ' + spec.primitiveCount);
95             spec.primitiveCount = 5;
96             test.addIteration(spec, 'draw count = ' + spec.primitiveCount);
98             spec.primitiveCount = 25;
99             test.addIteration(spec, 'draw count = ' + spec.primitiveCount);
100         } else if (type == es3fDrawTests.TestIterationType.INSTANCE_COUNT) {
101             spec.instanceCount = 1;
102             test.addIteration(spec, 'instance count = ' + spec.instanceCount);
104             spec.instanceCount = 4;
105             test.addIteration(spec, 'instance count = ' + spec.instanceCount);
107             spec.instanceCount = 11;
108             test.addIteration(spec, 'instance count = ' + spec.instanceCount);
109         } else if (type == es3fDrawTests.TestIterationType.INDEX_RANGE) {
110             spec.indexMin = 0;
111             spec.indexMax = 23;
112             test.addIteration(spec, 'index range = [' + spec.indexMin + ', ' + spec.indexMax + ']');
114             spec.indexMin = 23;
115             spec.indexMax = 40;
116             test.addIteration(spec, 'index range = [' + spec.indexMin + ', ' + spec.indexMax + ']');
118             // Only makes sense with points
119             if (spec.primitive == glsDrawTests.DrawTestSpec.Primitive.POINTS) {
120                 spec.indexMin = 5;
121                 spec.indexMax = 5;
122                 test.addIteration(spec, 'index range = [' + spec.indexMin + ', ' + spec.indexMax + ']');
123             }
124         } else
125             throw new Error('Invalid test iteration type');
126     };
128     /**
129      * @param {glsDrawTests.DrawTestSpec} spec
130      * @param {?glsDrawTests.DrawTestSpec.DrawMethod} method
131      */
132     es3fDrawTests.genBasicSpec = function(spec, method) {
133         //spec.apiType = glu::ApiType::es(3,0);
134         spec.primitive = glsDrawTests.DrawTestSpec.Primitive.TRIANGLES;
135         spec.primitiveCount = 6;
136         spec.drawMethod = method;
137         spec.indexType = null;
138         spec.indexPointerOffset = 0;
139         spec.indexStorage = null;
140         spec.first = 0;
141         spec.indexMin = 0;
142         spec.indexMax = 0;
143         spec.instanceCount = 1;
145         spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
147         spec.attribs[0].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
148         spec.attribs[0].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
149         spec.attribs[0].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
150         spec.attribs[0].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
151         spec.attribs[0].componentCount = 4;
152         spec.attribs[0].offset = 0;
153         spec.attribs[0].stride = 0;
154         spec.attribs[0].normalize = false;
155         spec.attribs[0].instanceDivisor = 0;
156         spec.attribs[0].useDefaultAttribute = false;
158         spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
160         spec.attribs[1].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
161         spec.attribs[1].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
162         spec.attribs[1].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
163         spec.attribs[1].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
164         spec.attribs[1].componentCount = 2;
165         spec.attribs[1].offset = 0;
166         spec.attribs[1].stride = 0;
167         spec.attribs[1].normalize = false;
168         spec.attribs[1].instanceDivisor = 0;
169         spec.attribs[1].useDefaultAttribute = false;
170     };
172     /**
173      * @constructor
174      * @extends {tcuTestCase.DeqpTest}
175      * @param {string} name
176      * @param {string} descr
177      * @param {?glsDrawTests.DrawTestSpec.DrawMethod} drawMethod
178      * @param {?glsDrawTests.DrawTestSpec.Primitive} primitive
179      * @param {?glsDrawTests.DrawTestSpec.IndexType} indexType
180      * @param {?glsDrawTests.DrawTestSpec.Storage} indexStorage
181      */
182     es3fDrawTests.AttributeGroup = function(name, descr, drawMethod, primitive, indexType, indexStorage) {
183         tcuTestCase.DeqpTest.call(this, name, descr);
184         this.m_method = drawMethod;
185         this.m_primitive = primitive;
186         this.m_indexType = indexType;
187         this.m_indexStorage = indexStorage;
188         this.makeExecutable();
189     };
191     es3fDrawTests.AttributeGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
192     es3fDrawTests.AttributeGroup.prototype.constructor = es3fDrawTests.AttributeGroup;
194     es3fDrawTests.AttributeGroup.prototype.init = function() {
195         // select test type
196         /** @type {boolean} */ var instanced = this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS_INSTANCED ||
197             this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_INSTANCED;
198         /** @type {boolean} */ var ranged = this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED;
199         /** @type {es3fDrawTests.TestIterationType} */ var testType = instanced ? es3fDrawTests.TestIterationType.INSTANCE_COUNT :
200             (ranged ? es3fDrawTests.TestIterationType.INDEX_RANGE : es3fDrawTests.TestIterationType.DRAW_COUNT);
202         // Single attribute
203         /** @type {glsDrawTests.DrawTest} */ var test = new glsDrawTests.DrawTest(null, 'single_attribute', 'Single attribute array.');
204         /** @type {glsDrawTests.DrawTestSpec} */ var spec = new glsDrawTests.DrawTestSpec();
206         //spec.apiType = glu::ApiType::es(3,0);
207         spec.primitive = this.m_primitive;
208         spec.primitiveCount = 5;
209         spec.drawMethod = this.m_method;
210         spec.indexType = this.m_indexType;
211         spec.indexPointerOffset = 0;
212         spec.indexStorage = this.m_indexStorage;
213         spec.first = 0;
214         spec.indexMin = 0;
215         spec.indexMax = 0;
216         spec.instanceCount = 1;
218         spec.attribs.length = 0;
220         spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
221         spec.attribs[0].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
222         spec.attribs[0].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
223         spec.attribs[0].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
224         spec.attribs[0].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
225         spec.attribs[0].componentCount = 2;
226         spec.attribs[0].offset = 0;
227         spec.attribs[0].stride = 0;
228         spec.attribs[0].normalize = false;
229         spec.attribs[0].instanceDivisor = 0;
230         spec.attribs[0].useDefaultAttribute = false;
232         es3fDrawTests.addTestIterations(test, spec, testType);
234         this.addChild(test);
236         // Multiple attribute
238         test = new glsDrawTests.DrawTest(null, 'multiple_attributes', 'Multiple attribute arrays.');
239         spec.primitive = this.m_primitive;
240         spec.primitiveCount = 5;
241         spec.drawMethod = this.m_method;
242         spec.indexType = this.m_indexType;
243         spec.indexPointerOffset = 0;
244         spec.indexStorage = this.m_indexStorage;
245         spec.first = 0;
246         spec.indexMin = 0;
247         spec.indexMax = 0;
248         spec.instanceCount = 1;
250         spec.attribs.length = 0;
252         spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
253         spec.attribs[0].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
254         spec.attribs[0].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
255         spec.attribs[0].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
256         spec.attribs[0].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
257         spec.attribs[0].componentCount = 4;
258         spec.attribs[0].offset = 0;
259         spec.attribs[0].stride = 0;
260         spec.attribs[0].normalize = false;
261         spec.attribs[0].instanceDivisor = 0;
262         spec.attribs[0].useDefaultAttribute = false;
264         spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
265         spec.attribs[1].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
266         spec.attribs[1].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
267         spec.attribs[1].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
268         spec.attribs[1].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
269         spec.attribs[1].componentCount = 2;
270         spec.attribs[1].offset = 0;
271         spec.attribs[1].stride = 0;
272         spec.attribs[1].normalize = false;
273         spec.attribs[1].instanceDivisor = 0;
274         spec.attribs[1].useDefaultAttribute = false;
276         es3fDrawTests.addTestIterations(test, spec, testType);
278         this.addChild(test);
280         // Multiple attribute, second one divided
282         test = new glsDrawTests.DrawTest(null, 'instanced_attributes', 'Instanced attribute array.');
284         //spec.apiType = glu::ApiType::es(3,0);
285         spec.primitive = this.m_primitive;
286         spec.primitiveCount = 5;
287         spec.drawMethod = this.m_method;
288         spec.indexType = this.m_indexType;
289         spec.indexPointerOffset = 0;
290         spec.indexStorage = this.m_indexStorage;
291         spec.first = 0;
292         spec.indexMin = 0;
293         spec.indexMax = 0;
294         spec.instanceCount = 1;
296         spec.attribs.length = 0;
298         spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
299         spec.attribs[0].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
300         spec.attribs[0].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
301         spec.attribs[0].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
302         spec.attribs[0].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
303         spec.attribs[0].componentCount = 4;
304         spec.attribs[0].offset = 0;
305         spec.attribs[0].stride = 0;
306         spec.attribs[0].normalize = false;
307         spec.attribs[0].instanceDivisor = 0;
308         spec.attribs[0].useDefaultAttribute = false;
310         // Add another position component so the instances wont be drawn on each other
311         spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
312         spec.attribs[1].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
313         spec.attribs[1].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
314         spec.attribs[1].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
315         spec.attribs[1].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
316         spec.attribs[1].componentCount = 2;
317         spec.attribs[1].offset = 0;
318         spec.attribs[1].stride = 0;
319         spec.attribs[1].normalize = false;
320         spec.attribs[1].instanceDivisor = 1;
321         spec.attribs[1].useDefaultAttribute = false;
322         spec.attribs[1].additionalPositionAttribute = true;
324         // Instanced color
325         spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
326         spec.attribs[2].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
327         spec.attribs[2].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
328         spec.attribs[2].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
329         spec.attribs[2].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
330         spec.attribs[2].componentCount = 3;
331         spec.attribs[2].offset = 0;
332         spec.attribs[2].stride = 0;
333         spec.attribs[2].normalize = false;
334         spec.attribs[2].instanceDivisor = 1;
335         spec.attribs[2].useDefaultAttribute = false;
337         es3fDrawTests.addTestIterations(test, spec, testType);
339         this.addChild(test);
341         // Multiple attribute, second one default
342         test = new glsDrawTests.DrawTest(null, 'default_attribute', 'Attribute specified with glVertexAttrib*.');
344         //spec.apiType = glu::ApiType::es(3,0);
345         spec.primitive = this.m_primitive;
346         spec.primitiveCount = 5;
347         spec.drawMethod = this.m_method;
348         spec.indexType = this.m_indexType;
349         spec.indexPointerOffset = 0;
350         spec.indexStorage = this.m_indexStorage;
351         spec.first = 0;
352         spec.indexMin = 0;
353         spec.indexMax = 17; // \note addTestIterations is not called for the spec, so we must ensure [indexMin, indexMax] is a good range
354         spec.instanceCount = 1;
356         spec.attribs.length = 0;
358         spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
359         spec.attribs[0].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
360         spec.attribs[0].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
361         spec.attribs[0].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
362         spec.attribs[0].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
363         spec.attribs[0].componentCount = 2;
364         spec.attribs[0].offset = 0;
365         spec.attribs[0].stride = 0;
366         spec.attribs[0].normalize = false;
367         spec.attribs[0].instanceDivisor = 0;
368         spec.attribs[0].useDefaultAttribute = false;
370         /** @type {Array<{input:?glsDrawTests.DrawTestSpec.InputType, output:?glsDrawTests.DrawTestSpec.OutputType, componentCount:number}>} */ var iopairs = [
371             {input: glsDrawTests.DrawTestSpec.InputType.FLOAT, output: glsDrawTests.DrawTestSpec.OutputType.VEC2, componentCount: 4},
372             {input: glsDrawTests.DrawTestSpec.InputType.FLOAT, output: glsDrawTests.DrawTestSpec.OutputType.VEC4, componentCount: 2},
373             {input: glsDrawTests.DrawTestSpec.InputType.INT, output: glsDrawTests.DrawTestSpec.OutputType.IVEC3, componentCount: 4},
374             {input: glsDrawTests.DrawTestSpec.InputType.UNSIGNED_INT, output: glsDrawTests.DrawTestSpec.OutputType.UVEC2, componentCount: 4}
375         ];
377         spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
378         for (var ioNdx = 0; ioNdx < iopairs.length; ++ioNdx) {
379             /** @type {string} */ var desc = glsDrawTests.DrawTestSpec.inputTypeToString(iopairs[ioNdx].input) + iopairs[ioNdx].componentCount + ' to ' + glsDrawTests.DrawTestSpec.outputTypeToString(iopairs[ioNdx].output);
381             spec.attribs[1].inputType = iopairs[ioNdx].input;
382             spec.attribs[1].outputType = iopairs[ioNdx].output;
383             spec.attribs[1].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
384             spec.attribs[1].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
385             spec.attribs[1].componentCount = iopairs[ioNdx].componentCount;
386             spec.attribs[1].offset = 0;
387             spec.attribs[1].stride = 0;
388             spec.attribs[1].normalize = false;
389             spec.attribs[1].instanceDivisor = 0;
390             spec.attribs[1].useDefaultAttribute = true;
392             test.addIteration(spec, desc);
393         }
395         this.addChild(test);
396     };
398     /**
399      * @constructor
400      * @extends {tcuTestCase.DeqpTest}
401      * @param {string} name
402      * @param {string} descr
403      * @param {?glsDrawTests.DrawTestSpec.DrawMethod} drawMethod
404      */
405     es3fDrawTests.IndexGroup = function(name, descr, drawMethod) {
406         tcuTestCase.DeqpTest.call(this, name, descr);
407         /** @type {?glsDrawTests.DrawTestSpec.DrawMethod} */ this.m_method = drawMethod;
408         this.makeExecutable();
409     };
411     es3fDrawTests.IndexGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
412     es3fDrawTests.IndexGroup.prototype.constructor = es3fDrawTests.IndexGroup;
414     es3fDrawTests.IndexGroup.prototype.init = function() {
415         /** @type {Array<{storage: ?glsDrawTests.DrawTestSpec.Storage, type: ?glsDrawTests.DrawTestSpec.IndexType, aligned: boolean, offsets: Array<number>}>} */ var tests = [
416             {storage: glsDrawTests.DrawTestSpec.Storage.BUFFER, type: glsDrawTests.DrawTestSpec.IndexType.BYTE, aligned: true, offsets: [0, 1, -1]},
417             {storage: glsDrawTests.DrawTestSpec.Storage.BUFFER, type: glsDrawTests.DrawTestSpec.IndexType.SHORT, aligned: true, offsets: [0, 2, -1]},
418             {storage: glsDrawTests.DrawTestSpec.Storage.BUFFER, type: glsDrawTests.DrawTestSpec.IndexType.INT, aligned: true, offsets: [0, 4, -1]},
420             {storage: glsDrawTests.DrawTestSpec.Storage.BUFFER, type: glsDrawTests.DrawTestSpec.IndexType.SHORT, aligned: false, offsets: [1, 3, -1]},
421             {storage: glsDrawTests.DrawTestSpec.Storage.BUFFER, type: glsDrawTests.DrawTestSpec.IndexType.INT, aligned: false, offsets: [2, 3, -1]}
422         ];
424         /** @type {glsDrawTests.DrawTestSpec} */ var spec = new glsDrawTests.DrawTestSpec();
425         es3fDrawTests.genBasicSpec(spec, this.m_method);
427         /** @type {tcuTestCase.DeqpTest} */ var bufferGroup = new tcuTestCase.DeqpTest('buffer', 'buffer');
428         /** @type {tcuTestCase.DeqpTest} */ var unalignedBufferGroup = new tcuTestCase.DeqpTest('unaligned_buffer', 'unaligned buffer');
430         this.addChild(bufferGroup);
431         this.addChild(unalignedBufferGroup);
433         for (var testNdx = 0; testNdx < tests.length; ++testNdx) {
434             /** @type {{storage: ?glsDrawTests.DrawTestSpec.Storage, type: ?glsDrawTests.DrawTestSpec.IndexType, aligned: boolean, offsets: Array<number>}} */
435             var indexTest = tests[testNdx];
436             /** @type {tcuTestCase.DeqpTest} */ var group = indexTest.aligned ? bufferGroup : unalignedBufferGroup;
438             /** @type {string} */ var name = 'index_' + glsDrawTests.DrawTestSpec.indexTypeToString(indexTest.type);
439             /** @type {string} */ var desc = 'index ' + glsDrawTests.DrawTestSpec.indexTypeToString(indexTest.type) + ' in ' + glsDrawTests.DrawTestSpec.storageToString(indexTest.storage);
440             /** @type {glsDrawTests.DrawTest} */ var test = new glsDrawTests.DrawTest(null, name, desc);
442             spec.indexType = indexTest.type;
443             spec.indexStorage = indexTest.storage;
445             for (var iterationNdx = 0; iterationNdx < indexTest.offsets.length && indexTest.offsets[iterationNdx] != -1; ++iterationNdx) {
446                 /** @type {string} */ var iterationDesc = 'offset ' + indexTest.offsets[iterationNdx];
447                 spec.indexPointerOffset = indexTest.offsets[iterationNdx];
448                 test.addIteration(spec, iterationDesc);
449             }
451             if (spec.isCompatibilityTest() != glsDrawTests.DrawTestSpec.CompatibilityTestType.UNALIGNED_OFFSET &&
452                 spec.isCompatibilityTest() != glsDrawTests.DrawTestSpec.CompatibilityTestType.UNALIGNED_STRIDE)
453                 group.addChild(test);
454         }
455     };
457     /**
458      * @constructor
459      * @extends {tcuTestCase.DeqpTest}
460      * @param {string} name
461      * @param {string} descr
462      * @param {?glsDrawTests.DrawTestSpec.DrawMethod} drawMethod
463      */
464     es3fDrawTests.FirstGroup = function(name, descr, drawMethod) {
465         tcuTestCase.DeqpTest.call(this, name, descr);
466         /** @type {?glsDrawTests.DrawTestSpec.DrawMethod} */ this.m_method = drawMethod;
467         this.makeExecutable();
468     };
470     es3fDrawTests.FirstGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
471     es3fDrawTests.FirstGroup.prototype.constructor = es3fDrawTests.FirstGroup;
473     /**
474      * init
475      */
476     es3fDrawTests.FirstGroup.prototype.init = function() {
477         var firsts =
478         [
479             1, 3, 17
480         ];
482         /** @type {glsDrawTests.DrawTestSpec} */ var spec = new glsDrawTests.DrawTestSpec();
483         es3fDrawTests.genBasicSpec(spec, this.m_method);
485         for (var firstNdx = 0; firstNdx < firsts.length; ++firstNdx) {
486             var name = 'first_' + firsts[firstNdx];
487             var desc = 'first ' + firsts[firstNdx];
488             /** @type {glsDrawTests.DrawTest} */ var test = new glsDrawTests.DrawTest(null, name, desc);
490             spec.first = firsts[firstNdx];
492             es3fDrawTests.addTestIterations(test, spec, es3fDrawTests.TestIterationType.DRAW_COUNT);
494             this.addChild(test);
495         }
496     };
498     /**
499      * @constructor
500      * @extends {tcuTestCase.DeqpTest}
501      * @param {string} name
502      * @param {string} descr
503      * @param {?glsDrawTests.DrawTestSpec.DrawMethod} drawMethod
504      */
505     es3fDrawTests.MethodGroup = function(name, descr, drawMethod) {
506         tcuTestCase.DeqpTest.call(this, name, descr);
507         /** @type {?glsDrawTests.DrawTestSpec.DrawMethod} */ this.m_method = drawMethod;
508         this.makeExecutable();
509     };
511     es3fDrawTests.MethodGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
512     es3fDrawTests.MethodGroup.prototype.constructor = es3fDrawTests.MethodGroup;
514     /**
515      * init
516      */
517     es3fDrawTests.MethodGroup.prototype.init = function() {
518         var indexed = (this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS) || (this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_INSTANCED) || (this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED);
519         var hasFirst = (this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS) || (this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS_INSTANCED);
521         var primitive =
522         [
523             glsDrawTests.DrawTestSpec.Primitive.POINTS,
524             glsDrawTests.DrawTestSpec.Primitive.TRIANGLES,
525             glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_FAN,
526             glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_STRIP,
527             glsDrawTests.DrawTestSpec.Primitive.LINES,
528             glsDrawTests.DrawTestSpec.Primitive.LINE_STRIP,
529             glsDrawTests.DrawTestSpec.Primitive.LINE_LOOP
530         ];
532         if (hasFirst) {
533             // First-tests
534             this.addChild(new es3fDrawTests.FirstGroup('first', 'First tests', this.m_method));
535         }
537         if (indexed) {
538             // Index-tests
539             if (this.m_method != glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED)
540                 this.addChild(new es3fDrawTests.IndexGroup('indices', 'Index tests', this.m_method));
541         }
543         for (var ndx = 0; ndx < primitive.length; ++ndx) {
544             var name = glsDrawTests.DrawTestSpec.primitiveToString(primitive[ndx]);
545             var desc = glsDrawTests.DrawTestSpec.primitiveToString(primitive[ndx]);
547             this.addChild(new es3fDrawTests.AttributeGroup(name, desc, this.m_method, primitive[ndx], glsDrawTests.DrawTestSpec.IndexType.SHORT, glsDrawTests.DrawTestSpec.Storage.BUFFER));
548         }
549     };
551     /**
552      * es3fDrawTests.GridProgram
553      * @constructor
554      * @extends {sglrShaderProgram.ShaderProgram}
555      */
556     es3fDrawTests.GridProgram = function() {
557         /** @type {sglrShaderProgram.ShaderProgramDeclaration} */ var decl = new sglrShaderProgram.ShaderProgramDeclaration();
559         decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
560         decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_offset', rrGenericVector.GenericVecType.FLOAT));
561         decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_color', rrGenericVector.GenericVecType.FLOAT));
563         decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
564         decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(rrGenericVector.GenericVecType.FLOAT));
566         decl.pushVertexSource(new sglrShaderProgram.VertexSource(
567             '#version 300 es\n' +
568             'in highp vec4 a_position;\n' +
569             'in highp vec4 a_offset;\n' +
570             'in highp vec4 a_color;\n' +
571             'out mediump vec4 v_color;\n' +
572             'void main(void)\n' +
573             '{\n' +
574             ' gl_Position = a_position + a_offset;\n' +
575             ' v_color = a_color;\n' +
576             '}\n'
577         ));
578         decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(
579             '#version 300 es\n' +
580             'layout(location = 0) out mediump vec4 dEQP_FragColor;\n' +
581             'in mediump vec4 v_color;\n' +
582             'void main(void)\n' +
583             '{\n' +
584             ' dEQP_FragColor = v_color;\n' +
585             '}\n'
586         ));
588         sglrShaderProgram.ShaderProgram.call(this, decl);
589     };
591     es3fDrawTests.GridProgram.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
592     es3fDrawTests.GridProgram.prototype.constructor = es3fDrawTests.GridProgram;
594     /**
595      * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
596      * @param {Array<rrVertexPacket.VertexPacket>} packets
597      * @param {number} numPackets
598      */
599     es3fDrawTests.GridProgram.prototype.shadeVertices = function(inputs, packets, numPackets) {
600         for (var ndx = 0; ndx < numPackets; ++ndx) {
601             packets[ndx].position = deMath.add(
602                 rrVertexAttrib.readVertexAttrib(inputs[0], packets[ndx].instanceNdx, packets[ndx].vertexNdx, rrGenericVector.GenericVecType.FLOAT),
603                 rrVertexAttrib.readVertexAttrib(inputs[1], packets[ndx].instanceNdx, packets[ndx].vertexNdx, rrGenericVector.GenericVecType.FLOAT)
604             );
605             packets[ndx].outputs[0] = rrVertexAttrib.readVertexAttrib(inputs[2], packets[ndx].instanceNdx, packets[ndx].vertexNdx, rrGenericVector.GenericVecType.FLOAT);
606         }
607     };
609     /**
610      * @param {Array<rrFragmentOperations.Fragment>} packets
611      * @param {rrShadingContext.FragmentShadingContext} context
612      */
613     es3fDrawTests.GridProgram.prototype.shadeFragments = function(packets, context) {
614         for (var packetNdx = 0; packetNdx < packets.length; ++packetNdx)
615         for (var fragNdx = 0; fragNdx < 4; ++fragNdx)
616             packets[packetNdx].value = rrShadingContext.readTriangleVarying(packets[packetNdx], context, fragNdx);
617     };
619     /**
620      * InstancedGridRenderTest
621      * @constructor
622      * @extends {tcuTestCase.DeqpTest}
623      * @param {string} name
624      * @param {string} desc
625      * @param {number} gridSide
626      * @param {boolean} useIndices
627      */
628     es3fDrawTests.InstancedGridRenderTest = function(name, desc, gridSide, useIndices) {
629         tcuTestCase.DeqpTest.call(this, name, desc);
630         this.m_gridSide = gridSide;
631         this.m_useIndices = useIndices;
632     };
634     es3fDrawTests.InstancedGridRenderTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
635     es3fDrawTests.InstancedGridRenderTest.prototype.constructor = es3fDrawTests.InstancedGridRenderTest;
637     /**
638      * iterate
639      * @return {tcuTestCase.IterateResult}
640      */
641     es3fDrawTests.InstancedGridRenderTest.prototype.iterate = function() {
642         var renderTargetWidth = Math.min(1024, gl.canvas.width);
643         var renderTargetHeight = Math.min(1024, gl.canvas.height);
645         /** @type {sglrGLContext.GLContext} */ var ctx = new sglrGLContext.GLContext(gl);
646         /** @type {tcuSurface.Surface} */ var surface = new tcuSurface.Surface(renderTargetWidth, renderTargetHeight);
647         /** @type {es3fDrawTests.GridProgram} */ var program = new es3fDrawTests.GridProgram();
649         // render
651         this.renderTo(ctx, program, surface);
653         // verify image
655         if (this.verifyImage(surface))
656             testPassed('');
657         else
658             testFailed('Incorrect rendering result');
659         return tcuTestCase.IterateResult.STOP;
660     };
662     /**
663      * @param {sglrGLContext.GLContext} ctx
664      * @param {sglrShaderProgram.ShaderProgram} program
665      * @param {tcuSurface.Surface} dst
666      */
667     es3fDrawTests.InstancedGridRenderTest.prototype.renderTo = function(ctx, program, dst) {
668         var green = [0, 1, 0, 1];
669         var yellow = [1, 1, 0, 1];
671         /** @type {WebGLBuffer} */ var positionBuf = null;
672         /** @type {WebGLBuffer} */ var offsetBuf = null;
673         /** @type {WebGLBuffer} */ var colorBuf = null;
674         /** @type {WebGLBuffer} */ var indexBuf = null;
675         /** @type {WebGLProgram} */ var programID = ctx.createProgram(program);
676         /** @type {number} */ var posLocation = ctx.getAttribLocation(/** @type {WebGLProgram} */ (programID), 'a_position');
677         /** @type {number} */ var offsetLocation = ctx.getAttribLocation(/** @type {WebGLProgram} */ (programID), 'a_offset');
678         /** @type {number} */ var colorLocation = ctx.getAttribLocation(/** @type {WebGLProgram} */ (programID), 'a_color');
680         var cellW = 2.0 / this.m_gridSide;
681         var cellH = 2.0 / this.m_gridSide;
682         var vertexPositions = new Float32Array([
683             0, 0, 0, 1,
684             cellW, 0, 0, 1,
685             0, cellH, 0, 1,
687             0, cellH, 0, 1,
688             cellW, 0, 0, 1,
689             cellW, cellH, 0, 1
690         ]);
692         var indices = new Uint16Array([
693             0, 4, 3,
694             2, 1, 5
695         ]);
697         var offsets = [];
698         for (var x = 0; x < this.m_gridSide; ++x)
699         for (var y = 0; y < this.m_gridSide; ++y) {
700             offsets.push(x * cellW - 1.0);
701             offsets.push(y * cellW - 1.0);
702             offsets.push(0, 0);
703         }
704         offsets = new Float32Array(offsets);
706         var colors = [];
707         for (var x = 0; x < this.m_gridSide; ++x)
708         for (var y = 0; y < this.m_gridSide; ++y) {
709             var colorToPush = ((x + y) % 2 == 0) ? (green) : (yellow);
710             colors.push(colorToPush[0]);
711             colors.push(colorToPush[1]);
712             colors.push(colorToPush[2]);
713             colors.push(colorToPush[3]);
714         }
715         colors = new Float32Array(colors);
717         positionBuf = ctx.createBuffer();
718         ctx.bindBuffer(gl.ARRAY_BUFFER, positionBuf);
719         ctx.bufferData(gl.ARRAY_BUFFER, vertexPositions, gl.STATIC_DRAW);
720         ctx.vertexAttribPointer(posLocation, 4, gl.FLOAT, false, 0, 0);
721         ctx.vertexAttribDivisor(posLocation, 0);
722         ctx.enableVertexAttribArray(posLocation);
724         offsetBuf = ctx.createBuffer();
725         ctx.bindBuffer(gl.ARRAY_BUFFER, offsetBuf);
726         ctx.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
727         ctx.vertexAttribPointer(offsetLocation, 4, gl.FLOAT, false, 0, 0);
728         ctx.vertexAttribDivisor(offsetLocation, 1);
729         ctx.enableVertexAttribArray(offsetLocation);
731         colorBuf = ctx.createBuffer();
732         ctx.bindBuffer(gl.ARRAY_BUFFER, colorBuf);
733         ctx.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
734         ctx.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);
735         ctx.vertexAttribDivisor(colorLocation, 1);
736         ctx.enableVertexAttribArray(colorLocation);
738         if (this.m_useIndices) {
739             indexBuf = ctx.createBuffer();
740             ctx.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuf);
741             ctx.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
742         }
744         ctx.clearColor(0, 0, 0, 1);
745         ctx.clear(gl.COLOR_BUFFER_BIT);
747         ctx.viewport(0, 0, dst.getWidth(), dst.getHeight());
749         ctx.useProgram(programID);
750         if (this.m_useIndices)
751             ctx.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, this.m_gridSide * this.m_gridSide);
752         else
753             ctx.drawArraysInstanced(gl.TRIANGLES, 0, 6, this.m_gridSide * this.m_gridSide);
754         ctx.useProgram(null);
756         if (this.m_useIndices)
757             ctx.deleteBuffer(indexBuf);
758         ctx.deleteBuffer(colorBuf);
759         ctx.deleteBuffer(offsetBuf);
760         ctx.deleteBuffer(positionBuf);
761         ctx.deleteProgram(programID);
763         ctx.finish();
764         dst.readViewport(ctx, [0 , 0, dst.getWidth(), dst.getHeight()]);
765     };
767     /**
768      * @param {tcuSurface.Surface} image
769      * @return {boolean}
770      */
771     es3fDrawTests.InstancedGridRenderTest.prototype.verifyImage = function(image) {
772         // \note the green/yellow pattern is only for clarity. The test will only verify that all instances were drawn by looking for anything non-green/yellow.
774         var green = [0, 255, 0, 255];
775         var yellow = [255, 255, 0, 255];
776         var colorThreshold = 20;
778         /** @type {tcuSurface.Surface} */ var error = new tcuSurface.Surface(image.getWidth(), image.getHeight());
779         var isOk = true;
781         for (var y = 1; y < image.getHeight() - 1; y++)
782         for (var x = 1; x < image.getWidth() - 1; x++) {
783             /** @type {tcuRGBA.RGBA} */ var pixel = new tcuRGBA.RGBA(image.getPixel(x, y));
784             var pixelOk = true;
786             // Any pixel with !(G ~= 255) is faulty (not a linear combinations of green and yellow)
787             if (Math.abs(pixel.getGreen() - 255) > colorThreshold)
788                 pixelOk = false;
790             // Any pixel with !(B ~= 0) is faulty (not a linear combinations of green and yellow)
791             if (Math.abs(pixel.getBlue() - 0) > colorThreshold)
792                 pixelOk = false;
794             error.setPixel(x, y, pixelOk ? [0, 255, 0, 255] : [255, 0, 0, 255]);
795             isOk = isOk && pixelOk;
796         }
798         if (!isOk) {
799             bufferedLogToConsole('Image verification failed.');
800             debug('Verfication result');
801             tcuLogImage.logImageWithInfo(image.getAccess(), 'Result');
802             tcuLogImage.logImageWithInfo(error.getAccess(), 'Error mask');
803         } else {
804             debug('Verfication result');
805         }
807         return isOk;
808     };
810     /**
811      * InstancingGroup
812      * @constructor
813      * @extends {tcuTestCase.DeqpTest}
814      */
815     es3fDrawTests.InstancingGroup = function(name, descr) {
816         tcuTestCase.DeqpTest.call(this, name, descr);
817         this.makeExecutable();
818     };
820     es3fDrawTests.InstancingGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
821     es3fDrawTests.InstancingGroup.prototype.constructor = es3fDrawTests.InstancingGroup;
823     /**
824      * init
825      */
826     es3fDrawTests.InstancingGroup.prototype.init = function() {
827         var gridWidths = [
828             2,
829             5,
830             10,
831             32,
832             100
833         ];
835         // drawArrays
836         for (var ndx = 0; ndx < gridWidths.length; ++ndx) {
837             var name = 'draw_arrays_instanced_grid_' + gridWidths[ndx] + 'x' + gridWidths[ndx];
838             var desc = 'DrawArraysInstanced, Grid size ' + gridWidths[ndx] + 'x' + gridWidths[ndx];
840             this.addChild(new es3fDrawTests.InstancedGridRenderTest(name, desc, gridWidths[ndx], false));
841         }
843         // drawElements
844         for (var ndx = 0; ndx < gridWidths.length; ++ndx) {
845             var name = 'draw_elements_instanced_grid_' + gridWidths[ndx] + 'x' + gridWidths[ndx];
846             var desc = 'DrawElementsInstanced, Grid size ' + gridWidths[ndx] + 'x' + gridWidths[ndx];
848             this.addChild(new es3fDrawTests.InstancedGridRenderTest(name, desc, gridWidths[ndx], true));
849         }
850     };
852     /**
853      * @constructor
854      * @param {number} size
855      */
856     es3fDrawTests.UniformWeightArray = function(size) {
857         this.weights = [];
859         for (var i = 0; i < size; ++i)
860             this.weights[i] = 1.0;
861     };
863     /**
864      * RandomGroup
865      * @constructor
866      * @extends {tcuTestCase.DeqpTest}
867      * @param {string} name
868      * @param {string} descr
869      */
870     es3fDrawTests.RandomGroup = function(name, descr) {
871         tcuTestCase.DeqpTest.call(this, name, descr);
872         this.makeExecutable();
873     };
875     es3fDrawTests.RandomGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
876     es3fDrawTests.RandomGroup.prototype.constructor = es3fDrawTests.RandomGroup;
878     /**
879      * init
880      */
881     es3fDrawTests.RandomGroup.prototype.init = function() {
882         /** @type {number} */ var numAttempts = 300;
884         /** @type {Array<number>} */ var attribCounts = [1, 2, 5];
885         /** @type {Array<number>} */ var attribWeights = [30, 10, 1];
886         /** @type {Array<number>} */ var primitiveCounts = [2, 6, 64];
887         /** @type {Array<number>} */ var primitiveCountWeights = [20, 10, 1];
888         /** @type {Array<number>} */ var indexOffsets = [0, 7, 13];
889         /** @type {Array<number>} */ var indexOffsetWeights = [20, 20, 1];
890         /** @type {Array<number>} */ var firsts = [0, 6, 12];
891         /** @type {Array<number>} */ var firstWeights = [20, 20, 1];
892         /** @type {Array<number>} */ var instanceCounts = [1, 2, 16, 17];
893         /** @type {Array<number>} */ var instanceWeights = [20, 10, 5, 1];
894         /** @type {Array<number>} */ var indexMins = [0, 1, 3, 9];
895         /** @type {Array<number>} */ var indexMaxs = [5, 9, 129, 257];
896         /** @type {Array<number>} */ var indexWeights = [50, 50, 50, 50];
897         /** @type {Array<number>} */ var offsets = [0, 1, 5, 12];
898         /** @type {Array<number>} */ var offsetWeights = [50, 10, 10, 10];
899         /** @type {Array<number>} */ var strides = [0, 7, 16, 17];
900         /** @type {Array<number>} */ var strideWeights = [50, 10, 10, 10];
901         /** @type {Array<number>} */ var instanceDivisors = [0, 1, 3, 129];
902         /** @type {Array<number>} */ var instanceDivisorWeights = [70, 30, 10, 10];
904         /** @type {Array<glsDrawTests.DrawTestSpec.Primitive>} */ var primitives = [
905             glsDrawTests.DrawTestSpec.Primitive.POINTS,
906             glsDrawTests.DrawTestSpec.Primitive.TRIANGLES,
907             glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_FAN,
908             glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_STRIP,
909             glsDrawTests.DrawTestSpec.Primitive.LINES,
910             glsDrawTests.DrawTestSpec.Primitive.LINE_STRIP,
911             glsDrawTests.DrawTestSpec.Primitive.LINE_LOOP
912         ];
913         /** @type {es3fDrawTests.UniformWeightArray} */ var primitiveWeights = new es3fDrawTests.UniformWeightArray(primitives.length);
915         /** @type {Array<glsDrawTests.DrawTestSpec.DrawMethod>} */ var drawMethods = [
916             glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS,
917             glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS_INSTANCED,
918             glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS,
919             glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED,
920             glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_INSTANCED
921         ];
922         /** @type {es3fDrawTests.UniformWeightArray} */ var drawMethodWeights = new es3fDrawTests.UniformWeightArray(drawMethods.length);
924         /** @type {Array<glsDrawTests.DrawTestSpec.IndexType>} */ var indexTypes = [
925             glsDrawTests.DrawTestSpec.IndexType.BYTE,
926             glsDrawTests.DrawTestSpec.IndexType.SHORT,
927             glsDrawTests.DrawTestSpec.IndexType.INT
928         ];
929         /** @type {es3fDrawTests.UniformWeightArray} */ var indexTypeWeights = new es3fDrawTests.UniformWeightArray(indexTypes.length);
931         /** @type {Array<glsDrawTests.DrawTestSpec.Storage>} */ var storages = [
932             //glsDrawTests.DrawTestSpec.Storage.USER,
933             glsDrawTests.DrawTestSpec.Storage.BUFFER
934         ];
935         /** @type {es3fDrawTests.UniformWeightArray} */ var storageWeights = new es3fDrawTests.UniformWeightArray(storages.length);
937         /** @type {Array<glsDrawTests.DrawTestSpec.InputType>} */ var inputTypes = [
938             glsDrawTests.DrawTestSpec.InputType.FLOAT,
939             //glsDrawTests.DrawTestSpec.InputType.FIXED,
940             glsDrawTests.DrawTestSpec.InputType.BYTE,
941             glsDrawTests.DrawTestSpec.InputType.SHORT,
942             glsDrawTests.DrawTestSpec.InputType.UNSIGNED_BYTE,
943             glsDrawTests.DrawTestSpec.InputType.UNSIGNED_SHORT,
944             glsDrawTests.DrawTestSpec.InputType.INT,
945             glsDrawTests.DrawTestSpec.InputType.UNSIGNED_INT,
946             glsDrawTests.DrawTestSpec.InputType.HALF,
947             glsDrawTests.DrawTestSpec.InputType.UNSIGNED_INT_2_10_10_10,
948             glsDrawTests.DrawTestSpec.InputType.INT_2_10_10_10
949         ];
950         /** @type {es3fDrawTests.UniformWeightArray} */ var inputTypeWeights = new es3fDrawTests.UniformWeightArray(inputTypes.length);
952         /** @type {Array<glsDrawTests.DrawTestSpec.OutputType>} */ var outputTypes = [
953             glsDrawTests.DrawTestSpec.OutputType.FLOAT,
954             glsDrawTests.DrawTestSpec.OutputType.VEC2,
955             glsDrawTests.DrawTestSpec.OutputType.VEC3,
956             glsDrawTests.DrawTestSpec.OutputType.VEC4,
957             glsDrawTests.DrawTestSpec.OutputType.INT,
958             glsDrawTests.DrawTestSpec.OutputType.UINT,
959             glsDrawTests.DrawTestSpec.OutputType.IVEC2,
960             glsDrawTests.DrawTestSpec.OutputType.IVEC3,
961             glsDrawTests.DrawTestSpec.OutputType.IVEC4,
962             glsDrawTests.DrawTestSpec.OutputType.UVEC2,
963             glsDrawTests.DrawTestSpec.OutputType.UVEC3,
964             glsDrawTests.DrawTestSpec.OutputType.UVEC4
965         ];
966         /** @type {es3fDrawTests.UniformWeightArray} */ var outputTypeWeights = new es3fDrawTests.UniformWeightArray(outputTypes.length);
968         /** @type {Array<glsDrawTests.DrawTestSpec.Usage>} */ var usages = [
969             glsDrawTests.DrawTestSpec.Usage.DYNAMIC_DRAW,
970             glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW,
971             glsDrawTests.DrawTestSpec.Usage.STREAM_DRAW,
972             glsDrawTests.DrawTestSpec.Usage.STREAM_READ,
973             glsDrawTests.DrawTestSpec.Usage.STREAM_COPY,
974             glsDrawTests.DrawTestSpec.Usage.STATIC_READ,
975             glsDrawTests.DrawTestSpec.Usage.STATIC_COPY,
976             glsDrawTests.DrawTestSpec.Usage.DYNAMIC_READ,
977             glsDrawTests.DrawTestSpec.Usage.DYNAMIC_COPY
978         ];
979         /** @type {es3fDrawTests.UniformWeightArray} */ var usageWeights = new es3fDrawTests.UniformWeightArray(usages.length);
981         /** @type {Array<number>} */ var insertedHashes = []; //'set' structure
982         /** @type {number} */ var insertedCount = 0;
984         for (var ndx = 0; ndx < numAttempts; ++ndx) {
985             /** @type {deRandom.Random} */ var random = new deRandom.Random(0xc551393 + ndx); // random does not depend on previous cases
987             /** @type {number} */ var attributeCount = random.chooseWeighted(attribCounts, attribWeights);
988             /** @type {glsDrawTests.DrawTestSpec} */ var spec = new glsDrawTests.DrawTestSpec();
990             //spec.apiType = glu::ApiType::es(3,0);
991             spec.primitive = /** @type {glsDrawTests.DrawTestSpec.Primitive} */ (random.chooseWeighted(primitives, primitiveWeights.weights));
992             spec.primitiveCount = random.chooseWeighted(primitiveCounts, primitiveCountWeights);
993             spec.drawMethod = /** @type {glsDrawTests.DrawTestSpec.DrawMethod} */ (random.chooseWeighted(drawMethods, drawMethodWeights.weights));
994             spec.indexType = /** @type {glsDrawTests.DrawTestSpec.IndexType} */ (random.chooseWeighted(indexTypes, indexTypeWeights.weights));
995             spec.indexPointerOffset = random.chooseWeighted(indexOffsets, indexOffsetWeights);
996             spec.indexStorage = /** @type {glsDrawTests.DrawTestSpec.Storage} */ (random.chooseWeighted(storages, storageWeights.weights));
997             spec.first = random.chooseWeighted(firsts, firstWeights);
998             spec.indexMin = random.chooseWeighted(indexMins, indexWeights);
999             spec.indexMax = random.chooseWeighted(indexMaxs, indexWeights);
1000             spec.instanceCount = random.chooseWeighted(instanceCounts, instanceWeights);
1002             // check spec is legal
1003             if (!spec.valid())
1004                 continue;
1006             var hasZeroDivisor = false;
1007             for (var attrNdx = 0; attrNdx < attributeCount;) {
1008                 /** @type {boolean} */ var valid;
1009                 /** @type {glsDrawTests.DrawTestSpec.AttributeSpec} */ var attribSpec = new glsDrawTests.DrawTestSpec.AttributeSpec();
1011                 attribSpec.inputType = /** @type {glsDrawTests.DrawTestSpec.InputType} */ (random.chooseWeighted(inputTypes, inputTypeWeights.weights));
1012                 attribSpec.outputType = /** @type {glsDrawTests.DrawTestSpec.OutputType} */ (random.chooseWeighted(outputTypes, outputTypeWeights.weights));
1013                 attribSpec.storage = /** @type {glsDrawTests.DrawTestSpec.Storage} */ (random.chooseWeighted(storages, storageWeights.weights));
1014                 attribSpec.usage = /** @type {glsDrawTests.DrawTestSpec.Usage} */ (random.chooseWeighted(usages, usageWeights.weights));
1015                 attribSpec.componentCount = random.getInt(1, 4);
1016                 attribSpec.offset = random.chooseWeighted(offsets, offsetWeights);
1017                 attribSpec.stride = random.chooseWeighted(strides, strideWeights);
1018                 attribSpec.normalize = random.getBool();
1019                 attribSpec.instanceDivisor = random.chooseWeighted(instanceDivisors, instanceDivisorWeights);
1020                 attribSpec.useDefaultAttribute = random.getBool();
1022                 // check spec is legal
1023                 valid = attribSpec.valid(/*spec.apiType*/);
1025                 // we do not want interleaved elements. (Might result in some weird floating point values)
1026                 if (attribSpec.stride && attribSpec.componentCount * glsDrawTests.DrawTestSpec.inputTypeSize(attribSpec.inputType) > attribSpec.stride)
1027                     valid = false;
1029                 // try again if not valid
1030                 if (valid) {
1031                     spec.attribs.push(attribSpec);
1032                     ++attrNdx;
1033                     if (attribSpec.instanceDivisor == 0)
1034                         hasZeroDivisor = true;
1035                 }
1036             }
1038             // Do not collapse all vertex positions to a single positions
1039             if (spec.primitive != glsDrawTests.DrawTestSpec.Primitive.POINTS) {
1040                 spec.attribs[0].instanceDivisor = 0;
1041                 hasZeroDivisor = true;
1042             }
1044             // There should be at least one enabled vertex attribute array that has a divisor of zero in WebGL.
1045             // This limitation is added to keep compatible with D3D. It differs from the feature in gles.
1046             // See the section <Enabled Attribute> in WebGL spec: https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.6
1047             if (hasZeroDivisor == false)
1048                 continue;
1050             // Is render result meaningful?
1051             // Only one vertex
1052             if (spec.drawMethod == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED && spec.indexMin == spec.indexMax && spec.primitive != glsDrawTests.DrawTestSpec.Primitive.POINTS)
1053                 continue;
1054             if (spec.attribs[0].useDefaultAttribute && spec.primitive != glsDrawTests.DrawTestSpec.Primitive.POINTS)
1055                 continue;
1057             // Triangle only on one axis
1058             if (spec.primitive == glsDrawTests.DrawTestSpec.Primitive.TRIANGLES || spec.primitive == glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_FAN || spec.primitive == glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_STRIP) {
1059                 if (spec.attribs[0].componentCount == 1)
1060                     continue;
1061                 if (spec.attribs[0].outputType == glsDrawTests.DrawTestSpec.OutputType.FLOAT || spec.attribs[0].outputType == glsDrawTests.DrawTestSpec.OutputType.INT || spec.attribs[0].outputType == glsDrawTests.DrawTestSpec.OutputType.UINT)
1062                     continue;
1063                 if (spec.drawMethod == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED && (spec.indexMax - spec.indexMin) < 2)
1064                     continue;
1065             }
1067             // Add case
1068             /** @type {number} */ var hash = spec.hash();
1069             for (var attrNdx = 0; attrNdx < attributeCount; ++attrNdx)
1070                 hash = deMath.binaryOp(deMath.shiftLeft(hash, 2), spec.attribs[attrNdx].hash(), deMath.BinaryOp.XOR);
1072             if (insertedHashes.indexOf(hash) == -1) {
1073                 // Only properly aligned
1074                 if (spec.isCompatibilityTest() != glsDrawTests.DrawTestSpec.CompatibilityTestType.UNALIGNED_OFFSET &&
1075                     spec.isCompatibilityTest() != glsDrawTests.DrawTestSpec.CompatibilityTestType.UNALIGNED_STRIDE) {
1076                     this.addChild(new glsDrawTests.DrawTest(spec, insertedCount + '', spec.getDesc()));
1077                 }
1078                 deUtil.dePushUniqueToArray(insertedHashes, hash);
1080                 ++insertedCount;
1081             }
1082         }
1083     };
1085     /**
1086      * @constructor
1087      * @extends {tcuTestCase.DeqpTest}
1088      */
1089     es3fDrawTests.DrawTest = function() {
1090         tcuTestCase.DeqpTest.call(this, 'draw', 'Drawing tests');
1091         this.makeExecutable();
1092     };
1094     es3fDrawTests.DrawTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
1095     es3fDrawTests.DrawTest.prototype.constructor = es3fDrawTests.DrawTest;
1097     /**
1098      * init
1099      */
1100     es3fDrawTests.DrawTest.prototype.init = function() {
1101         // Basic
1102         /** @type {Array<glsDrawTests.DrawTestSpec.DrawMethod>} */ var basicMethods = [
1103             glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS,
1104             glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS,
1105             glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS_INSTANCED,
1106             glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_INSTANCED,
1107             glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED
1108         ];
1110         for (var ndx = 0; ndx < basicMethods.length; ++ndx) {
1111             var name = glsDrawTests.DrawTestSpec.drawMethodToString(basicMethods[ndx]);
1112             var desc = glsDrawTests.DrawTestSpec.drawMethodToString(basicMethods[ndx]);
1114             this.addChild(new es3fDrawTests.MethodGroup(name, desc, basicMethods[ndx]));
1115         }
1117         // extreme instancing
1119         this.addChild(new es3fDrawTests.InstancingGroup('instancing', 'draw tests with a large instance count.'));
1121         // Random
1123         this.addChild(new es3fDrawTests.RandomGroup('random', 'random draw commands.'));
1124     };
1126     /**
1127      * Create and execute the test cases
1128      * @param {WebGL2RenderingContext} context
1129      */
1130     es3fDrawTests.run = function(context, range) {
1131         gl = context;
1132         //Set up Test Root parameters
1133         var state = tcuTestCase.runner;
1135         var rootTest = new es3fDrawTests.DrawTest();
1136         state.setRoot(rootTest);
1138         //Set up name and description of this test series.
1139         setCurrentTestName(rootTest.fullName());
1140         description(rootTest.getDescription());
1142         try {
1143             if (range) {
1144                 state.setRange(range);
1145             }
1146             //Run test cases
1147             tcuTestCase.runTestCases();
1148         }
1149         catch (err) {
1150             testFailedOptions('Failed to run draw tests', false);
1151             tcuTestCase.runner.terminate();
1152         }
1153     };