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('modules.shared.glsDrawTests');
23 goog
.require('framework.common.tcuFloat');
24 goog
.require('framework.common.tcuImageCompare');
25 goog
.require('framework.common.tcuPixelFormat');
26 goog
.require('framework.common.tcuRGBA');
27 goog
.require('framework.common.tcuSurface');
28 goog
.require('framework.common.tcuTestCase');
29 goog
.require('framework.common.tcuTextureUtil');
30 goog
.require('framework.delibs.debase.deMath');
31 goog
.require('framework.delibs.debase.deRandom');
32 goog
.require('framework.opengl.gluShaderUtil');
33 goog
.require('framework.opengl.gluStrUtil');
34 goog
.require('framework.opengl.simplereference.sglrGLContext');
35 goog
.require('framework.opengl.simplereference.sglrReferenceContext');
36 goog
.require('framework.opengl.simplereference.sglrShaderProgram');
37 goog
.require('framework.referencerenderer.rrFragmentOperations');
38 goog
.require('framework.referencerenderer.rrGenericVector');
39 goog
.require('framework.referencerenderer.rrShadingContext');
40 goog
.require('framework.referencerenderer.rrVertexAttrib');
41 goog
.require('framework.referencerenderer.rrVertexPacket');
43 goog
.scope(function() {
45 var glsDrawTests
= modules
.shared
.glsDrawTests
;
46 var tcuTestCase
= framework
.common
.tcuTestCase
;
47 var tcuRGBA
= framework
.common
.tcuRGBA
;
48 var tcuFloat
= framework
.common
.tcuFloat
;
49 var tcuPixelFormat
= framework
.common
.tcuPixelFormat
;
50 var tcuSurface
= framework
.common
.tcuSurface
;
51 var tcuImageCompare
= framework
.common
.tcuImageCompare
;
52 var tcuTextureUtil
= framework
.common
.tcuTextureUtil
;
53 var gluShaderUtil
= framework
.opengl
.gluShaderUtil
;
54 var gluStrUtil
= framework
.opengl
.gluStrUtil
;
55 var sglrGLContext
= framework
.opengl
.simplereference
.sglrGLContext
;
56 var sglrReferenceContext
= framework
.opengl
.simplereference
.sglrReferenceContext
;
57 var sglrShaderProgram
= framework
.opengl
.simplereference
.sglrShaderProgram
;
58 var deMath
= framework
.delibs
.debase
.deMath
;
59 var deRandom
= framework
.delibs
.debase
.deRandom
;
60 var rrFragmentOperations
= framework
.referencerenderer
.rrFragmentOperations
;
61 var rrGenericVector
= framework
.referencerenderer
.rrGenericVector
;
62 var rrShadingContext
= framework
.referencerenderer
.rrShadingContext
;
63 var rrVertexAttrib
= framework
.referencerenderer
.rrVertexAttrib
;
64 var rrVertexPacket
= framework
.referencerenderer
.rrVertexPacket
;
66 /** @const {number} */ glsDrawTests
.MAX_RENDER_TARGET_SIZE
= 512;
71 * @param {glsDrawTests.DrawTestSpec.Target} target
74 glsDrawTests
.targetToGL = function(target
) {
75 assertMsgOptions(target
!= null, 'Target is null', false, true);
78 gl
.ELEMENT_ARRAY_BUFFER
, // TARGET_ELEMENT_ARRAY = 0,
79 gl
.ARRAY_BUFFER
// TARGET_ARRAY,
82 return targets
[target
];
86 * @param {?glsDrawTests.DrawTestSpec.Usage} usage
89 glsDrawTests
.usageToGL = function(usage
) {
90 assertMsgOptions(usage
!= null, 'Usage is null', false, true);
93 gl
.DYNAMIC_DRAW
, // USAGE_DYNAMIC_DRAW = 0,
94 gl
.STATIC_DRAW
, // USAGE_STATIC_DRAW,
95 gl
.STREAM_DRAW
, // USAGE_STREAM_DRAW,
97 gl
.STREAM_READ
, // USAGE_STREAM_READ,
98 gl
.STREAM_COPY
, // USAGE_STREAM_COPY,
100 gl
.STATIC_READ
, // USAGE_STATIC_READ,
101 gl
.STATIC_COPY
, // USAGE_STATIC_COPY,
103 gl
.DYNAMIC_READ
, // USAGE_DYNAMIC_READ,
104 gl
.DYNAMIC_COPY
// USAGE_DYNAMIC_COPY,
106 assertMsgOptions(usages
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.Usage
).length
,
107 'Amount of usage gl vlaues is different from amount of usages', false, true);
109 return usages
[usage
];
113 * @param {?glsDrawTests.DrawTestSpec.InputType} type
116 glsDrawTests
.inputTypeToGL = function(type
) {
117 assertMsgOptions(type
!= null, 'Input type is null', false, true);
120 gl
.FLOAT
, // INPUTTYPE_FLOAT = 0,
121 gl
.BYTE
, // INPUTTYPE_BYTE,
122 gl
.SHORT
, // INPUTTYPE_SHORT,
123 gl
.UNSIGNED_BYTE
, // INPUTTYPE_UNSIGNED_BYTE,
124 gl
.UNSIGNED_SHORT
, // INPUTTYPE_UNSIGNED_SHORT,
126 gl
.INT
, // INPUTTYPE_INT,
127 gl
.UNSIGNED_INT
, // INPUTTYPE_UNSIGNED_INT,
128 gl
.HALF_FLOAT
, // INPUTTYPE_HALF,
129 gl
.UNSIGNED_INT_2_10_10_10_REV
, // INPUTTYPE_UNSIGNED_INT_2_10_10_10,
130 gl
.INT_2_10_10_10_REV
// INPUTTYPE_INT_2_10_10_10,
132 assertMsgOptions(types
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.InputType
).length
,
133 'Amount of gl input types is different from amount of input types', false, true);
139 * @param {?glsDrawTests.DrawTestSpec.OutputType} type
142 glsDrawTests
.outputTypeToGLType = function(type
) {
143 assertMsgOptions(type
!= null, 'Output type is null', false, true);
146 'float', // OUTPUTTYPE_FLOAT = 0,
147 'vec2', // OUTPUTTYPE_VEC2,
148 'vec3', // OUTPUTTYPE_VEC3,
149 'vec4', // OUTPUTTYPE_VEC4,
151 'int', // OUTPUTTYPE_INT,
152 'uint', // OUTPUTTYPE_UINT,
154 'ivec2', // OUTPUTTYPE_IVEC2,
155 'ivec3', // OUTPUTTYPE_IVEC3,
156 'ivec4', // OUTPUTTYPE_IVEC4,
158 'uvec2', // OUTPUTTYPE_UVEC2,
159 'uvec3', // OUTPUTTYPE_UVEC3,
160 'uvec4' // OUTPUTTYPE_UVEC4,
162 assertMsgOptions(types
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.OutputType
).length
,
163 'Amount of output type names is different than amount of output types', false, true);
169 * @param {?glsDrawTests.DrawTestSpec.Primitive} primitive
172 glsDrawTests
.primitiveToGL = function(primitive
) {
174 gl
.POINTS
, // PRIMITIVE_POINTS = 0,
175 gl
.TRIANGLES
, // PRIMITIVE_TRIANGLES,
176 gl
.TRIANGLE_FAN
, // PRIMITIVE_TRIANGLE_FAN,
177 gl
.TRIANGLE_STRIP
, // PRIMITIVE_TRIANGLE_STRIP,
178 gl
.LINES
, // PRIMITIVE_LINES
179 gl
.LINE_STRIP
, // PRIMITIVE_LINE_STRIP
182 assertMsgOptions(primitives
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.Primitive
).length
,
183 'Amount of gl primitive values is different than amount of primitives', false, true);
185 return primitives
[primitive
];
189 * @param {?glsDrawTests.DrawTestSpec.IndexType} indexType
192 glsDrawTests
.indexTypeToGL = function(indexType
) {
194 gl
.UNSIGNED_BYTE
, // INDEXTYPE_BYTE = 0,
195 gl
.UNSIGNED_SHORT
, // INDEXTYPE_SHORT,
196 gl
.UNSIGNED_INT
// INDEXTYPE_INT,
198 assertMsgOptions(indexTypes
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.IndexType
).length
,
199 'Amount of gl index types is different than amount of index types', false, true);
201 return indexTypes
[indexType
];
205 * @param {?glsDrawTests.DrawTestSpec.IndexType} indexType
206 * @return {?glsDrawTests.DrawTestSpec.InputType}
208 glsDrawTests
.indexTypeToInputType = function(indexType
) {
210 glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_BYTE
, // INDEXTYPE_BYTE = 0,
211 glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_SHORT
, // INDEXTYPE_SHORT,
212 glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT
// INDEXTYPE_INT,
214 assertMsgOptions(inputTypes
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.IndexType
).length
,
215 'Amount of relevant input types is different than amount of index types', false, true);
217 return inputTypes
[indexType
];
221 * @param {?glsDrawTests.DrawTestSpec.InputType} type
224 glsDrawTests
.inputTypeIsFloatType = function(type
) {
225 if (type
== glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
)
227 if (type
== glsDrawTests
.DrawTestSpec
.InputType
.HALF
)
233 * @param {?glsDrawTests.DrawTestSpec.OutputType} type
236 glsDrawTests
.outputTypeIsFloatType = function(type
) {
237 if (type
== glsDrawTests
.DrawTestSpec
.OutputType
.FLOAT
||
238 type
== glsDrawTests
.DrawTestSpec
.OutputType
.VEC2
||
239 type
== glsDrawTests
.DrawTestSpec
.OutputType
.VEC3
||
240 type
== glsDrawTests
.DrawTestSpec
.OutputType
.VEC4
)
247 * @param {?glsDrawTests.DrawTestSpec.OutputType} type
250 glsDrawTests
.outputTypeIsIntType = function(type
) {
251 if (type
== glsDrawTests
.DrawTestSpec
.OutputType
.INT
||
252 type
== glsDrawTests
.DrawTestSpec
.OutputType
.IVEC2
||
253 type
== glsDrawTests
.DrawTestSpec
.OutputType
.IVEC3
||
254 type
== glsDrawTests
.DrawTestSpec
.OutputType
.IVEC4
)
261 * @param {?glsDrawTests.DrawTestSpec.OutputType} type
264 glsDrawTests
.outputTypeIsUintType = function(type
) {
265 if (type
== glsDrawTests
.DrawTestSpec
.OutputType
.UINT
||
266 type
== glsDrawTests
.DrawTestSpec
.OutputType
.UVEC2
||
267 type
== glsDrawTests
.DrawTestSpec
.OutputType
.UVEC3
||
268 type
== glsDrawTests
.DrawTestSpec
.OutputType
.UVEC4
)
275 * @param {?glsDrawTests.DrawTestSpec.Primitive} primitive
276 * @param {number} primitiveCount
279 glsDrawTests
.getElementCount = function(primitive
, primitiveCount
) {
281 case glsDrawTests
.DrawTestSpec
.Primitive
.POINTS
: return primitiveCount
;
282 case glsDrawTests
.DrawTestSpec
.Primitive
.TRIANGLES
: return primitiveCount
* 3;
283 case glsDrawTests
.DrawTestSpec
.Primitive
.TRIANGLE_FAN
: return primitiveCount
+ 2;
284 case glsDrawTests
.DrawTestSpec
.Primitive
.TRIANGLE_STRIP
: return primitiveCount
+ 2;
285 case glsDrawTests
.DrawTestSpec
.Primitive
.LINES
: return primitiveCount
* 2;
286 case glsDrawTests
.DrawTestSpec
.Primitive
.LINE_STRIP
: return primitiveCount
+ 1;
287 case glsDrawTests
.DrawTestSpec
.Primitive
.LINE_LOOP
: return (primitiveCount
== 1) ? (2) : (primitiveCount
);
289 throw new Error('Invalid primitive');
296 * @typedef {{indexed: boolean, instanced: boolean, ranged: boolean, first: boolean}}
298 glsDrawTests
.MethodInfo
= {
299 /** @type {boolean} */ indexed
: false,
300 /** @type {boolean} */ instanced
: false,
301 /** @type {boolean} */ ranged
: false,
302 /** @type {boolean} */ first
: false
306 * @param {?glsDrawTests.DrawTestSpec.DrawMethod} method
307 * @return {glsDrawTests.MethodInfo}
309 glsDrawTests
.getMethodInfo = function(method
) {
310 /** @type {Array<glsDrawTests.MethodInfo>} */ var infos
= [{
311 indexed
: false, instanced
: false, ranged
: false, first
: true //!< DRAWMETHOD_DRAWARRAYS,
313 indexed
: false, instanced
: true, ranged
: false, first
: true //!< DRAWMETHOD_DRAWARRAYS_INSTANCED,
315 indexed
: true, instanced
: false, ranged
: false, first
: false //!< DRAWMETHOD_DRAWELEMENTS,
317 indexed
: true, instanced
: false, ranged
: true, first
: false //!< DRAWMETHOD_DRAWELEMENTS_RANGED,
319 indexed
: true, instanced
: true, ranged
: false, first
: false //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED
323 assertMsgOptions(infos
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.DrawMethod
).length
,
324 'Number of info names', false, true);
325 assertMsgOptions(method
< infos
.length
, 'Invalid method', false, true);
326 return /** @type {glsDrawTests.MethodInfo} */ (infos
[method
]);
330 * @param {glsDrawTests.DrawTestSpec} a
331 * @param {glsDrawTests.DrawTestSpec} b
334 glsDrawTests
.checkSpecsShaderCompatible = function(a
, b
) {
335 // Only the attributes matter
336 if (a
.attribs
.length
!= b
.attribs
.length
)
339 for (var ndx
= 0; ndx
< a
.attribs
.length
; ++ndx
) {
340 // Only the output type (== shader input type) matters and the usage in the shader.
342 if (a
.attribs
[ndx
].additionalPositionAttribute
!= b
.attribs
[ndx
].additionalPositionAttribute
)
345 // component counts need not to match
346 if (glsDrawTests
.outputTypeIsFloatType(a
.attribs
[ndx
].outputType
) && glsDrawTests
.outputTypeIsFloatType(b
.attribs
[ndx
].outputType
))
348 if (glsDrawTests
.outputTypeIsIntType(a
.attribs
[ndx
].outputType
) && glsDrawTests
.outputTypeIsIntType(b
.attribs
[ndx
].outputType
))
350 if (glsDrawTests
.outputTypeIsUintType(a
.attribs
[ndx
].outputType
) && glsDrawTests
.outputTypeIsUintType(b
.attribs
[ndx
].outputType
))
359 // generate random vectors in a way that does not depend on argument evaluation order
362 * @param {deRandom.Random} random
363 * @return {Array<number>}
365 glsDrawTests
.generateRandomVec4 = function(random
) {
366 /** @type {Array<number>} */ var retVal
= [];
368 for (var i
= 0; i
< 4; ++i
)
369 retVal
[i
] = random
.getFloat();
375 * @param {deRandom.Random} random
376 * @return {Array<number>}
378 glsDrawTests
.generateRandomIVec4 = function(random
) {
379 /** @type {Array<number>} */ var retVal
= [];
381 for (var i
= 0; i
< 4; ++i
)
382 retVal
[i
] = random
.getInt();
388 * @param {deRandom.Random} random
389 * @return {Array<number>}
391 glsDrawTests
.generateRandomUVec4 = function(random
) {
392 /** @type {Array<number>} */ var retVal
= [];
394 for (var i
= 0; i
< 4; ++i
)
395 retVal
[i
] = Math
.abs(random
.getInt());
403 * glsDrawTests.GLValue class
406 glsDrawTests
.GLValue = function() {
407 /** @type {goog.NumberArray} */ this.m_value
= [0];
408 /** @type {?glsDrawTests.DrawTestSpec.InputType} */ this.m_type
;
412 * @param {goog.TypedArray} dst
413 * @param {glsDrawTests.GLValue} val
415 glsDrawTests
.copyGLValueToArray = function(dst
, val
) {
416 /** @type {Uint8Array} */ var dst8
= new Uint8Array(dst
.buffer
).subarray(dst
.byteOffset
, dst
.byteOffset
+ dst
.byteLength
);
417 /** @type {Uint8Array} */ var val8
= new Uint8Array(val
.m_value
.buffer
); // TODO: Fix encapsulation issue
422 * @param {goog.TypedArray} dst
423 * @param {goog.TypedArray} src
425 glsDrawTests
.copyArray = function(dst
, src
) {
426 /** @type {Uint8Array} */ var dst8
= new Uint8Array(dst
.buffer
).subarray(dst
.byteOffset
, dst
.byteOffset
+ dst
.byteLength
);
427 /** @type {Uint8Array} */ var src8
= new Uint8Array(src
.buffer
).subarray(src
.byteOffset
, src
.byteOffset
+ src
.byteLength
);
432 * typeToTypedArray function. Determines which type of array will store the value, and stores it.
433 * @param {number} value
434 * @param {?glsDrawTests.DrawTestSpec.InputType} type
436 glsDrawTests
.GLValue
.typeToTypedArray = function(value
, type
) {
440 case glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
:
441 array
= new Float32Array(1);
444 case glsDrawTests
.DrawTestSpec
.InputType
.BYTE
:
445 array
= new Int8Array(1);
447 case glsDrawTests
.DrawTestSpec
.InputType
.SHORT
:
448 array
= new Int16Array(1);
451 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_BYTE
:
452 array
= new Uint8Array(1);
454 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_SHORT
:
455 array
= new Uint16Array(1);
458 case glsDrawTests
.DrawTestSpec
.InputType
.INT
:
459 array
= new Int32Array(1);
461 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT
:
462 array
= new Uint32Array(1);
464 case glsDrawTests
.DrawTestSpec
.InputType
.HALF
:
465 array
= new Uint16Array(1);
466 value
= glsDrawTests
.GLValue
.floatToHalf(value
);
468 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT_2_10_10_10
:
469 array
= new Uint32Array(1);
471 case glsDrawTests
.DrawTestSpec
.InputType
.INT_2_10_10_10
:
472 array
= new Int32Array(1);
475 throw new Error('glsDrawTests.GLValue.typeToTypedArray - Invalid InputType');
483 * glsDrawTests.GLValue.create
484 * @param {number} value
485 * @param {?glsDrawTests.DrawTestSpec.InputType} type
487 glsDrawTests
.GLValue
.create = function(value
, type
) {
488 var v
= new glsDrawTests
.GLValue();
489 v
.m_value
= glsDrawTests
.GLValue
.typeToTypedArray(value
, type
);
495 * glsDrawTests.GLValue.halfToFloat
496 * @param {number} value
499 glsDrawTests
.GLValue
.halfToFloat = function(value
) {
500 return tcuFloat
.halfFloatToNumberNoDenorm(value
);
507 glsDrawTests
.GLValue
.floatToHalf = function(f
) {
508 // No denorm support.
509 return tcuFloat
.numberToHalfFloatNoDenorm(f
);
513 * glsDrawTests.GLValue.getMaxValue
514 * @param {?glsDrawTests.DrawTestSpec.InputType} type
515 * @return {glsDrawTests.GLValue}
517 glsDrawTests
.GLValue
.getMaxValue = function(type
) {
520 assertMsgOptions(type
>= 0 && type
< Object
.keys(glsDrawTests
.DrawTestSpec
.InputType
).length
,
521 'Invalid type for GLValue', false, true);
524 case glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
:
527 case glsDrawTests
.DrawTestSpec
.InputType
.BYTE
:
530 case glsDrawTests
.DrawTestSpec
.InputType
.SHORT
:
533 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_BYTE
:
536 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_SHORT
:
539 case glsDrawTests
.DrawTestSpec
.InputType
.INT
:
542 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT
:
545 case glsDrawTests
.DrawTestSpec
.InputType
.HALF
:
548 default: //For any other valid type, return 0
552 return glsDrawTests
.GLValue
.create(value
, type
);
556 * glsDrawTests.GLValue.getMinValue
557 * @param {?glsDrawTests.DrawTestSpec.InputType} type
558 * @return {glsDrawTests.GLValue}
560 glsDrawTests
.GLValue
.getMinValue = function(type
) {
563 assertMsgOptions(type
>= 0 && type
< Object
.keys(glsDrawTests
.DrawTestSpec
.InputType
).length
,
564 'Invalid type for GLValue', false, true);
567 case glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
:
570 case glsDrawTests
.DrawTestSpec
.InputType
.BYTE
:
573 case glsDrawTests
.DrawTestSpec
.InputType
.SHORT
:
576 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_BYTE
:
579 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_SHORT
:
582 case glsDrawTests
.DrawTestSpec
.InputType
.INT
:
585 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT
:
588 case glsDrawTests
.DrawTestSpec
.InputType
.HALF
:
591 default: //For any other valid type, return 0
595 return glsDrawTests
.GLValue
.create(value
, type
);
599 * glsDrawTests.GLValue.getRandom
600 * @param {deRandom.Random} rnd
601 * @param {glsDrawTests.GLValue} min
602 * @param {glsDrawTests.GLValue} max
603 * @return {glsDrawTests.GLValue}
605 glsDrawTests
.GLValue
.getRandom = function(rnd
, min
, max
) {
606 assertMsgOptions(min
.getType() == max
.getType(), 'Min and max types differ', false, true);
608 var minv
= min
.interpret();
609 var maxv
= max
.interpret();
610 var type
= min
.getType();
617 case glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
:
618 case glsDrawTests
.DrawTestSpec
.InputType
.HALF
: {
619 return glsDrawTests
.GLValue
.create(minv
+ rnd
.getFloat() * (maxv
- minv
), type
);
623 case glsDrawTests
.DrawTestSpec
.InputType
.SHORT
:
624 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_SHORT
:
625 case glsDrawTests
.DrawTestSpec
.InputType
.BYTE
:
626 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_BYTE
:
627 case glsDrawTests
.DrawTestSpec
.InputType
.INT
:
628 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT
: {
629 return glsDrawTests
.GLValue
.create(minv
+ rnd
.getInt() % (maxv
- minv
), type
);
634 throw new Error('glsDrawTests.GLValue.getRandom - Invalid input type');
639 // Minimum difference required between coordinates
642 * @param {?glsDrawTests.DrawTestSpec.InputType} type
643 * @return {glsDrawTests.GLValue}
645 glsDrawTests
.GLValue
.minValue = function(type
) {
647 case glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
:
648 case glsDrawTests
.DrawTestSpec
.InputType
.BYTE
:
649 case glsDrawTests
.DrawTestSpec
.InputType
.HALF
:
650 return glsDrawTests
.GLValue
.create(4, type
);
651 case glsDrawTests
.DrawTestSpec
.InputType
.SHORT
:
652 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_SHORT
:
653 return glsDrawTests
.GLValue
.create(4 * 256, type
);
654 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_BYTE
:
655 return glsDrawTests
.GLValue
.create(4 * 2, type
);
656 case glsDrawTests
.DrawTestSpec
.InputType
.INT
:
657 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT
:
658 return glsDrawTests
.GLValue
.create(4 * 16777216, type
);
661 throw new Error('glsDrawTests.GLValue.minValue - Invalid input type');
666 * @param {glsDrawTests.GLValue} val
667 * @return {glsDrawTests.GLValue}
669 glsDrawTests
.GLValue
.abs = function(val
) {
670 var type
= val
.getType();
672 case glsDrawTests
.DrawTestSpec
.InputType
.SHORT
:
673 return glsDrawTests
.GLValue
.create(0x7FFF & val
.getValue(), type
);
674 case glsDrawTests
.DrawTestSpec
.InputType
.BYTE
:
675 return glsDrawTests
.GLValue
.create(0x7F & val
.getValue(), type
);
676 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_BYTE
:
677 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_SHORT
:
678 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT
:
680 case glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
:
681 case glsDrawTests
.DrawTestSpec
.InputType
.HALF
:
682 return glsDrawTests
.GLValue
.create(Math
.abs(val
.interpret()), type
);
683 case glsDrawTests
.DrawTestSpec
.InputType
.INT
:
684 return glsDrawTests
.GLValue
.create(0x7FFFFFFF & val
.getValue(), type
);
686 throw new Error('glsDrawTests.GLValue.abs - Invalid input type');
691 * @return {?glsDrawTests.DrawTestSpec.InputType}
693 glsDrawTests
.GLValue
.prototype.getType = function() {
698 * glsDrawTests.GLValue.toFloat
701 glsDrawTests
.GLValue
.prototype.toFloat = function() {
702 return this.interpret();
706 * glsDrawTests.GLValue.getValue
709 glsDrawTests
.GLValue
.prototype.getValue = function() {
710 return this.m_value
[0];
714 * interpret function. Returns the m_value as a quantity so arithmetic operations can be performed on it
715 * Only some types require this.
718 glsDrawTests
.GLValue
.prototype.interpret = function() {
719 if (this.m_type
== glsDrawTests
.DrawTestSpec
.InputType
.HALF
)
720 return glsDrawTests
.GLValue
.halfToFloat(this.m_value
[0]);
722 return this.m_value
[0];
726 * @param {glsDrawTests.GLValue} other
727 * @return {glsDrawTests.GLValue}
729 glsDrawTests
.GLValue
.prototype.add = function(other
) {
730 return glsDrawTests
.GLValue
.create(this.interpret() + other
.interpret(), this.m_type
);
734 * @param {glsDrawTests.GLValue} other
735 * @return {glsDrawTests.GLValue}
737 glsDrawTests
.GLValue
.prototype.mul = function(other
) {
738 return glsDrawTests
.GLValue
.create(this.interpret() * other
.interpret(), this.m_type
);
742 * @param {glsDrawTests.GLValue} other
743 * @return {glsDrawTests.GLValue}
745 glsDrawTests
.GLValue
.prototype.div = function(other
) {
746 return glsDrawTests
.GLValue
.create(this.interpret() / other
.interpret(), this.m_type
);
750 * @param {glsDrawTests.GLValue} other
751 * @return {glsDrawTests.GLValue}
753 glsDrawTests
.GLValue
.prototype.sub = function(other
) {
754 return glsDrawTests
.GLValue
.create(this.interpret() - other
.interpret(), this.m_type
);
758 * @param {glsDrawTests.GLValue} other
759 * @return {glsDrawTests.GLValue}
761 glsDrawTests
.GLValue
.prototype.addToSelf = function(other
) {
762 this.m_value
[0] = this.interpret() + other
.interpret();
767 * @param {glsDrawTests.GLValue} other
768 * @return {glsDrawTests.GLValue}
770 glsDrawTests
.GLValue
.prototype.subToSelf = function(other
) {
771 this.m_value
[0] = this.interpret() - other
.interpret();
776 * @param {glsDrawTests.GLValue} other
777 * @return {glsDrawTests.GLValue}
779 glsDrawTests
.GLValue
.prototype.mulToSelf = function(other
) {
780 this.m_value
[0] = this.interpret() * other
.interpret();
785 * @param {glsDrawTests.GLValue} other
786 * @return {glsDrawTests.GLValue}
788 glsDrawTests
.GLValue
.prototype.divToSelf = function(other
) {
789 this.m_value
[0] = this.interpret() / other
.interpret();
794 * @param {glsDrawTests.GLValue} other
797 glsDrawTests
.GLValue
.prototype.equals = function(other
) {
798 return this.m_value
[0] == other
.getValue();
802 * @param {glsDrawTests.GLValue} other
805 glsDrawTests
.GLValue
.prototype.lessThan = function(other
) {
806 return this.interpret() < other
.interpret();
810 * @param {glsDrawTests.GLValue} other
813 glsDrawTests
.GLValue
.prototype.greaterThan = function(other
) {
814 return this.interpret() > other
.interpret();
818 * @param {glsDrawTests.GLValue} other
821 glsDrawTests
.GLValue
.prototype.lessOrEqualThan = function(other
) {
822 return this.interpret() <= other
.interpret();
826 * @param {glsDrawTests.GLValue} other
829 glsDrawTests
.GLValue
.prototype.greaterOrEqualThan = function(other
) {
830 return this.interpret() >= other
.interpret();
838 * @param {?glsDrawTests.DrawTestSpec.Storage} storage
839 * @param {sglrGLContext.GLContext | sglrReferenceContext.ReferenceContext} context
841 glsDrawTests
.AttributeArray = function(storage
, context
) {
842 /** @type {?glsDrawTests.DrawTestSpec.Storage} */ this.m_storage
= storage
;
843 /** @type {sglrGLContext.GLContext | sglrReferenceContext.ReferenceContext} */ this.m_ctx
= context
;
844 /** @type {WebGLBuffer|sglrReferenceContext.DataBuffer|null} */ this.m_glBuffer
;
846 /** @type {number} */ this.m_size
= 0;
847 /** @type {Uint8Array} */ this.m_data
; //NOTE: Used in unsupported user storage
848 /** @type {number} */ this.m_componentCount
;
849 /** @type {boolean} */ this.m_bound
= false;
850 /** @type {glsDrawTests.DrawTestSpec.Target} */ this.m_target
= glsDrawTests
.DrawTestSpec
.Target
.ARRAY
;
851 /** @type {?glsDrawTests.DrawTestSpec.InputType} */ this.m_inputType
= glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
;
852 /** @type {?glsDrawTests.DrawTestSpec.OutputType} */ this.m_outputType
= glsDrawTests
.DrawTestSpec
.OutputType
.VEC4
;
853 /** @type {boolean} */ this.m_normalize
= false;
854 /** @type {number} */ this.m_stride
= 0;
855 /** @type {number} */ this.m_offset
= 0;
856 /** @type {Array<number>} */ this.m_defaultAttrib
;
857 /** @type {number} */ this.m_instanceDivisor
= 0;
858 /** @type {boolean} */ this.m_isPositionAttr
= false;
860 if (this.m_storage
== glsDrawTests
.DrawTestSpec
.Storage
.BUFFER
) {
861 this.m_glBuffer
= this.m_ctx
.createBuffer();
865 /** @return {number} */ glsDrawTests
.AttributeArray
.prototype.getComponentCount = function() {return this.m_componentCount
;};
867 /** @return {?glsDrawTests.DrawTestSpec.Target} */ glsDrawTests
.AttributeArray
.prototype.getTarget = function() {return this.m_target
;};
869 /** @return {?glsDrawTests.DrawTestSpec.InputType} */ glsDrawTests
.AttributeArray
.prototype.getInputType = function() {return this.m_inputType
;};
871 /** @return {?glsDrawTests.DrawTestSpec.OutputType} */ glsDrawTests
.AttributeArray
.prototype.getOutputType = function() {return this.m_outputType
;};
873 /** @return {?glsDrawTests.DrawTestSpec.Storage} */ glsDrawTests
.AttributeArray
.prototype.getStorageType = function() {return this.m_storage
;};
875 /** @return {boolean} */ glsDrawTests
.AttributeArray
.prototype.getNormalized = function() {return this.m_normalize
;};
877 /** @return {number} */ glsDrawTests
.AttributeArray
.prototype.getStride = function() {return this.m_stride
;};
879 /** @return {boolean} */ glsDrawTests
.AttributeArray
.prototype.isBound = function() {return this.m_bound
;};
881 /** @return {boolean} */ glsDrawTests
.AttributeArray
.prototype.isPositionAttribute = function() {return this.m_isPositionAttr
;};
884 * @param {glsDrawTests.DrawTestSpec.Target} target
885 * @param {number} size
886 * @param {goog.TypedArray} ptr
887 * @param {?glsDrawTests.DrawTestSpec.Usage} usage
889 glsDrawTests
.AttributeArray
.prototype.data = function(target
, size
, ptr
, usage
) {
891 this.m_target
= target
;
893 if (this.m_storage
== glsDrawTests
.DrawTestSpec
.Storage
.BUFFER
) {
894 this.m_ctx
.bindBuffer(glsDrawTests
.targetToGL(target
), this.m_glBuffer
);
895 this.m_ctx
.bufferData(glsDrawTests
.targetToGL(target
), ptr
, glsDrawTests
.usageToGL(usage
));
897 throw new Error('Wrong storage type');
901 * @param {glsDrawTests.DrawTestSpec.Target} target
902 * @param {number} offset
903 * @param {number} size
904 * @param {goog.TypedArray} ptr
906 glsDrawTests
.AttributeArray
.prototype.subdata = function(target
, offset
, size
, ptr
) {
907 this.m_target
= target
;
909 if (this.m_storage
== glsDrawTests
.DrawTestSpec
.Storage
.BUFFER
) {
910 this.m_ctx
.bindBuffer(glsDrawTests
.targetToGL(target
), this.m_glBuffer
);
912 this.m_ctx
.bufferSubData(glsDrawTests
.targetToGL(target
), offset
, size
, ptr
);
914 throw new Error('Wrong storage type');
918 * @param {boolean} bound
919 * @param {number} offset
920 * @param {number} size
921 * @param {?glsDrawTests.DrawTestSpec.InputType} inputType
922 * @param {?glsDrawTests.DrawTestSpec.OutputType} outType
923 * @param {boolean} normalized
924 * @param {number} stride
925 * @param {number} instanceDivisor
926 * @param {Array<number>} defaultAttrib
927 * @param {boolean} isPositionAttr
929 glsDrawTests
.AttributeArray
.prototype.setupArray = function(bound
, offset
, size
, inputType
, outType
,
930 normalized
, stride
, instanceDivisor
, defaultAttrib
, isPositionAttr
) {
931 this.m_componentCount
= size
;
932 this.m_bound
= bound
;
933 this.m_inputType
= inputType
;
934 this.m_outputType
= outType
;
935 this.m_normalize
= normalized
;
936 this.m_stride
= stride
;
937 this.m_offset
= offset
;
938 this.m_defaultAttrib
= defaultAttrib
;
939 this.m_instanceDivisor
= instanceDivisor
;
940 this.m_isPositionAttr
= isPositionAttr
;
944 * @param {number} loc (32-bit)
946 glsDrawTests
.AttributeArray
.prototype.bindAttribute = function(loc
) {
947 if (!this.isBound()) {
948 /** @type {Array<number>} */ var attr
= this.m_defaultAttrib
;
949 switch (this.m_inputType
) {
950 case glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
: {
951 switch (this.m_componentCount
) {
952 case 1: this.m_ctx
.vertexAttrib1f(loc
, attr
[0]); break;
953 case 2: this.m_ctx
.vertexAttrib2f(loc
, attr
[0], attr
[1]); break;
954 case 3: this.m_ctx
.vertexAttrib3f(loc
, attr
[0], attr
[1], attr
[2]); break;
955 case 4: this.m_ctx
.vertexAttrib4f(loc
, attr
[0], attr
[1], attr
[2], attr
[3]); break;
956 default: throw new Error('Invalid component count'); break;
960 case glsDrawTests
.DrawTestSpec
.InputType
.INT
: {
961 this.m_ctx
.vertexAttribI4i(loc
, attr
[0], attr
[1], attr
[2], attr
[3]);
964 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT
: {
965 this.m_ctx
.vertexAttribI4ui(loc
, attr
[0], attr
[1], attr
[2], attr
[3]);
969 throw new Error('Invalid input type');
973 /** @type {Uint8Array} */ var basePtr
= null;
975 if (this.m_storage
== glsDrawTests
.DrawTestSpec
.Storage
.BUFFER
) {
976 this.m_ctx
.bindBuffer(glsDrawTests
.targetToGL(this.m_target
), this.m_glBuffer
);
980 throw new Error('Invalid storage type');
982 if (!glsDrawTests
.inputTypeIsFloatType(this.m_inputType
)) {
983 // Input is not float type
985 if (glsDrawTests
.outputTypeIsFloatType(this.m_outputType
)) {
986 var size
= this.m_componentCount
;
988 // Output type is float type
989 this.m_ctx
.vertexAttribPointer(loc
, size
, glsDrawTests
.inputTypeToGL(this.m_inputType
), this.m_normalize
, this.m_stride
, this.m_offset
);
991 // Output type is int type
992 this.m_ctx
.vertexAttribIPointer(loc
, this.m_componentCount
, glsDrawTests
.inputTypeToGL(this.m_inputType
), this.m_stride
, this.m_offset
);
995 // Input type is float type
997 // Output type must be float type
998 assertMsgOptions(glsDrawTests
.outputTypeIsFloatType(this.m_outputType
), 'Output type is not float', false, true);
1000 this.m_ctx
.vertexAttribPointer(loc
, this.m_componentCount
, glsDrawTests
.inputTypeToGL(this.m_inputType
), this.m_normalize
,
1001 this.m_stride
, this.m_offset
);
1004 if (this.m_instanceDivisor
)
1005 this.m_ctx
.vertexAttribDivisor(loc
, this.m_instanceDivisor
);
1010 * @param {glsDrawTests.DrawTestSpec.Target} target
1012 glsDrawTests
.AttributeArray
.prototype.bindIndexArray = function(target
) {
1013 if (this.m_storage
== glsDrawTests
.DrawTestSpec
.Storage
.BUFFER
) {
1014 this.m_ctx
.bindBuffer(glsDrawTests
.targetToGL(target
), this.m_glBuffer
);
1018 // DrawTestShaderProgram
1022 * @extends {sglrShaderProgram.ShaderProgram}
1023 * @param {Array<glsDrawTests.AttributeArray>} arrays
1025 glsDrawTests
.DrawTestShaderProgram = function(arrays
) {
1026 sglrShaderProgram
.ShaderProgram
.call(this, this.createProgramDeclaration(arrays
));
1028 this.m_componentCount
= [];
1029 this.m_isCoord
= [];
1030 this.m_attrType
= [];
1032 for (var arrayNdx
= 0; arrayNdx
< arrays
.length
; arrayNdx
++) {
1033 this.m_componentCount
[arrayNdx
] = this.getComponentCount(arrays
[arrayNdx
].getOutputType());
1034 this.m_isCoord
[arrayNdx
] = arrays
[arrayNdx
].isPositionAttribute();
1035 this.m_attrType
[arrayNdx
] = this.mapOutputType(arrays
[arrayNdx
].getOutputType());
1039 glsDrawTests
.DrawTestShaderProgram
.prototype = Object
.create(sglrShaderProgram
.ShaderProgram
.prototype);
1040 glsDrawTests
.DrawTestShaderProgram
.prototype.constructor = glsDrawTests
.DrawTestShaderProgram
;
1043 * @param {Array<number>} color
1044 * @param {goog.NumberArray} attribValue
1045 * @param {number} numComponents
1046 * @return {Array<number>}
1048 glsDrawTests
.calcShaderColor = function(color
, attribValue
, numComponents
) {
1049 switch (numComponents
) {
1051 color
[0] = deMath
.scale(color
, attribValue
[0])[0];
1055 color
[0] = color
[0] * attribValue
[0];
1056 color
[1] = color
[1] * attribValue
[1];
1060 color
[0] = color
[0] * attribValue
[0];
1061 color
[1] = color
[1] * attribValue
[1];
1062 color
[2] = color
[2] * attribValue
[2];
1066 color
[0] = color
[0] * attribValue
[0] * attribValue
[3];
1067 color
[1] = color
[1] * attribValue
[1] * attribValue
[3];
1068 color
[2] = color
[2] * attribValue
[2] * attribValue
[3];
1072 throw new Error('Invalid component count');
1079 * @param {Array<number>} coord
1080 * @param {goog.NumberArray} attribValue
1081 * @param {number} numComponents
1082 * @return {Array<number>}
1084 glsDrawTests
.calcShaderCoord = function(coord
, attribValue
, numComponents
) {
1085 switch (numComponents
) {
1088 coord
= deMath
.add(coord
, [attribValue
[0], attribValue
[0]]);
1089 coord
[0] = coord
[0];
1090 coord
[1] = coord
[1];
1093 coord
= deMath
.add(coord
, [attribValue
[0], attribValue
[1]]);
1094 coord
[0] = coord
[0];
1095 coord
[1] = coord
[1];
1098 coord
= deMath
.add(coord
, [attribValue
[0] + attribValue
[2], attribValue
[1]]);
1099 coord
[0] = coord
[0];
1100 coord
[1] = coord
[1];
1101 coord
[2] = coord
[2];
1104 coord
= deMath
.add(coord
, [attribValue
[0] + attribValue
[2], attribValue
[1] + attribValue
[3]]);
1105 coord
[0] = coord
[0];
1106 coord
[1] = coord
[1];
1107 coord
[2] = coord
[2];
1108 coord
[3] = coord
[3];
1112 throw new Error('Invalid component count');
1119 * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
1120 * @param {Array<rrVertexPacket.VertexPacket>} packets
1121 * @param {number} numPackets
1123 glsDrawTests
.DrawTestShaderProgram
.prototype.shadeVertices = function(inputs
, packets
, numPackets
) {
1124 var u_coordScale
= this.getUniformByName('u_coordScale').value
;
1125 var u_colorScale
= this.getUniformByName('u_colorScale').value
;
1127 for (var packetNdx
= 0; packetNdx
< numPackets
; ++packetNdx
) {
1128 var varyingLocColor
= 0;
1130 /** @type {rrVertexPacket.VertexPacket} */ var packet
= packets
[packetNdx
];
1132 // Calc output color
1133 /** @type {Array<number>} */ var coord
= [0.0, 0.0];
1134 /** @type {Array<number>} */ var color
= [1.0, 1.0, 1.0];
1136 for (var attribNdx
= 0; attribNdx
< this.m_attrType
.length
; attribNdx
++) {
1137 var numComponents
= this.m_componentCount
[attribNdx
];
1138 /** @type {boolean} */ var isCoord
= this.m_isCoord
[attribNdx
];
1140 var attrib
= rrVertexAttrib
.readVertexAttrib(inputs
[attribNdx
], packet
.instanceNdx
, packet
.vertexNdx
, this.m_attrType
[attribNdx
]);
1143 coord
= glsDrawTests
.calcShaderCoord(
1149 color
= glsDrawTests
.calcShaderColor(
1157 // Transform position
1158 packet
.position
= [u_coordScale
* coord
[0], u_coordScale
* coord
[1], 1.0, 1.0];
1159 packet
.pointSize
= 1.0;
1162 packet
.outputs
[varyingLocColor
] = deMath
.add(deMath
.scale([u_colorScale
* color
[0], u_colorScale
* color
[1], u_colorScale
* color
[2], 1.0], 0.5), [0.5, 0.5, 0.5, 0.5]);
1167 * @param {Array<rrFragmentOperations.Fragment>} packets
1168 * @param {rrShadingContext.FragmentShadingContext} context
1170 glsDrawTests
.DrawTestShaderProgram
.prototype.shadeFragments = function(packets
, context
) {
1171 var varyingLocColor
= 0;
1173 for (var packetNdx
= 0; packetNdx
< packets
.length
; ++packetNdx
) {
1174 /** @type {rrFragmentOperations.Fragment} */ var packet
= packets
[packetNdx
];
1175 packet
.value
= rrShadingContext
.readVarying(packet
, context
, varyingLocColor
);
1180 * @param {Array<glsDrawTests.AttributeArray>} arrays
1183 glsDrawTests
.DrawTestShaderProgram
.prototype.genVertexSource = function(arrays
) {
1184 /** @type {Array<string>}*/ var params
;
1185 var vertexShaderTmpl
= '';
1187 params
= this.generateShaderParams();
1189 vertexShaderTmpl
+= params
['VTX_HDR'];
1191 for (var arrayNdx
= 0; arrayNdx
< arrays
.length
; arrayNdx
++) {
1192 vertexShaderTmpl
+= params
['VTX_IN'] + ' highp ' + glsDrawTests
.outputTypeToGLType(arrays
[arrayNdx
].getOutputType()) + ' a_' + arrayNdx
+ ';\n';
1196 'uniform highp float u_coordScale;\n' +
1197 'uniform highp float u_colorScale;\n' +
1198 params
['VTX_OUT'] + ' ' + params
['COL_PRECISION'] + ' vec4 v_color;\n' +
1199 'void main(void)\n' +
1201 '\tgl_PointSize = 1.0;\n' +
1202 '\thighp vec2 coord = vec2(0.0, 0.0);\n' +
1203 '\thighp vec3 color = vec3(1.0, 1.0, 1.0);\n';
1205 for (var arrayNdx
= 0; arrayNdx
< arrays
.length
; arrayNdx
++) {
1206 var isPositionAttr
= arrays
[arrayNdx
].isPositionAttribute();
1208 if (isPositionAttr
) {
1209 switch (arrays
[arrayNdx
].getOutputType()) {
1210 case glsDrawTests
.DrawTestSpec
.OutputType
.FLOAT
:
1211 case glsDrawTests
.DrawTestSpec
.OutputType
.INT
:
1212 case glsDrawTests
.DrawTestSpec
.OutputType
.UINT
:
1214 '\tcoord += vec2(float(a_' + arrayNdx
+ '), float(a_' + arrayNdx
+ '));\n';
1217 case glsDrawTests
.DrawTestSpec
.OutputType
.VEC2
:
1218 case glsDrawTests
.DrawTestSpec
.OutputType
.IVEC2
:
1219 case glsDrawTests
.DrawTestSpec
.OutputType
.UVEC2
:
1221 '\tcoord += vec2(a_' + arrayNdx
+ '.xy);\n';
1224 case glsDrawTests
.DrawTestSpec
.OutputType
.VEC3
:
1225 case glsDrawTests
.DrawTestSpec
.OutputType
.IVEC3
:
1226 case glsDrawTests
.DrawTestSpec
.OutputType
.UVEC3
:
1228 '\tcoord += vec2(a_' + arrayNdx
+ '.xy);\n' +
1229 '\tcoord.x += float(a_' + arrayNdx
+ '.z);\n';
1232 case glsDrawTests
.DrawTestSpec
.OutputType
.VEC4
:
1233 case glsDrawTests
.DrawTestSpec
.OutputType
.IVEC4
:
1234 case glsDrawTests
.DrawTestSpec
.OutputType
.UVEC4
:
1236 '\tcoord += vec2(a_' + arrayNdx
+ '.xy);\n' +
1237 '\tcoord += vec2(a_' + arrayNdx
+ '.zw);\n';
1241 throw new Error('Invalid output type');
1245 switch (arrays
[arrayNdx
].getOutputType()) {
1246 case glsDrawTests
.DrawTestSpec
.OutputType
.FLOAT
:
1247 case glsDrawTests
.DrawTestSpec
.OutputType
.INT
:
1248 case glsDrawTests
.DrawTestSpec
.OutputType
.UINT
:
1250 '\tcolor = color * float(a_' + arrayNdx
+ ');\n';
1253 case glsDrawTests
.DrawTestSpec
.OutputType
.VEC2
:
1254 case glsDrawTests
.DrawTestSpec
.OutputType
.IVEC2
:
1255 case glsDrawTests
.DrawTestSpec
.OutputType
.UVEC2
:
1257 '\tcolor.rg = color.rg * vec2(a_' + arrayNdx
+ '.xy);\n';
1260 case glsDrawTests
.DrawTestSpec
.OutputType
.VEC3
:
1261 case glsDrawTests
.DrawTestSpec
.OutputType
.IVEC3
:
1262 case glsDrawTests
.DrawTestSpec
.OutputType
.UVEC3
:
1264 '\tcolor = color.rgb * vec3(a_' + arrayNdx
+ '.xyz);\n';
1267 case glsDrawTests
.DrawTestSpec
.OutputType
.VEC4
:
1268 case glsDrawTests
.DrawTestSpec
.OutputType
.IVEC4
:
1269 case glsDrawTests
.DrawTestSpec
.OutputType
.UVEC4
:
1271 '\tcolor = color.rgb * vec3(a_' + arrayNdx
+ '.xyz) * float(a_' + arrayNdx
+ '.w);\n';
1275 throw new Error('Invalid output type');
1282 '\tv_color = vec4(u_colorScale * color, 1.0) * 0.5 + vec4(0.5, 0.5, 0.5, 0.5);\n' +
1283 '\tgl_Position = vec4(u_coordScale * coord, 1.0, 1.0);\n' +
1286 return vertexShaderTmpl
;
1292 glsDrawTests
.DrawTestShaderProgram
.prototype.genFragmentSource = function() {
1293 /** @type {Array<string>} */ var params
;
1295 params
= this.generateShaderParams();
1297 var fragmentShaderTmpl
= params
['FRAG_HDR'] +
1298 params
['FRAG_IN'] + ' ' + params
['COL_PRECISION'] + ' vec4 v_color;\n' +
1299 'void main(void)\n' +
1301 '\t' + params
['FRAG_COLOR'] + '= v_color;\n' +
1304 return fragmentShaderTmpl
;
1308 * @return {Array<string>}
1310 glsDrawTests
.DrawTestShaderProgram
.prototype.generateShaderParams = function() {
1311 /** @type {Array<string>} */ var params
= [];
1312 if (gluShaderUtil
.isGLSLVersionSupported(gl
, gluShaderUtil
.GLSLVersion
.V300_ES
)) {
1313 params
['VTX_IN'] = 'in';
1314 params
['VTX_OUT'] = 'out';
1315 params
['FRAG_IN'] = 'in';
1316 params
['FRAG_COLOR'] = 'dEQP_FragColor';
1317 params
['VTX_HDR'] = '#version 300 es\n';
1318 params
['FRAG_HDR'] = '#version 300 es\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n';
1319 params
['COL_PRECISION'] = 'mediump';
1320 } else if (gluShaderUtil
.isGLSLVersionSupported(gl
, gluShaderUtil
.GLSLVersion
.V100_ES
)) {
1321 params
['VTX_IN'] = 'attribute';
1322 params
['VTX_OUT'] = 'varying';
1323 params
['FRAG_IN'] = 'varying';
1324 params
['FRAG_COLOR'] = 'gl_FragColor';
1325 params
['VTX_HDR'] = '';
1326 params
['FRAG_HDR'] = '';
1327 params
['COL_PRECISION'] = 'mediump';
1329 throw new Error('Invalid GL version');
1335 * @param {?glsDrawTests.DrawTestSpec.OutputType} type
1336 * @return {rrGenericVector.GenericVecType}
1338 glsDrawTests
.DrawTestShaderProgram
.prototype.mapOutputType = function(type
) {
1340 case glsDrawTests
.DrawTestSpec
.OutputType
.FLOAT
:
1341 case glsDrawTests
.DrawTestSpec
.OutputType
.VEC2
:
1342 case glsDrawTests
.DrawTestSpec
.OutputType
.VEC3
:
1343 case glsDrawTests
.DrawTestSpec
.OutputType
.VEC4
:
1344 return rrGenericVector
.GenericVecType
.FLOAT
;
1346 case glsDrawTests
.DrawTestSpec
.OutputType
.INT
:
1347 case glsDrawTests
.DrawTestSpec
.OutputType
.IVEC2
:
1348 case glsDrawTests
.DrawTestSpec
.OutputType
.IVEC3
:
1349 case glsDrawTests
.DrawTestSpec
.OutputType
.IVEC4
:
1350 return rrGenericVector
.GenericVecType
.INT32
;
1352 case glsDrawTests
.DrawTestSpec
.OutputType
.UINT
:
1353 case glsDrawTests
.DrawTestSpec
.OutputType
.UVEC2
:
1354 case glsDrawTests
.DrawTestSpec
.OutputType
.UVEC3
:
1355 case glsDrawTests
.DrawTestSpec
.OutputType
.UVEC4
:
1356 return rrGenericVector
.GenericVecType
.UINT32
;
1359 throw new Error('Invalid output type');
1364 * @param {?glsDrawTests.DrawTestSpec.OutputType} type
1367 glsDrawTests
.DrawTestShaderProgram
.prototype.getComponentCount = function(type
) {
1369 case glsDrawTests
.DrawTestSpec
.OutputType
.FLOAT
:
1370 case glsDrawTests
.DrawTestSpec
.OutputType
.INT
:
1371 case glsDrawTests
.DrawTestSpec
.OutputType
.UINT
:
1374 case glsDrawTests
.DrawTestSpec
.OutputType
.VEC2
:
1375 case glsDrawTests
.DrawTestSpec
.OutputType
.IVEC2
:
1376 case glsDrawTests
.DrawTestSpec
.OutputType
.UVEC2
:
1379 case glsDrawTests
.DrawTestSpec
.OutputType
.VEC3
:
1380 case glsDrawTests
.DrawTestSpec
.OutputType
.IVEC3
:
1381 case glsDrawTests
.DrawTestSpec
.OutputType
.UVEC3
:
1384 case glsDrawTests
.DrawTestSpec
.OutputType
.VEC4
:
1385 case glsDrawTests
.DrawTestSpec
.OutputType
.IVEC4
:
1386 case glsDrawTests
.DrawTestSpec
.OutputType
.UVEC4
:
1390 throw new Error('Invalid output type');
1395 * @param {Array<glsDrawTests.AttributeArray>} arrays
1396 * @return {sglrShaderProgram.ShaderProgramDeclaration}
1398 glsDrawTests
.DrawTestShaderProgram
.prototype.createProgramDeclaration = function(arrays
) {
1399 /** @type {sglrShaderProgram.ShaderProgramDeclaration} */ var decl
= new sglrShaderProgram
.ShaderProgramDeclaration();
1401 for (var arrayNdx
= 0; arrayNdx
< arrays
.length
; arrayNdx
++)
1402 decl
.pushVertexAttribute(new sglrShaderProgram
.VertexAttribute('a_' + arrayNdx
, this.mapOutputType(arrays
[arrayNdx
].getOutputType())));
1404 decl
.pushVertexToFragmentVarying(new sglrShaderProgram
.VertexToFragmentVarying(rrGenericVector
.GenericVecType
.FLOAT
));
1405 decl
.pushFragmentOutput(new sglrShaderProgram
.FragmentOutput(rrGenericVector
.GenericVecType
.FLOAT
));
1407 decl
.pushVertexSource(new sglrShaderProgram
.VertexSource(this.genVertexSource(arrays
)));
1408 decl
.pushFragmentSource(new sglrShaderProgram
.FragmentSource(this.genFragmentSource()));
1410 decl
.pushUniform(new sglrShaderProgram
.Uniform('u_coordScale', gluShaderUtil
.DataType
.FLOAT
));
1411 decl
.pushUniform(new sglrShaderProgram
.Uniform('u_colorScale', gluShaderUtil
.DataType
.FLOAT
));
1417 * @typedef {glsDrawTests.RandomArrayGenerator}
1419 glsDrawTests
.RandomArrayGenerator
= {};
1422 * @param {goog.TypedArray} data
1423 * @param {?glsDrawTests.DrawTestSpec.InputType} type
1424 * @param {deRandom.Random} rnd
1425 * @param {glsDrawTests.GLValue} min
1426 * @param {glsDrawTests.GLValue} max
1428 glsDrawTests
.RandomArrayGenerator
.setData = function(data
, type
, rnd
, min
, max
) {
1430 case glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
:
1431 case glsDrawTests
.DrawTestSpec
.InputType
.SHORT
:
1432 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_SHORT
:
1433 case glsDrawTests
.DrawTestSpec
.InputType
.BYTE
:
1434 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_BYTE
:
1435 case glsDrawTests
.DrawTestSpec
.InputType
.INT
:
1436 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT
:
1437 case glsDrawTests
.DrawTestSpec
.InputType
.HALF
:
1438 glsDrawTests
.copyGLValueToArray(data
, glsDrawTests
.GLValue
.getRandom(rnd
, min
, max
));
1441 throw new Error('Invalid input type');
1447 * @param {number} seed
1448 * @param {number} elementCount
1449 * @param {number} componentCount
1450 * @param {number} offset
1451 * @param {number} stride
1452 * @param {?glsDrawTests.DrawTestSpec.InputType} type
1453 * @param {number} first
1454 * @param {?glsDrawTests.DrawTestSpec.Primitive} primitive
1455 * @param {?goog.TypedArray} indices
1456 * @param {number} indexSize
1457 * @return {goog.TypedArray}
1459 glsDrawTests
.RandomArrayGenerator
.createArray = function(seed
, elementCount
, componentCount
, offset
, stride
, type
, first
, primitive
, indices
, indexSize
) {
1460 assertMsgOptions(componentCount
>= 1 && componentCount
<= 4, 'Unacceptable number of components', false, true);
1462 /** @type {glsDrawTests.GLValue} */ var min
= glsDrawTests
.GLValue
.getMinValue(type
);
1463 /** @type {glsDrawTests.GLValue} */ var max
= glsDrawTests
.GLValue
.getMaxValue(type
);
1465 var packed
= type
== glsDrawTests
.DrawTestSpec
.InputType
.INT_2_10_10_10
||
1466 type
== glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT_2_10_10_10
;
1467 /** @type {number} */ var limit10
= (1 << 10);
1468 /** @type {number} */ var limit2
= (1 << 2);
1471 /** @type {number} */ var componentSize
= glsDrawTests
.DrawTestSpec
.inputTypeSize(type
);
1472 /** @type {number} */ var elementSize
= componentSize
* componentCount
;
1473 /** @type {number} */ var bufferSize
= offset
+ Math
.max(elementCount
* stride
, elementCount
* elementSize
);
1475 var data
= new ArrayBuffer(bufferSize
);
1476 var writePtr
= new Uint8Array(data
, offset
);
1478 var previousComponentsFloat
= [0, 0, 0, 0];
1479 var rnd
= new deRandom
.Random(seed
);
1481 for (var vertexNdx
= 0; vertexNdx
< elementCount
; vertexNdx
++) {
1482 var components
= [];
1484 for (var componentNdx
= 0; componentNdx
< componentCount
; componentNdx
++) {
1485 var getRandomComponent = function() {
1486 // For packed formats we can't use GLValue
1488 if (componentNdx
== 3) {
1489 return rnd
.getInt() % limit2
;
1491 return rnd
.getInt() % limit10
;
1494 return glsDrawTests
.GLValue
.getRandom(rnd
, min
, max
);
1498 var component
= getRandomComponent();
1499 var componentFloat
= (component
instanceof glsDrawTests
.GLValue
) ? component
.toFloat() : component
;
1501 // Try to not create vertex near previous
1502 if (vertexNdx
!= 0 && Math
.abs(componentFloat
- previousComponentsFloat
[componentNdx
]) < min
.toFloat()) {
1503 // Too close, try again (but only once)
1504 component
= getRandomComponent();
1505 componentFloat
= (component
instanceof glsDrawTests
.GLValue
) ? component
.toFloat() : component
;
1508 components
.push(component
);
1509 previousComponentsFloat
[componentNdx
] = componentFloat
;
1513 var packedValue
= deMath
.binaryOp(
1514 deMath
.shiftLeft(/** @type {Array<number>} */ (components
)[3], 30), deMath
.binaryOp(
1515 deMath
.shiftLeft(/** @type {Array<number>} */ (components
)[2], 20), deMath
.binaryOp(
1516 deMath
.shiftLeft(/** @type {Array<number>} */ (components
)[1], 10), /** @type {Array<number>} */ (components
)[0], deMath
.BinaryOp
.OR
1517 ), deMath
.BinaryOp
.OR
1518 ), deMath
.BinaryOp
.OR
1520 glsDrawTests
.copyArray(writePtr
, new Uint32Array([packedValue
]));
1522 for (var componentNdx
= 0; componentNdx
< componentCount
; componentNdx
++) {
1523 glsDrawTests
.copyGLValueToArray(writePtr
.subarray(componentNdx
* componentSize
), components
[componentNdx
]);
1527 writePtr
= writePtr
.subarray(stride
);
1530 return new Uint8Array(data
);
1534 * @param {number} seed
1535 * @param {number} elementCount
1536 * @param {?glsDrawTests.DrawTestSpec.IndexType} type
1537 * @param {number} offset
1538 * @param {number} min
1539 * @param {number} max
1540 * @return {goog.TypedArray}
1542 glsDrawTests
.RandomArrayGenerator
.generateIndices = function(seed
, elementCount
, type
, offset
, min
, max
) {
1543 return glsDrawTests
.RandomArrayGenerator
.createIndices(seed
, elementCount
, offset
, min
, max
, type
);
1547 * @param {number} seed
1548 * @param {number} elementCount
1549 * @param {number} offset
1550 * @param {number} min
1551 * @param {number} max
1552 * @param {?glsDrawTests.DrawTestSpec.IndexType} type
1553 * @return {goog.TypedArray}
1555 glsDrawTests
.RandomArrayGenerator
.createIndices = function(seed
, elementCount
, offset
, min
, max
, type
) {
1556 /** @type {number}*/ var elementSize
= glsDrawTests
.DrawTestSpec
.indexTypeSize(type
);
1557 /** @type {number}*/ var bufferSize
= offset
+ elementCount
* elementSize
;
1559 var data
= new ArrayBuffer(bufferSize
);
1560 var writePtr
= new Uint8Array(data
).subarray(offset
);
1562 var rnd
= new deRandom
.Random(seed
);
1564 /* TODO: get limits for given index type --> if (min < 0 || min > std::numeric_limits<T>::max() ||
1565 max < 0 || max > std::numeric_limits<T>::max() ||
1567 DE_ASSERT(!"Invalid range");*/
1569 // JS refrast requires shuffled unique keys
1571 for (var key
= 0; key
< elementCount
; key
++)
1572 keys
.push(glsDrawTests
.GLValue
.create(key
, glsDrawTests
.indexTypeToInputType(type
)));
1574 for (var elementNdx
= 0; elementNdx
< elementCount
; ++elementNdx
) {
1575 var randomkey
= rnd
.getInt(0, keys
.length
- 1);
1576 var ndx
= keys
[randomkey
];
1578 keys
.splice(randomkey
, 1);
1580 glsDrawTests
.copyArray(
1581 writePtr
.subarray(elementSize
* elementNdx
),
1582 new Uint8Array(ndx
.m_value
.buffer
)
1586 return new Uint8Array(data
);
1590 * @param {number} seed
1591 * @param {?glsDrawTests.DrawTestSpec.InputType} type
1592 * @return {Array<number>}
1594 glsDrawTests
.RandomArrayGenerator
.generateAttributeValue = function(seed
, type
) {
1595 var random
= new deRandom
.Random(seed
);
1598 case glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
:
1599 return glsDrawTests
.generateRandomVec4(random
);
1601 case glsDrawTests
.DrawTestSpec
.InputType
.INT
:
1602 return glsDrawTests
.generateRandomIVec4(random
);
1604 case glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT
:
1605 return glsDrawTests
.generateRandomUVec4(random
);
1608 throw new Error('Invalid attribute type');
1615 * @param {sglrReferenceContext.ReferenceContext | sglrGLContext.GLContext} drawContext
1616 * @param {Array<number>} screenSize (2 positive elements in array)
1617 * @param {boolean} useVao
1618 * @param {boolean} logEnabled
1621 glsDrawTests
.AttributePack = function(drawContext
, screenSize
, useVao
, logEnabled
) {
1622 /** @type {sglrReferenceContext.ReferenceContext | sglrGLContext.GLContext} */ this.m_ctx
= drawContext
;
1624 /** @type {Array<glsDrawTests.AttributeArray>} */ this.m_arrays
= [];
1625 /** @type {sglrShaderProgram.ShaderProgram} */ this.m_program
;
1626 /** @type {tcuSurface.Surface} */ this.m_screen
= new tcuSurface
.Surface(screenSize
[0], screenSize
[1]);
1627 /** @type {boolean} */ this.m_useVao
= useVao
;
1628 /** @type {boolean} */ this.m_logEnabled
= logEnabled
;
1629 /** @type {WebGLProgram | sglrShaderProgram.ShaderProgram | null} */ this.m_programID
= null;
1630 /** @type {WebGLVertexArrayObject|sglrReferenceContext.VertexArray|null} */ this.m_vaoID
= null;
1633 this.m_vaoID
= this.m_ctx
.createVertexArray();
1637 * @return {tcuSurface.Surface}
1639 glsDrawTests
.AttributePack
.prototype.getSurface = function() {
1640 return this.m_screen
;
1645 * @return {glsDrawTests.AttributeArray}
1647 glsDrawTests
.AttributePack
.prototype.getArray = function(i
) {
1648 return this.m_arrays
[i
];
1654 glsDrawTests
.AttributePack
.prototype.getArrayCount = function() {
1655 return this.m_arrays
.length
;
1659 * @param {?glsDrawTests.DrawTestSpec.Storage} storage
1661 glsDrawTests
.AttributePack
.prototype.newArray = function(storage
) {
1662 this.m_arrays
.push(new glsDrawTests
.AttributeArray(storage
, this.m_ctx
));
1668 glsDrawTests
.AttributePack
.prototype.clearArrays = function() {
1669 this.m_arrays
.length
= 0;
1675 glsDrawTests
.AttributePack
.prototype.updateProgram = function() {
1676 if (this.m_programID
)
1677 this.m_ctx
.deleteProgram(this.m_programID
);
1679 this.m_program
= new glsDrawTests
.DrawTestShaderProgram(this.m_arrays
);
1680 this.m_programID
= this.m_ctx
.createProgram(this.m_program
);
1684 * @param {?glsDrawTests.DrawTestSpec.Primitive} primitive
1685 * @param {?glsDrawTests.DrawTestSpec.DrawMethod} drawMethod
1686 * @param {number} firstVertex
1687 * @param {number} vertexCount
1688 * @param {?glsDrawTests.DrawTestSpec.IndexType} indexType
1689 * @param {number} indexOffset
1690 * @param {number} rangeStart
1691 * @param {number} rangeEnd
1692 * @param {number} instanceCount
1693 * @param {number} coordScale
1694 * @param {number} colorScale
1695 * @param {glsDrawTests.AttributeArray} indexArray
1697 glsDrawTests
.AttributePack
.prototype.render = function(primitive
, drawMethod
, firstVertex
, vertexCount
, indexType
,
1698 indexOffset
, rangeStart
, rangeEnd
, instanceCount
, coordScale
, colorScale
, indexArray
) {
1699 assertMsgOptions(this.m_program
!= null, 'Program is null', false, true);
1700 assertMsgOptions(this.m_programID
!= null, 'No context created program', false, true);
1702 this.m_ctx
.viewport(0, 0, this.m_screen
.getWidth(), this.m_screen
.getHeight());
1703 this.m_ctx
.clearColor(0.0, 0.0, 0.0, 1.0);
1704 this.m_ctx
.clear(gl
.COLOR_BUFFER_BIT
);
1706 this.m_ctx
.useProgram(this.m_programID
);
1708 this.m_ctx
.uniform1f(this.m_ctx
.getUniformLocation(this.m_programID
, 'u_coordScale'), coordScale
);
1709 this.m_ctx
.uniform1f(this.m_ctx
.getUniformLocation(this.m_programID
, 'u_colorScale'), colorScale
);
1712 this.m_ctx
.bindVertexArray(this.m_vaoID
);
1715 indexArray
.bindIndexArray(glsDrawTests
.DrawTestSpec
.Target
.ELEMENT_ARRAY
);
1717 for (var arrayNdx
= 0; arrayNdx
< this.m_arrays
.length
; arrayNdx
++) {
1718 var attribName
= '';
1719 attribName
+= 'a_' + arrayNdx
;
1721 var loc
= this.m_ctx
.getAttribLocation(this.m_programID
, attribName
);
1723 if (this.m_arrays
[arrayNdx
].isBound())
1724 this.m_ctx
.enableVertexAttribArray(loc
);
1726 this.m_arrays
[arrayNdx
].bindAttribute(loc
);
1729 if (drawMethod
== glsDrawTests
.DrawTestSpec
.DrawMethod
.DRAWARRAYS
)
1730 this.m_ctx
.drawArrays(glsDrawTests
.primitiveToGL(primitive
), firstVertex
, vertexCount
);
1731 else if (drawMethod
== glsDrawTests
.DrawTestSpec
.DrawMethod
.DRAWARRAYS_INSTANCED
)
1732 this.m_ctx
.drawArraysInstanced(glsDrawTests
.primitiveToGL(primitive
), firstVertex
, vertexCount
, instanceCount
);
1733 else if (drawMethod
== glsDrawTests
.DrawTestSpec
.DrawMethod
.DRAWELEMENTS
)
1734 this.m_ctx
.drawElements(glsDrawTests
.primitiveToGL(primitive
), vertexCount
, glsDrawTests
.indexTypeToGL(indexType
), indexOffset
);
1735 else if (drawMethod
== glsDrawTests
.DrawTestSpec
.DrawMethod
.DRAWELEMENTS_RANGED
)
1736 this.m_ctx
.drawRangeElements(glsDrawTests
.primitiveToGL(primitive
), rangeStart
, rangeEnd
, vertexCount
, glsDrawTests
.indexTypeToGL(indexType
), indexOffset
);
1737 else if (drawMethod
== glsDrawTests
.DrawTestSpec
.DrawMethod
.DRAWELEMENTS_INSTANCED
)
1738 this.m_ctx
.drawElementsInstanced(glsDrawTests
.primitiveToGL(primitive
), vertexCount
, glsDrawTests
.indexTypeToGL(indexType
), indexOffset
, instanceCount
);
1740 throw new Error('Invalid draw method');
1742 for (var arrayNdx
= 0; arrayNdx
< this.m_arrays
.length
; arrayNdx
++) {
1743 if (this.m_arrays
[arrayNdx
].isBound()) {
1744 var attribName
= '';
1745 attribName
+= 'a_' + arrayNdx
;
1747 var loc
= this.m_ctx
.getAttribLocation(this.m_programID
, attribName
);
1749 this.m_ctx
.disableVertexAttribArray(loc
);
1754 this.m_ctx
.bindVertexArray(null);
1756 this.m_ctx
.useProgram(null);
1757 this.m_screen
.readViewport(this.m_ctx
, [0 , 0, this.m_screen
.getWidth(), this.m_screen
.getHeight()]);
1765 glsDrawTests
.DrawTestSpec = function() {
1766 /** @type {?glsDrawTests.DrawTestSpec.Primitive} */ this.primitive
= null;
1767 /** @type {number} */ this.primitiveCount
= 0; //!< number of primitives to draw (per instance)
1769 /** @type {?glsDrawTests.DrawTestSpec.DrawMethod} */ this.drawMethod
= null;
1770 /** @type {?glsDrawTests.DrawTestSpec.IndexType} */ this.indexType
= null; //!< used only if drawMethod = DrawElements*
1771 /** @type {number} */ this.indexPointerOffset
= 0; //!< used only if drawMethod = DrawElements*
1772 /** @type {?glsDrawTests.DrawTestSpec.Storage} */ this.indexStorage
= null; //!< used only if drawMethod = DrawElements*
1773 /** @type {number} */ this.first
= 0; //!< used only if drawMethod = DrawArrays*
1774 /** @type {number} */ this.indexMin
= 0; //!< used only if drawMethod = Draw*Ranged
1775 /** @type {number} */ this.indexMax
= 0; //!< used only if drawMethod = Draw*Ranged
1776 /** @type {number} */ this.instanceCount
= 0; //!< used only if drawMethod = Draw*Instanced or Draw*Indirect
1777 /** @type {number} */ this.indirectOffset
= 0; //!< used only if drawMethod = Draw*Indirect
1778 /** @type {number} */ this.baseVertex
= 0; //!< used only if drawMethod = DrawElementsIndirect or *BaseVertex
1780 /** @type {Array<glsDrawTests.DrawTestSpec.AttributeSpec>} */ this.attribs
= [];
1784 * @param {glsDrawTests.DrawTestSpec.Target} target
1787 glsDrawTests
.DrawTestSpec
.targetToString = function(target
) {
1788 assertMsgOptions(target
!= null, 'Target is null', false, true);
1791 'element_array', // TARGET_ELEMENT_ARRAY = 0,
1792 'array' // TARGET_ARRAY,
1794 assertMsgOptions(targets
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.Target
).length
,
1795 'The amount of target names is different than the amount of targets', false, true);
1797 return targets
[target
];
1801 * @param {?glsDrawTests.DrawTestSpec.InputType} type
1804 glsDrawTests
.DrawTestSpec
.inputTypeToString = function(type
) {
1805 assertMsgOptions(type
!= null, 'Type is null', false, true);
1808 'float', // INPUTTYPE_FLOAT = 0,
1810 'byte', // INPUTTYPE_BYTE,
1811 'short', // INPUTTYPE_SHORT,
1813 'unsigned_byte', // INPUTTYPE_UNSIGNED_BYTE,
1814 'unsigned_short', // INPUTTYPE_UNSIGNED_SHORT,
1816 'int', // INPUTTYPE_INT,
1817 'unsigned_int', // INPUTTYPE_UNSIGNED_INT,
1818 'half', // INPUTTYPE_HALF,
1819 'unsigned_int2_10_10_10', // INPUTTYPE_UNSIGNED_INT_2_10_10_10,
1820 'int2_10_10_10' // INPUTTYPE_INT_2_10_10_10,
1822 assertMsgOptions(types
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.InputType
).length
,
1823 'The amount of type names is different than the amount of types', false, true);
1829 * @param {?glsDrawTests.DrawTestSpec.OutputType} type
1832 glsDrawTests
.DrawTestSpec
.outputTypeToString = function(type
) {
1833 assertMsgOptions(type
!= null, 'Type is null', false, true);
1836 'float', // OUTPUTTYPE_FLOAT = 0,
1837 'vec2', // OUTPUTTYPE_VEC2,
1838 'vec3', // OUTPUTTYPE_VEC3,
1839 'vec4', // OUTPUTTYPE_VEC4,
1841 'int', // OUTPUTTYPE_INT,
1842 'uint', // OUTPUTTYPE_UINT,
1844 'ivec2', // OUTPUTTYPE_IVEC2,
1845 'ivec3', // OUTPUTTYPE_IVEC3,
1846 'ivec4', // OUTPUTTYPE_IVEC4,
1848 'uvec2', // OUTPUTTYPE_UVEC2,
1849 'uvec3', // OUTPUTTYPE_UVEC3,
1850 'uvec4' // OUTPUTTYPE_UVEC4,
1852 assertMsgOptions(types
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.OutputType
).length
,
1853 'The amount of type names is different than the amount of types', false, true);
1859 * @param {?glsDrawTests.DrawTestSpec.Usage} usage
1862 glsDrawTests
.DrawTestSpec
.usageTypeToString = function(usage
) {
1863 assertMsgOptions(usage
!= null, 'Usage is null', false, true);
1866 'dynamic_draw', // USAGE_DYNAMIC_DRAW = 0,
1867 'static_draw', // USAGE_STATIC_DRAW,
1868 'stream_draw', // USAGE_STREAM_DRAW,
1870 'stream_read', // USAGE_STREAM_READ,
1871 'stream_copy', // USAGE_STREAM_COPY,
1873 'static_read', // USAGE_STATIC_READ,
1874 'static_copy', // USAGE_STATIC_COPY,
1876 'dynamic_read', // USAGE_DYNAMIC_READ,
1877 'dynamic_copy' // USAGE_DYNAMIC_COPY,
1879 assertMsgOptions(usages
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.Usage
).length
,
1880 'The amount of usage names is different than the amount of usages', false, true);
1882 return usages
[usage
];
1886 * @param {?glsDrawTests.DrawTestSpec.Storage} storage
1889 glsDrawTests
.DrawTestSpec
.storageToString = function(storage
) {
1890 assertMsgOptions(storage
!= null, 'Storage is null', false, true);
1893 'user_ptr', // STORAGE_USER = 0,
1894 'buffer' // STORAGE_BUFFER,
1896 assertMsgOptions(storages
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.Storage
).length
,
1897 'The amount of storage names is different than the amount of storages', false, true);
1899 return storages
[storage
];
1903 * @param {glsDrawTests.DrawTestSpec.Primitive} primitive
1906 glsDrawTests
.DrawTestSpec
.primitiveToString = function(primitive
) {
1907 assertMsgOptions(primitive
!= null, 'Primitive is null', false, true);
1910 'points', // PRIMITIVE_POINTS ,
1911 'triangles', // PRIMITIVE_TRIANGLES,
1912 'triangle_fan', // PRIMITIVE_TRIANGLE_FAN,
1913 'triangle_strip', // PRIMITIVE_TRIANGLE_STRIP,
1914 'lines', // PRIMITIVE_LINES
1915 'line_strip', // PRIMITIVE_LINE_STRIP
1918 assertMsgOptions(primitives
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.Primitive
).length
,
1919 'The amount of primitive names is different than the amount of primitives', false, true);
1921 return primitives
[primitive
];
1925 * @param {?glsDrawTests.DrawTestSpec.IndexType} type
1928 glsDrawTests
.DrawTestSpec
.indexTypeToString = function(type
) {
1929 assertMsgOptions(type
!= null, 'Index type is null', false, true);
1932 'byte', // INDEXTYPE_BYTE = 0,
1933 'short', // INDEXTYPE_SHORT,
1934 'int' // INDEXTYPE_INT,
1936 assertMsgOptions(indexTypes
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.IndexType
).length
,
1937 'The amount of index type names is different than the amount of index types', false, true);
1939 return indexTypes
[type
];
1943 * @param {?glsDrawTests.DrawTestSpec.DrawMethod} method
1946 glsDrawTests
.DrawTestSpec
.drawMethodToString = function(method
) {
1947 assertMsgOptions(method
!= null, 'Method is null', false, true);
1950 'draw_arrays', //!< DRAWMETHOD_DRAWARRAYS
1951 'draw_arrays_instanced', //!< DRAWMETHOD_DRAWARRAYS_INSTANCED
1952 'draw_elements', //!< DRAWMETHOD_DRAWELEMENTS
1953 'draw_range_elements', //!< DRAWMETHOD_DRAWELEMENTS_RANGED
1954 'draw_elements_instanced' //!< DRAWMETHOD_DRAWELEMENTS_INSTANCED
1956 assertMsgOptions(methods
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.DrawMethod
).length
,
1957 'The amount of method names is different than the amount of methods', false, true);
1959 return methods
[method
];
1963 * @param {?glsDrawTests.DrawTestSpec.InputType} type
1966 glsDrawTests
.DrawTestSpec
.inputTypeSize = function(type
) {
1967 assertMsgOptions(type
!= null, 'Input type is null', false, true);
1970 4, // INPUTTYPE_FLOAT = 0,
1972 1, // INPUTTYPE_BYTE,
1973 2, // INPUTTYPE_SHORT,
1975 1, // INPUTTYPE_UNSIGNED_BYTE,
1976 2, // INPUTTYPE_UNSIGNED_SHORT,
1978 4, // INPUTTYPE_INT,
1979 4, // INPUTTYPE_UNSIGNED_INT,
1980 2, // INPUTTYPE_HALF,
1981 4 / 4, // INPUTTYPE_UNSIGNED_INT_2_10_10_10,
1982 4 / 4 // INPUTTYPE_INT_2_10_10_10,
1984 assertMsgOptions(size
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.InputType
).length
,
1985 'The amount of type names is different than the amount of types', false, true);
1991 * @param {?glsDrawTests.DrawTestSpec.IndexType} type
1994 glsDrawTests
.DrawTestSpec
.indexTypeSize = function(type
) {
1995 assertMsgOptions(type
!= null, 'Type is null', false, true);
1998 1, // INDEXTYPE_BYTE,
1999 2, // INDEXTYPE_SHORT,
2002 assertMsgOptions(size
.length
== Object
.keys(glsDrawTests
.DrawTestSpec
.IndexType
).length
,
2003 'The amount of type names is different than the amount of types', false, true);
2011 glsDrawTests
.DrawTestSpec
.prototype.getName = function() {
2012 /** @type {glsDrawTests.MethodInfo} */ var methodInfo
= glsDrawTests
.getMethodInfo(this.drawMethod
);
2013 /** @type {boolean} */ var hasFirst
= methodInfo
.first
;
2014 /** @type {boolean} */ var instanced
= methodInfo
.instanced
;
2015 /** @type {boolean} */ var ranged
= methodInfo
.ranged
;
2016 /** @type {boolean} */ var indexed
= methodInfo
.indexed
;
2020 for (var ndx
= 0; ndx
< this.attribs
.length
; ++ndx
) {
2021 /** @type {glsDrawTests.DrawTestSpec.AttributeSpec}*/ var attrib
= this.attribs
[ndx
];
2023 if (this.attribs
.length
> 1)
2024 name
+= 'attrib' + ndx
+ '_';
2026 if (ndx
== 0 || attrib
.additionalPositionAttribute
)
2031 if (attrib
.useDefaultAttribute
) {
2032 name
+= 'non_array_' +
2033 glsDrawTests
.DrawTestSpec
.inputTypeToString(/** @type {?glsDrawTests.DrawTestSpec.InputType} */ (attrib
.inputType
)) + '_' +
2034 attrib
.componentCount
+ '_' +
2035 glsDrawTests
.DrawTestSpec
.outputTypeToString(attrib
.outputType
) + '_';
2037 name
+= glsDrawTests
.DrawTestSpec
.storageToString(attrib
.storage
) + '_' +
2038 attrib
.offset
+ '_' +
2039 attrib
.stride
+ '_' +
2040 glsDrawTests
.DrawTestSpec
.inputTypeToString(/** @type {?glsDrawTests.DrawTestSpec.InputType} */ (attrib
.inputType
));
2041 if (attrib
.inputType
!= glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT_2_10_10_10
&& attrib
.inputType
!= glsDrawTests
.DrawTestSpec
.InputType
.INT_2_10_10_10
)
2042 name
+= attrib
.componentCount
;
2044 (attrib
.normalize
? 'normalized_' : '') +
2045 glsDrawTests
.DrawTestSpec
.outputTypeToString(attrib
.outputType
) + '_' +
2046 glsDrawTests
.DrawTestSpec
.usageTypeToString(attrib
.usage
) + '_' +
2047 attrib
.instanceDivisor
+ '_';
2052 name
+= 'index_' + glsDrawTests
.DrawTestSpec
.indexTypeToString(this.indexType
) + '_' +
2053 glsDrawTests
.DrawTestSpec
.storageToString(this.indexStorage
) + '_' +
2054 'offset' + this.indexPointerOffset
+ '_';
2056 name
+= 'first' + this.first
+ '_';
2058 name
+= 'ranged_' + this.indexMin
+ '_' + this.indexMax
+ '_';
2060 name
+= 'instances' + this.instanceCount
+ '_';
2062 switch (this.primitive
) {
2063 case glsDrawTests
.DrawTestSpec
.Primitive
.POINTS
:
2066 case glsDrawTests
.DrawTestSpec
.Primitive
.TRIANGLES
:
2067 name
+= 'triangles_';
2069 case glsDrawTests
.DrawTestSpec
.Primitive
.TRIANGLE_FAN
:
2070 name
+= 'triangle_fan_';
2072 case glsDrawTests
.DrawTestSpec
.Primitive
.TRIANGLE_STRIP
:
2073 name
+= 'triangle_strip_';
2075 case glsDrawTests
.DrawTestSpec
.Primitive
.LINES
:
2078 case glsDrawTests
.DrawTestSpec
.Primitive
.LINE_STRIP
:
2079 name
+= 'line_strip_';
2081 case glsDrawTests
.DrawTestSpec
.Primitive
.LINE_LOOP
:
2082 name
+= 'line_loop_';
2085 throw new Error('Invalid primitive');
2089 name
+= this.primitiveCount
;
2097 glsDrawTests
.DrawTestSpec
.prototype.getDesc = function() {
2100 for (var ndx
= 0; ndx
< this.attribs
.length
; ++ndx
) {
2101 /** @type {glsDrawTests.DrawTestSpec.AttributeSpec} */ var attrib
= this.attribs
[ndx
];
2103 if (attrib
.useDefaultAttribute
) {
2104 desc
+= 'Attribute ' + ndx
+ ': default, ' + ((ndx
== 0 || attrib
.additionalPositionAttribute
) ? ('position ,') : ('color ,')) +
2105 'input datatype ' + glsDrawTests
.DrawTestSpec
.inputTypeToString(/** @type {?glsDrawTests.DrawTestSpec.InputType} */ (attrib
.inputType
)) + ', ' +
2106 'input component count ' + attrib
.componentCount
+ ', ' +
2107 'used as ' + glsDrawTests
.DrawTestSpec
.outputTypeToString(attrib
.outputType
) + ', ';
2109 desc
+= 'Attribute ' + ndx
+ ': ' + ((ndx
== 0 || attrib
.additionalPositionAttribute
) ? ('position ,') : ('color ,')) +
2110 'Storage in ' + glsDrawTests
.DrawTestSpec
.storageToString(attrib
.storage
) + ', ' +
2111 'stride ' + attrib
.stride
+ ', ' +
2112 'input datatype ' + glsDrawTests
.DrawTestSpec
.inputTypeToString(/** @type {?glsDrawTests.DrawTestSpec.InputType} */ (attrib
.inputType
)) + ', ' +
2113 'input component count ' + attrib
.componentCount
+ ', ' +
2114 (attrib
.normalize
? 'normalized, ' : '') +
2115 'used as ' + glsDrawTests
.DrawTestSpec
.outputTypeToString(attrib
.outputType
) + ', ' +
2116 'instance divisor ' + attrib
.instanceDivisor
+ ', ';
2120 if (this.drawMethod
== glsDrawTests
.DrawTestSpec
.DrawMethod
.DRAWARRAYS
) {
2121 desc
+= 'drawArrays(), ' +
2122 'first ' + this.first
+ ', ';
2123 } else if (this.drawMethod
== glsDrawTests
.DrawTestSpec
.DrawMethod
.DRAWARRAYS_INSTANCED
) {
2124 desc
+= 'drawArraysInstanced(), ' +
2125 'first ' + this.first
+ ', ' +
2126 'instance count ' + this.instanceCount
+ ', ';
2127 } else if (this.drawMethod
== glsDrawTests
.DrawTestSpec
.DrawMethod
.DRAWELEMENTS
) {
2128 desc
+= 'drawElements(), ' +
2129 'index type ' + glsDrawTests
.DrawTestSpec
.indexTypeToString(this.indexType
) + ', ' +
2130 'index storage in ' + glsDrawTests
.DrawTestSpec
.storageToString(this.indexStorage
) + ', ' +
2131 'index offset ' + this.indexPointerOffset
+ ', ';
2132 } else if (this.drawMethod
== glsDrawTests
.DrawTestSpec
.DrawMethod
.DRAWELEMENTS_RANGED
) {
2133 desc
+= 'drawElementsRanged(), ' +
2134 'index type ' + glsDrawTests
.DrawTestSpec
.indexTypeToString(this.indexType
) + ', ' +
2135 'index storage in ' + glsDrawTests
.DrawTestSpec
.storageToString(this.indexStorage
) + ', ' +
2136 'index offset ' + this.indexPointerOffset
+ ', ' +
2137 'range start ' + this.indexMin
+ ', ' +
2138 'range end ' + this.indexMax
+ ', ';
2139 } else if (this.drawMethod
== glsDrawTests
.DrawTestSpec
.DrawMethod
.DRAWELEMENTS_INSTANCED
) {
2140 desc
+= 'drawElementsInstanced(), ' +
2141 'index type ' + glsDrawTests
.DrawTestSpec
.indexTypeToString(this.indexType
) + ', ' +
2142 'index storage in ' + glsDrawTests
.DrawTestSpec
.storageToString(this.indexStorage
) + ', ' +
2143 'index offset ' + this.indexPointerOffset
+ ', ' +
2144 'instance count ' + this.instanceCount
+ ', ';
2146 throw new Error('Invalid draw method');
2148 desc
+= this.primitiveCount
;
2150 switch (this.primitive
) {
2151 case glsDrawTests
.DrawTestSpec
.Primitive
.POINTS
:
2154 case glsDrawTests
.DrawTestSpec
.Primitive
.TRIANGLES
:
2155 desc
+= 'triangles';
2157 case glsDrawTests
.DrawTestSpec
.Primitive
.TRIANGLE_FAN
:
2158 desc
+= 'triangles (fan)';
2160 case glsDrawTests
.DrawTestSpec
.Primitive
.TRIANGLE_STRIP
:
2161 desc
+= 'triangles (strip)';
2163 case glsDrawTests
.DrawTestSpec
.Primitive
.LINES
:
2166 case glsDrawTests
.DrawTestSpec
.Primitive
.LINE_STRIP
:
2167 desc
+= 'lines (strip)';
2169 case glsDrawTests
.DrawTestSpec
.Primitive
.LINE_LOOP
:
2170 desc
+= 'lines (loop)';
2173 throw new Error('Invalid primitive');
2183 glsDrawTests
.DrawTestSpec
.prototype.getMultilineDesc = function() {
2186 for (var ndx
= 0; ndx
< this.attribs
.length
; ++ndx
) {
2187 /** @type {glsDrawTests.DrawTestSpec.AttributeSpec} */ var attrib
= this.attribs
[ndx
];
2189 if (attrib
.useDefaultAttribute
) {
2190 desc
+= 'Attribute ' + ndx
+ ': default, ' + ((ndx
== 0 || attrib
.additionalPositionAttribute
) ? ('position\n') : ('color\n')) +
2191 '\tinput datatype ' + glsDrawTests
.DrawTestSpec
.inputTypeToString(/** @type {?glsDrawTests.DrawTestSpec.InputType} */ (attrib
.inputType
)) + '\n' +
2192 '\tinput component count ' + attrib
.componentCount
+ '\n' +
2193 '\tused as ' + glsDrawTests
.DrawTestSpec
.outputTypeToString(attrib
.outputType
) + '\n';
2195 desc
+= 'Attribute ' + ndx
+ ': ' + ((ndx
== 0 || attrib
.additionalPositionAttribute
) ? ('position\n') : ('color\n')) +
2196 '\tStorage in ' + glsDrawTests
.DrawTestSpec
.storageToString(attrib
.storage
) + '\n' +
2197 '\tstride ' + attrib
.stride
+ '\n' +
2198 '\tinput datatype ' + glsDrawTests
.DrawTestSpec
.inputTypeToString(/** @type {?glsDrawTests.DrawTestSpec.InputType} */ (attrib
.inputType
)) + '\n' +
2199 '\tinput component count ' + attrib
.componentCount
+ '\n' +
2200 (attrib
.normalize
? '\tnormalized\n' : '') +
2201 '\tused as ' + glsDrawTests
.DrawTestSpec
.outputTypeToString(attrib
.outputType
) + '\n' +
2202 '\tinstance divisor ' + attrib
.instanceDivisor
+ '\n';
2206 if (this.drawMethod
== glsDrawTests
.DrawTestSpec
.DrawMethod
.DRAWARRAYS
) {
2207 desc
+= 'drawArrays()\n' +
2208 '\tfirst ' + this.first
+ '\n';
2209 } else if (this.drawMethod
== glsDrawTests
.DrawTestSpec
.DrawMethod
.DRAWARRAYS_INSTANCED
) {
2210 desc
+= 'drawArraysInstanced()\n' +
2211 '\tfirst ' + this.first
+ '\n' +
2212 '\tinstance count ' + this.instanceCount
+ '\n';
2213 } else if (this.drawMethod
== glsDrawTests
.DrawTestSpec
.DrawMethod
.DRAWELEMENTS
) {
2214 desc
+= 'drawElements()\n' +
2215 '\tindex type ' + glsDrawTests
.DrawTestSpec
.indexTypeToString(this.indexType
) + '\n' +
2216 '\tindex storage in ' + glsDrawTests
.DrawTestSpec
.storageToString(this.indexStorage
) + '\n' +
2217 '\tindex offset ' + this.indexPointerOffset
+ '\n';
2218 } else if (this.drawMethod
== glsDrawTests
.DrawTestSpec
.DrawMethod
.DRAWELEMENTS_RANGED
) {
2219 desc
+= 'drawElementsRanged()\n' +
2220 '\tindex type ' + glsDrawTests
.DrawTestSpec
.indexTypeToString(this.indexType
) + '\n' +
2221 '\tindex storage in ' + glsDrawTests
.DrawTestSpec
.storageToString(this.indexStorage
) + '\n' +
2222 '\tindex offset ' + this.indexPointerOffset
+ '\n' +
2223 '\trange start ' + this.indexMin
+ '\n' +
2224 '\trange end ' + this.indexMax
+ '\n';
2225 } else if (this.drawMethod
== glsDrawTests
.DrawTestSpec
.DrawMethod
.DRAWELEMENTS_INSTANCED
) {
2226 desc
+= 'drawElementsInstanced()\n' +
2227 '\tindex type ' + glsDrawTests
.DrawTestSpec
.indexTypeToString(this.indexType
) + '\n' +
2228 '\tindex storage in ' + glsDrawTests
.DrawTestSpec
.storageToString(this.indexStorage
) + '\n' +
2229 '\tindex offset ' + this.indexPointerOffset
+ '\n' +
2230 '\tinstance count ' + this.instanceCount
+ '\n';
2232 throw new Error('Invalid draw method');
2234 desc
+= '\t' + this.primitiveCount
+ ' ';
2236 switch (this.primitive
) {
2237 case glsDrawTests
.DrawTestSpec
.Primitive
.POINTS
:
2240 case glsDrawTests
.DrawTestSpec
.Primitive
.TRIANGLES
:
2241 desc
+= 'triangles';
2243 case glsDrawTests
.DrawTestSpec
.Primitive
.TRIANGLE_FAN
:
2244 desc
+= 'triangles (fan)';
2246 case glsDrawTests
.DrawTestSpec
.Primitive
.TRIANGLE_STRIP
:
2247 desc
+= 'triangles (strip)';
2249 case glsDrawTests
.DrawTestSpec
.Primitive
.LINES
:
2252 case glsDrawTests
.DrawTestSpec
.Primitive
.LINE_STRIP
:
2253 desc
+= 'lines (strip)';
2255 case glsDrawTests
.DrawTestSpec
.Primitive
.LINE_LOOP
:
2256 desc
+= 'lines (loop)';
2259 throw new Error('Invalid primitive');
2271 glsDrawTests
.DrawTestSpec
.Target
= {
2279 glsDrawTests
.DrawTestSpec
.InputType
= {
2291 UNSIGNED_INT_2_10_10_10
: 8,
2298 glsDrawTests
.DrawTestSpec
.OutputType
= {
2319 glsDrawTests
.DrawTestSpec
.Usage
= {
2337 glsDrawTests
.DrawTestSpec
.Storage
= {
2345 glsDrawTests
.DrawTestSpec
.Primitive
= {
2358 glsDrawTests
.DrawTestSpec
.IndexType
= {
2367 glsDrawTests
.DrawTestSpec
.DrawMethod
= {
2369 DRAWARRAYS_INSTANCED
: 1,
2371 DRAWELEMENTS_RANGED
: 3,
2372 DRAWELEMENTS_INSTANCED
: 4
2378 glsDrawTests
.DrawTestSpec
.CompatibilityTestType
= {
2380 UNALIGNED_OFFSET
: 1,
2387 glsDrawTests
.DrawTestSpec
.prototype.hash = function() {
2388 // Use only drawmode-relevant values in "hashing" as the unrelevant values might not be set (causing non-deterministic behavior).
2389 /** @type {glsDrawTests.MethodInfo} */ var methodInfo
= glsDrawTests
.getMethodInfo(this.drawMethod
);
2390 /** @type {boolean} */ var arrayed
= methodInfo
.first
;
2391 /** @type {boolean} */ var instanced
= methodInfo
.instanced
;
2392 /** @type {boolean} */ var ranged
= methodInfo
.ranged
;
2393 /** @type {boolean} */ var indexed
= methodInfo
.indexed
;
2395 /** @type {number} */ var indexHash
= (!indexed
) ? (0) : (this.indexType
+ 10 * this.indexPointerOffset
+ 100 * this.indexStorage
);
2396 /** @type {number} */ var arrayHash
= (!arrayed
) ? (0) : (this.first
);
2397 /** @type {number} */ var indexRangeHash
= (!ranged
) ? (0) : (this.indexMin
+ 10 * this.indexMax
);
2398 /** @type {number} */ var instanceHash
= (!instanced
) ? (0) : (this.instanceCount
);
2399 /** @type {number} */ var basicHash
= this.primitive
+ 10 * this.primitiveCount
+ 100 * this.drawMethod
;
2401 return indexHash
+ 3 * arrayHash
+ 5 * indexRangeHash
+ 7 * instanceHash
+ 13 * basicHash
+ 17 * this.attribs
.length
+ 19 * this.primitiveCount
;
2407 glsDrawTests
.DrawTestSpec
.prototype.valid = function() {
2408 assertMsgOptions(this.primitive
!= null, 'Primitive is null', false, true);
2409 assertMsgOptions(this.drawMethod
!= null, 'Draw method is null', false, true);
2411 var methodInfo
= glsDrawTests
.getMethodInfo(this.drawMethod
);
2413 if (methodInfo
.ranged
) {
2414 var maxIndexValue
= 0;
2415 if (this.indexType
== glsDrawTests
.DrawTestSpec
.IndexType
.BYTE
)
2416 maxIndexValue
= glsDrawTests
.GLValue
.getMaxValue(glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_BYTE
).interpret();
2417 else if (this.indexType
== glsDrawTests
.DrawTestSpec
.IndexType
.SHORT
)
2418 maxIndexValue
= glsDrawTests
.GLValue
.getMaxValue(glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_SHORT
).interpret();
2419 else if (this.indexType
== glsDrawTests
.DrawTestSpec
.IndexType
.INT
)
2420 maxIndexValue
= glsDrawTests
.GLValue
.getMaxValue(glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT
).interpret();
2422 throw new Error('Invalid index type');
2424 if (this.indexMin
> this.indexMax
)
2426 if (this.indexMin
< 0 || this.indexMax
< 0)
2428 if (this.indexMin
> maxIndexValue
|| this.indexMax
> maxIndexValue
)
2432 if (methodInfo
.first
&& this.first
< 0)
2439 * @return {glsDrawTests.DrawTestSpec.CompatibilityTestType}
2441 glsDrawTests
.DrawTestSpec
.prototype.isCompatibilityTest = function() {
2442 var methodInfo
= glsDrawTests
.getMethodInfo(this.drawMethod
);
2444 var bufferAlignmentBad
= false;
2445 var strideAlignmentBad
= false;
2447 // Attribute buffer alignment
2448 for (var ndx
= 0; ndx
< this.attribs
.length
; ++ndx
)
2449 if (!this.attribs
[ndx
].isBufferAligned())
2450 bufferAlignmentBad
= true;
2452 // Attribute stride alignment
2453 for (var ndx
= 0; ndx
< this.attribs
.length
; ++ndx
)
2454 if (!this.attribs
[ndx
].isBufferStrideAligned())
2455 strideAlignmentBad
= true;
2457 // Index buffer alignment
2458 if (methodInfo
.indexed
) {
2459 if (this.indexStorage
== glsDrawTests
.DrawTestSpec
.Storage
.BUFFER
) {
2461 if (this.indexType
== glsDrawTests
.DrawTestSpec
.IndexType
.BYTE
)
2463 else if (this.indexType
== glsDrawTests
.DrawTestSpec
.IndexType
.SHORT
)
2465 else if (this.indexType
== glsDrawTests
.DrawTestSpec
.IndexType
.INT
)
2468 throw new Error('');
2470 if (this.indexPointerOffset
% indexSize
!= 0)
2471 bufferAlignmentBad
= true;
2475 // \note combination bad alignment & stride is treated as bad offset
2476 if (bufferAlignmentBad
)
2477 return glsDrawTests
.DrawTestSpec
.CompatibilityTestType
.UNALIGNED_OFFSET
;
2478 else if (strideAlignmentBad
)
2479 return glsDrawTests
.DrawTestSpec
.CompatibilityTestType
.UNALIGNED_STRIDE
;
2481 return glsDrawTests
.DrawTestSpec
.CompatibilityTestType
.NONE
;
2484 // DrawTestSpec.AttributeSpec
2489 glsDrawTests
.DrawTestSpec
.AttributeSpec = function() {
2490 /** @type {?glsDrawTests.DrawTestSpec.InputType} */ this.inputType
= null;
2491 /** @type {?glsDrawTests.DrawTestSpec.OutputType} */ this.outputType
= null;
2492 /** @type {?glsDrawTests.DrawTestSpec.Storage} */ this.storage
= glsDrawTests
.DrawTestSpec
.Storage
.BUFFER
; //Always BUFFER in WebGL up to 2
2493 /** @type {?glsDrawTests.DrawTestSpec.Usage} */ this.usage
= null;
2494 /** @type {number} */ this.componentCount
= 0;
2495 /** @type {number} */ this.offset
= 0;
2496 /** @type {number} */ this.stride
= 0;
2497 /** @type {boolean} */ this.normalize
= false;
2498 /** @type {number} */ this.instanceDivisor
= 0; //!< used only if drawMethod = Draw*Instanced
2499 /** @type {boolean} */ this.useDefaultAttribute
= false;
2501 /** @type {boolean} */ this.additionalPositionAttribute
= false; //!< treat this attribute as position attribute. Attribute at index 0 is alway treated as such. False by default
2505 * @param {?glsDrawTests.DrawTestSpec.InputType} inputType
2506 * @param {?glsDrawTests.DrawTestSpec.OutputType} outputType
2507 * @param {?glsDrawTests.DrawTestSpec.Storage} storage
2508 * @param {?glsDrawTests.DrawTestSpec.Usage} usage
2509 * @param {number} componentCount
2510 * @param {number} offset
2511 * @param {number} stride
2512 * @param {boolean} normalize
2513 * @param {number} instanceDivisor
2514 * @return {glsDrawTests.DrawTestSpec.AttributeSpec}
2516 glsDrawTests
.DrawTestSpec
.AttributeSpec
.createAttributeArray = function(inputType
, outputType
, storage
, usage
, componentCount
,
2517 offset
, stride
, normalize
, instanceDivisor
) {
2518 /** @type {glsDrawTests.DrawTestSpec.AttributeSpec} */ var spec
;
2520 spec
.inputType
= inputType
;
2521 spec
.outputType
= outputType
;
2522 spec
.storage
= storage
;
2524 spec
.componentCount
= componentCount
;
2525 spec
.offset
= offset
;
2526 spec
.stride
= stride
;
2527 spec
.normalize
= normalize
;
2528 spec
.instanceDivisor
= instanceDivisor
;
2530 spec
.useDefaultAttribute
= false;
2536 * @param {?glsDrawTests.DrawTestSpec.InputType} inputType
2537 * @param {?glsDrawTests.DrawTestSpec.OutputType} outputType
2538 * @param {number} componentCount
2539 * @return {glsDrawTests.DrawTestSpec.AttributeSpec}
2541 glsDrawTests
.DrawTestSpec
.AttributeSpec
.createDefaultAttribute = function(inputType
, outputType
, componentCount
) {
2542 assertMsgOptions(inputType
== glsDrawTests
.DrawTestSpec
.InputType
.INT
|| inputType
== glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT
|| inputType
== glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
, 'Invalid input type', false, true);
2543 assertMsgOptions(inputType
== glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
|| componentCount
== 4, 'If not float, input type should have 4 components', false, true);
2545 /** @type {glsDrawTests.DrawTestSpec.AttributeSpec} */ var spec
;
2547 spec
.inputType
= inputType
;
2548 spec
.outputType
= outputType
;
2549 spec
.storage
= glsDrawTests
.DrawTestSpec
.Storage
.BUFFER
; //Always BUFFER in WebGL up to 2
2551 spec
.componentCount
= componentCount
;
2554 spec
.normalize
= false;
2555 spec
.instanceDivisor
= 0;
2557 spec
.useDefaultAttribute
= true;
2565 glsDrawTests
.DrawTestSpec
.AttributeSpec
.prototype.hash = function() {
2566 if (this.useDefaultAttribute
) {
2567 return 1 * this.inputType
+ 7 * this.outputType
+ 13 * this.componentCount
;
2569 return 1 * this.inputType
+ 2 * this.outputType
+ 3 * this.storage
+ 5 * this.usage
+ 7 * this.componentCount
+ 11 * this.offset
+ 13 * this.stride
+ 17 * (this.normalize
? 0 : 1) + 19 * this.instanceDivisor
;
2576 glsDrawTests
.DrawTestSpec
.AttributeSpec
.prototype.valid = function(/*ctxType*/) {
2577 /** @type {boolean} */ var inputTypeFloat
= this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
|| this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.HALF
;
2578 /** @type {boolean} */ var inputTypeUnsignedInteger
= this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_BYTE
|| this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_SHORT
|| this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT
|| this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT_2_10_10_10
;
2579 /** @type {boolean} */ var inputTypeSignedInteger
= this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.BYTE
|| this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.SHORT
|| this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.INT
|| this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.INT_2_10_10_10
;
2580 /** @type {boolean} */ var inputTypePacked
= this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT_2_10_10_10
|| this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.INT_2_10_10_10
;
2582 /** @type {boolean} */ var outputTypeFloat
= this.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.FLOAT
|| this.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.VEC2
|| this.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.VEC3
|| this.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.VEC4
;
2583 /** @type {boolean} */ var outputTypeSignedInteger
= this.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.INT
|| this.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.IVEC2
|| this.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.IVEC3
|| this.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.IVEC4
;
2584 /** @type {boolean} */ var outputTypeUnsignedInteger
= this.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.UINT
|| this.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.UVEC2
|| this.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.UVEC3
|| this.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.UVEC4
;
2586 if (this.useDefaultAttribute
) {
2587 if (this.inputType
!= glsDrawTests
.DrawTestSpec
.InputType
.INT
&& this.inputType
!= glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT
&& this.inputType
!= glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
)
2590 if (this.inputType
!= glsDrawTests
.DrawTestSpec
.InputType
.FLOAT
&& this.componentCount
!= 4)
2593 // no casting allowed (undefined results)
2594 if (this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.INT
&& !outputTypeSignedInteger
)
2596 if (this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT
&& !outputTypeUnsignedInteger
)
2600 if (inputTypePacked
&& this.componentCount
!= 4)
2603 // Invalid conversions:
2606 if (inputTypeFloat
&& !outputTypeFloat
)
2609 // uint -> int (undefined results)
2610 if (inputTypeUnsignedInteger
&& outputTypeSignedInteger
)
2613 // int -> uint (undefined results)
2614 if (inputTypeSignedInteger
&& outputTypeUnsignedInteger
)
2617 // packed -> non-float (packed formats are converted to floats)
2618 if (inputTypePacked
&& !outputTypeFloat
)
2621 // Invalid normalize. Normalize is only valid if output type is float
2622 if (this.normalize
&& !outputTypeFloat
)
2631 glsDrawTests
.DrawTestSpec
.AttributeSpec
.prototype.isBufferAligned = function() {
2632 var inputTypePacked
= this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT_2_10_10_10
|| this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.INT_2_10_10_10
;
2634 // Buffer alignment, offset is a multiple of underlying data type size?
2635 if (this.storage
== glsDrawTests
.DrawTestSpec
.Storage
.BUFFER
) {
2636 var dataTypeSize
= glsDrawTests
.DrawTestSpec
.inputTypeSize(this.inputType
);
2637 if (inputTypePacked
)
2640 if (this.offset
% dataTypeSize
!= 0)
2650 glsDrawTests
.DrawTestSpec
.AttributeSpec
.prototype.isBufferStrideAligned = function() {
2651 var inputTypePacked
= this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT_2_10_10_10
|| this.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.INT_2_10_10_10
;
2653 // Buffer alignment, offset is a multiple of underlying data type size?
2654 if (this.storage
== glsDrawTests
.DrawTestSpec
.Storage
.BUFFER
) {
2655 var dataTypeSize
= glsDrawTests
.DrawTestSpec
.inputTypeSize(this.inputType
);
2656 if (inputTypePacked
)
2659 if (this.stride
% dataTypeSize
!= 0)
2668 * @extends {tcuTestCase.DeqpTest}
2669 * @param {glsDrawTests.DrawTestSpec} spec
2670 * @param {string} name
2671 * @param {string} desc
2673 glsDrawTests
.DrawTest = function(spec
, name
, desc
) {
2674 tcuTestCase
.DeqpTest
.call(this, name
, desc
, spec
);
2676 /** @type {WebGL2RenderingContext} */ this.m_renderCtx
= gl
;
2677 /** @type {tcuPixelFormat.PixelFormat} */ this.m_pixelformat
= new tcuPixelFormat
.PixelFormat(
2678 /** @type {number} */ (gl
.getParameter(gl
.RED_BITS
)), /** @type {number} */ (gl
.getParameter(gl
.GREEN_BITS
)),
2679 /** @type {number} */ (gl
.getParameter(gl
.BLUE_BITS
)), /** @type {number} */ (gl
.getParameter(gl
.ALPHA_BITS
))
2682 /** @type {sglrReferenceContext.ReferenceContextBuffers} */ this.m_refBuffers
= null;
2683 /** @type {sglrReferenceContext.ReferenceContext} */ this.m_refContext
= null;
2684 /** @type {sglrGLContext.GLContext} */ this.m_glesContext
= null;
2686 /** @type {glsDrawTests.AttributePack} */ this.m_glArrayPack
= null;
2687 /** @type {glsDrawTests.AttributePack} */ this.m_rrArrayPack
= null;
2689 /** @type {number} */ this.m_maxDiffRed
= -1;
2690 /** @type {number} */ this.m_maxDiffGreen
= -1;
2691 /** @type {number} */ this.m_maxDiffBlue
= -1;
2693 /** @type {Array<glsDrawTests.DrawTestSpec>} */ this.m_specs
= [];
2694 /** @type {Array<string>} */this.m_iteration_descriptions
= [];
2695 /** @type {number} */ this.m_iteration
= 0;
2698 this.addIteration(spec
);
2701 glsDrawTests
.DrawTest
.prototype = Object
.create(tcuTestCase
.DeqpTest
.prototype);
2702 glsDrawTests
.DrawTest
.prototype.constructor = glsDrawTests
.DrawTest
;
2705 * @param {glsDrawTests.DrawTestSpec} spec
2706 * @param {string=} description
2708 glsDrawTests
.DrawTest
.prototype.addIteration = function(spec
, description
) {
2710 /** @type {boolean} */ var validSpec
= spec
.valid();
2715 this.m_specs
.push(spec
);
2718 this.m_iteration_descriptions
.push(description
);
2720 this.m_iteration_descriptions
.push('');
2726 glsDrawTests
.DrawTest
.prototype.init = function() {
2727 var renderTargetWidth
= Math
.min(glsDrawTests
.MAX_RENDER_TARGET_SIZE
, gl
.canvas
.width
);
2728 var renderTargetHeight
= Math
.min(glsDrawTests
.MAX_RENDER_TARGET_SIZE
, gl
.canvas
.height
);
2729 /** @type {sglrReferenceContext.ReferenceContextLimits} */ var limits
= new sglrReferenceContext
.ReferenceContextLimits(gl
);
2730 /** @type {boolean} */ var useVao
= true;
2732 this.m_glesContext
= new sglrGLContext
.GLContext(gl
);
2734 assertMsgOptions(this.m_specs
.length
> 0, 'Specs is empty', false, true);
2736 this.m_refBuffers
= new sglrReferenceContext
.ReferenceContextBuffers(this.m_pixelformat
, 0, 0, renderTargetWidth
, renderTargetHeight
);
2737 this.m_refContext
= new sglrReferenceContext
.ReferenceContext(limits
, this.m_refBuffers
.getColorbuffer(), this.m_refBuffers
.getDepthbuffer(), this.m_refBuffers
.getStencilbuffer());
2739 this.m_glArrayPack
= new glsDrawTests
.AttributePack(this.m_glesContext
, [renderTargetWidth
, renderTargetHeight
], useVao
, true);
2740 this.m_rrArrayPack
= new glsDrawTests
.AttributePack(this.m_refContext
, [renderTargetWidth
, renderTargetHeight
], useVao
, false);
2742 this.m_maxDiffRed
= Math
.ceil(256.0 * (15.0 / (1 << this.m_pixelformat
.redBits
)));
2743 this.m_maxDiffGreen
= Math
.ceil(256.0 * (15.0 / (1 << this.m_pixelformat
.greenBits
)));
2744 this.m_maxDiffBlue
= Math
.ceil(256.0 * (15.0 / (1 << this.m_pixelformat
.blueBits
)));
2748 * @return {tcuTestCase.IterateResult}
2750 glsDrawTests
.DrawTest
.prototype.iterate = function() {
2751 var specNdx
= Math
.floor(this.m_iteration
/ 2);
2752 var drawStep
= (this.m_iteration
% 2) == 0;
2753 var compareStep
= (this.m_iteration
% 2) == 1;
2754 /** @type {tcuTestCase.IterateResult} */ var iterateResult
= (this.m_iteration
+ 1 == this.m_specs
.length
* 2) ? (tcuTestCase
.IterateResult
.STOP
) : (tcuTestCase
.IterateResult
.CONTINUE
);
2755 /** @type {glsDrawTests.DrawTestSpec} */ var spec
= this.m_specs
[specNdx
];
2756 var updateProgram
= (this.m_iteration
== 0) || (drawStep
&& !glsDrawTests
.checkSpecsShaderCompatible(this.m_specs
[specNdx
], this.m_specs
[specNdx
- 1])); // try to use the same shader in all iterations
2758 if (drawStep
&& this.m_specs
.length
!= 1)
2759 debug('Iteration ' + specNdx
+ ' of ' + (this.m_specs
.length
- 1) + ': ' + this.m_iteration_descriptions
[specNdx
]);
2764 /** @type {glsDrawTests.MethodInfo} */ var methodInfo
= glsDrawTests
.getMethodInfo(spec
.drawMethod
);
2765 /** @type {boolean} */ var indexed
= methodInfo
.indexed
;
2766 /** @type {boolean} */ var instanced
= methodInfo
.instanced
;
2767 /** @type {boolean} */ var ranged
= methodInfo
.ranged
;
2768 /** @type {boolean} */ var hasFirst
= methodInfo
.first
;
2770 /** @type {number} */ var primitiveElementCount
= glsDrawTests
.getElementCount(spec
.primitive
, spec
.primitiveCount
); // !< elements to be drawn
2771 /** @type {number} */ var indexMin
= (ranged
) ? (spec
.indexMin
) : (0);
2772 /** @type {number} */ var firstAddition
= (hasFirst
) ? (spec
.first
) : (0);
2773 /** @type {number} */ var elementCount
= primitiveElementCount
+ indexMin
+ firstAddition
; // !< elements in buffer (buffer should have at least primitiveElementCount ACCESSIBLE (index range, first) elements)
2774 /** @type {number} */ var maxElementIndex
= primitiveElementCount
+ indexMin
+ firstAddition
- 1;
2775 /** @type {number} */ var indexMax
= Math
.max(0, (ranged
) ? (deMath
.clamp(spec
.indexMax
, 0, maxElementIndex
)) : (maxElementIndex
));
2776 /** @type {number} */ var coordScale
= this.getCoordScale(spec
);
2777 /** @type {number} */ var colorScale
= this.getColorScale(spec
);
2779 /** @type {Array<number>} */ var nullAttribValue
= [];
2782 bufferedLogToConsole(spec
.getMultilineDesc());
2785 this.m_glArrayPack
.clearArrays();
2786 this.m_rrArrayPack
.clearArrays();
2789 /** @type {number} */ var seed
;
2790 /** @type {number} */ var indexElementSize
;
2791 /** @type {number} */ var indexArraySize
;
2792 /** @type {goog.TypedArray} */ var indexArray
;
2793 /** @type {goog.TypedArray} */ var indexPointer
;
2795 /** @type {glsDrawTests.AttributeArray}*/ var glArray
;
2796 /** @type {glsDrawTests.AttributeArray}*/ var rrArray
;
2800 indexElementSize
= glsDrawTests
.DrawTestSpec
.indexTypeSize(spec
.indexType
);
2801 indexArraySize
= spec
.indexPointerOffset
+ indexElementSize
* elementCount
;
2802 indexArray
= glsDrawTests
.RandomArrayGenerator
.generateIndices(seed
, elementCount
, spec
.indexType
, spec
.indexPointerOffset
, indexMin
, indexMax
);
2803 indexPointer
= indexArray
.subarray(spec
.indexPointerOffset
);
2805 glArray
= new glsDrawTests
.AttributeArray(spec
.indexStorage
, this.m_glesContext
);
2806 rrArray
= new glsDrawTests
.AttributeArray(spec
.indexStorage
, this.m_refContext
);
2808 glArray
.data(glsDrawTests
.DrawTestSpec
.Target
.ELEMENT_ARRAY
, indexArraySize
, indexArray
, glsDrawTests
.DrawTestSpec
.Usage
.STATIC_DRAW
);
2809 rrArray
.data(glsDrawTests
.DrawTestSpec
.Target
.ELEMENT_ARRAY
, indexArraySize
, indexArray
, glsDrawTests
.DrawTestSpec
.Usage
.STATIC_DRAW
);
2815 for (var attribNdx
= 0; attribNdx
< spec
.attribs
.length
; attribNdx
++) {
2816 /** @type {glsDrawTests.DrawTestSpec.AttributeSpec} */ var attribSpec
= spec
.attribs
[attribNdx
];
2817 var isPositionAttr
= (attribNdx
== 0) || (attribSpec
.additionalPositionAttribute
);
2819 if (attribSpec
.useDefaultAttribute
) {
2820 seed
= 10 * attribSpec
.hash() + 100 * spec
.hash() + attribNdx
;
2821 /** @type {Array<number>} */ var attribValue
= glsDrawTests
.RandomArrayGenerator
.generateAttributeValue(seed
, attribSpec
.inputType
);
2823 // changed USER for BUFFER in JS version
2824 this.m_glArrayPack
.newArray(glsDrawTests
.DrawTestSpec
.Storage
.BUFFER
);
2825 this.m_rrArrayPack
.newArray(glsDrawTests
.DrawTestSpec
.Storage
.BUFFER
);
2827 this.m_glArrayPack
.getArray(attribNdx
).setupArray(false, 0, attribSpec
.componentCount
, attribSpec
.inputType
, attribSpec
.outputType
, false, 0, 0, attribValue
, isPositionAttr
);
2828 this.m_rrArrayPack
.getArray(attribNdx
).setupArray(false, 0, attribSpec
.componentCount
, attribSpec
.inputType
, attribSpec
.outputType
, false, 0, 0, attribValue
, isPositionAttr
);
2830 seed
= attribSpec
.hash() + 100 * spec
.hash() + attribNdx
;
2831 /** @type {number} */ var elementSize
= attribSpec
.componentCount
* glsDrawTests
.DrawTestSpec
.inputTypeSize(attribSpec
.inputType
);
2832 /** @type {number} */ var stride
= (attribSpec
.stride
== 0) ? (elementSize
) : (attribSpec
.stride
);
2833 /** @type {number} */ var evaluatedElementCount
= (instanced
&& attribSpec
.instanceDivisor
> 0) ? (spec
.instanceCount
/ attribSpec
.instanceDivisor
+ 1) : (elementCount
);
2834 /** @type {number} */ var referencedElementCount
= (ranged
) ? (Math
.max(evaluatedElementCount
, spec
.indexMax
+ 1)) : (evaluatedElementCount
);
2835 /** @type {number} */ var bufferSize
= attribSpec
.offset
+ stride
* (referencedElementCount
- 1) + elementSize
;
2836 /** @type {goog.TypedArray} */ var data
= glsDrawTests
.RandomArrayGenerator
.createArray(
2838 referencedElementCount
,
2839 attribSpec
.componentCount
,
2842 attribSpec
.inputType
,
2843 indexed
? 0 : spec
.first
,
2845 indexed
? indexPointer
: null,
2849 this.m_glArrayPack
.newArray(attribSpec
.storage
);
2850 this.m_rrArrayPack
.newArray(attribSpec
.storage
);
2852 this.m_glArrayPack
.getArray(attribNdx
).data(glsDrawTests
.DrawTestSpec
.Target
.ARRAY
, bufferSize
, data
, attribSpec
.usage
);
2853 this.m_rrArrayPack
.getArray(attribNdx
).data(glsDrawTests
.DrawTestSpec
.Target
.ARRAY
, bufferSize
, data
, attribSpec
.usage
);
2855 this.m_glArrayPack
.getArray(attribNdx
).setupArray(true, attribSpec
.offset
, attribSpec
.componentCount
, attribSpec
.inputType
, attribSpec
.outputType
, attribSpec
.normalize
, attribSpec
.stride
, attribSpec
.instanceDivisor
, nullAttribValue
, isPositionAttr
);
2856 this.m_rrArrayPack
.getArray(attribNdx
).setupArray(true, attribSpec
.offset
, attribSpec
.componentCount
, attribSpec
.inputType
, attribSpec
.outputType
, attribSpec
.normalize
, attribSpec
.stride
, attribSpec
.instanceDivisor
, nullAttribValue
, isPositionAttr
);
2863 if (updateProgram
) {
2864 this.m_glArrayPack
.updateProgram();
2865 this.m_rrArrayPack
.updateProgram();
2868 /** @type {glsDrawTests.DrawTestSpec.CompatibilityTestType} */ var ctype
;
2874 this.m_glArrayPack
.render(spec
.primitive
, spec
.drawMethod
, 0, primitiveElementCount
, spec
.indexType
, spec
.indexPointerOffset
, spec
.indexMin
, spec
.indexMax
, spec
.instanceCount
, coordScale
, colorScale
, glArray
);
2875 this.m_rrArrayPack
.render(spec
.primitive
, spec
.drawMethod
, 0, primitiveElementCount
, spec
.indexType
, spec
.indexPointerOffset
, spec
.indexMin
, spec
.indexMax
, spec
.instanceCount
, coordScale
, colorScale
, rrArray
);
2877 this.m_glArrayPack
.render(spec
.primitive
, spec
.drawMethod
, spec
.first
, primitiveElementCount
, null, 0, 0, 0, spec
.instanceCount
, coordScale
, colorScale
, null);
2878 this.m_rrArrayPack
.render(spec
.primitive
, spec
.drawMethod
, spec
.first
, primitiveElementCount
, null, 0, 0, 0, spec
.instanceCount
, coordScale
, colorScale
, null);
2881 if (err
instanceof wtu
.GLErrorException
) {
2882 // GL Errors are ok if the mode is not properly aligned
2883 ctype
= spec
.isCompatibilityTest();
2885 bufferedLogToConsole('Got error: ' + err
.message
);
2887 if (ctype
== glsDrawTests
.DrawTestSpec
.CompatibilityTestType
.UNALIGNED_OFFSET
)
2888 checkMessage(false, 'Failed to draw with unaligned buffers.');
2889 else if (ctype
== glsDrawTests
.DrawTestSpec
.CompatibilityTestType
.UNALIGNED_STRIDE
)
2890 checkMessage(false, 'Failed to draw with unaligned stride.');
2895 } else if (compareStep
) {
2896 if (!this.compare(spec
.primitive
)) {
2897 ctype
= spec
.isCompatibilityTest();
2899 if (ctype
== glsDrawTests
.DrawTestSpec
.CompatibilityTestType
.UNALIGNED_OFFSET
)
2900 checkMessage(false, 'Failed to draw with unaligned buffers.');
2901 else if (ctype
== glsDrawTests
.DrawTestSpec
.CompatibilityTestType
.UNALIGNED_STRIDE
)
2902 checkMessage(false, 'Failed to draw with unaligned stride.');
2904 testFailedOptions('Image comparison failed.', false);
2905 return iterateResult
;
2908 testFailedOptions('Image comparison failed.', false);
2909 return tcuTestCase
.IterateResult
.STOP
;
2912 if (iterateResult
== tcuTestCase
.IterateResult
.STOP
)
2915 return iterateResult
;
2919 * @enum {number} PrimitiveClass
2921 glsDrawTests
.PrimitiveClass
= {
2928 * @param {?glsDrawTests.DrawTestSpec.Primitive} primitiveType
2929 * @return {glsDrawTests.PrimitiveClass}
2931 glsDrawTests
.getDrawPrimitiveClass = function(primitiveType
) {
2932 switch (primitiveType
) {
2933 case glsDrawTests
.DrawTestSpec
.Primitive
.POINTS
:
2934 return glsDrawTests
.PrimitiveClass
.POINT
;
2936 case glsDrawTests
.DrawTestSpec
.Primitive
.LINES
:
2937 case glsDrawTests
.DrawTestSpec
.Primitive
.LINE_STRIP
:
2938 case glsDrawTests
.DrawTestSpec
.Primitive
.LINE_LOOP
:
2939 return glsDrawTests
.PrimitiveClass
.LINE
;
2941 case glsDrawTests
.DrawTestSpec
.Primitive
.TRIANGLES
:
2942 case glsDrawTests
.DrawTestSpec
.Primitive
.TRIANGLE_FAN
:
2943 case glsDrawTests
.DrawTestSpec
.Primitive
.TRIANGLE_STRIP
:
2944 return glsDrawTests
.PrimitiveClass
.TRIANGLE
;
2947 throw new Error('Invalid primitive type');
2952 * @param {number} c1
2953 * @param {number} c2
2954 * @param {Array<number>} threshold
2957 glsDrawTests
.compareUintRGB8 = function(c1
, c2
, threshold
) {
2958 return (Math
.abs(((c1
>> 16) & 0xff) - ((c2
>> 16) & 0xff)) <= threshold
[0] && // Red
2959 Math
.abs(((c1
>> 8) & 0xff) - ((c2
>> 8) & 0xff)) <= threshold
[1] && // Green
2960 Math
.abs((c1
& 0xff) - (c2
& 0xff)) <= threshold
[2]); // Blue
2964 * @param {number} c1
2965 * @param {number} c2
2966 * @param {number} c3
2967 * @param {number} renderTargetDifference
2970 glsDrawTests
.isEdgeTripletComponent = function(c1
, c2
, c3
, renderTargetDifference
) {
2971 /** @type {number} */ var roundingDifference
= 2 * renderTargetDifference
; // src and dst pixels rounded to different directions
2972 /** @type {number} */ var d1
= c2
- c1
;
2973 /** @type {number} */ var d2
= c3
- c2
;
2974 /** @type {number} */ var rampDiff
= Math
.abs(d2
- d1
);
2976 return rampDiff
> roundingDifference
;
2980 * @param {tcuRGBA.RGBA} c1
2981 * @param {tcuRGBA.RGBA} c2
2982 * @param {tcuRGBA.RGBA} c3
2983 * @param {Array<number>} renderTargetThreshold
2986 glsDrawTests
.isEdgeTriplet = function(c1
, c2
, c3
, renderTargetThreshold
) {
2987 // black (background color) and non-black is always an edge
2988 /** @type {boolean} */ var b1
= c1
== 0x000000;
2989 /** @type {boolean} */ var b2
= c2
== 0x000000;
2990 /** @type {boolean} */ var b3
= c3
== 0x000000;
2992 // both pixels with coverage and pixels without coverage
2993 if ((b1
&& b2
&& b3
) == false && (b1
|| b2
|| b3
) == true)
2998 // all with coverage
2999 assertMsgOptions(!b1
&& !b2
&& !b3
, 'All colors with coverage', false, true);
3001 // Color is always linearly interpolated => component values change nearly linearly
3002 // in any constant direction on triangle hull. (df/dx ~= C).
3004 // Edge detection (this function) is run against the reference image
3005 // => no dithering to worry about
3007 return glsDrawTests
.isEdgeTripletComponent((c1
>> 16) && 0xff, (c2
>> 16) && 0xff, (c3
>> 16) && 0xff, renderTargetThreshold
[0]) ||
3008 glsDrawTests
.isEdgeTripletComponent((c1
>> 8) && 0xff, (c2
>> 8) && 0xff, (c3
>> 8) && 0xff, renderTargetThreshold
[1]) ||
3009 glsDrawTests
.isEdgeTripletComponent(c1
&& 0xff, c2
&& 0xff, c3
&& 0xff, renderTargetThreshold
[2]);
3015 * @param {tcuSurface.Surface} ref
3016 * @param {Array<number>} renderTargetThreshold
3019 glsDrawTests
.pixelNearEdge = function(x
, y
, ref
, renderTargetThreshold
) {
3020 // should not be called for edge pixels
3021 assertMsgOptions(x
>= 1 && x
<= ref
.getWidth() - 2, 'The pixel was on the edge', false, true);
3022 assertMsgOptions(y
>= 1 && y
<= ref
.getHeight() - 2, 'The pixel was on the edge', false, true);
3026 /** @type {number} */ var c1
;
3027 /** @type {number} */ var c2
;
3028 /** @type {number} */ var c3
;
3030 for (var dy
= -1; dy
< 2; ++dy
) {
3031 c1
= ref
.getPixelUintRGB8(x
- 1, y
+ dy
);
3032 c2
= ref
.getPixelUintRGB8(x
, y
+ dy
);
3033 c3
= ref
.getPixelUintRGB8(x
+ 1, y
+ dy
);
3034 if (glsDrawTests
.isEdgeTriplet(c1
, c2
, c3
, renderTargetThreshold
))
3040 for (var dx
= -1; dx
< 2; ++dx
) {
3041 c1
= ref
.getPixelUintRGB8(x
+ dx
, y
- 1);
3042 c2
= ref
.getPixelUintRGB8(x
+ dx
, y
);
3043 c3
= ref
.getPixelUintRGB8(x
+ dx
, y
+ 1);
3044 if (glsDrawTests
.isEdgeTriplet(c1
, c2
, c3
, renderTargetThreshold
))
3055 glsDrawTests
.getVisualizationGrayscaleColorUintRGB8 = function(c
) {
3056 // make triangle coverage and error pixels obvious by converting coverage to grayscale
3060 return 50 + Math
.floor((((c
>> 16) & 0xff) + ((c
>> 8) & 0xff) + (c
& 0xff)) / 8);
3066 * @param {tcuSurface.Surface} target
3069 glsDrawTests
.pixelNearLineIntersection = function(x
, y
, target
) {
3070 // should not be called for edge pixels
3071 assertMsgOptions(x
>= 1 && x
<= target
.getWidth() - 2, 'Pixel is in the edge', false, true);
3072 assertMsgOptions(y
>= 1 && y
<= target
.getHeight() - 2, 'Pixel is in the edge', false, true);
3074 var coveredPixels
= 0;
3076 for (var dy
= -1; dy
< 2; dy
++)
3077 for (var dx
= -1; dx
< 2; dx
++) {
3078 var targetCoverage
= target
.getPixelUintRGB8(x
+ dx
, y
+ dy
);
3079 if (targetCoverage
) {
3082 // A single thin line cannot have more than 3 covered pixels in a 3x3 area
3083 if (coveredPixels
>= 4)
3091 // search 3x3 are for matching color
3093 * @param {tcuSurface.Surface} target
3096 * @param {tcuRGBA.RGBA} color
3097 * @param {Array<number>} compareThreshold
3100 glsDrawTests
.pixelNeighborhoodContainsColor = function(target
, x
, y
, color
, compareThreshold
) {
3101 // should not be called for edge pixels
3102 assertMsgOptions(x
>= 1 && x
<= target
.getWidth() - 2, 'Pixel is in the edge', false, true);
3103 assertMsgOptions(y
>= 1 && y
<= target
.getHeight() - 2, 'Pixel is in the edge', false, true);
3105 for (var dy
= -1; dy
< 2; dy
++)
3106 for (var dx
= -1; dx
< 2; dx
++) {
3107 if (glsDrawTests
.compareUintRGB8(color
, target
.getPixelUintRGB8(x
+ dx
, y
+ dy
), compareThreshold
))
3114 // search 3x3 are for matching coverage (coverage == (color != background color))
3116 * @param {tcuSurface.Surface} target
3119 * @param {boolean} coverage
3122 glsDrawTests
.pixelNeighborhoodContainsCoverage = function(target
, x
, y
, coverage
) {
3123 // should not be called for edge pixels
3124 assertMsgOptions(x
>= 1 && x
<= target
.getWidth() - 2, 'Pixel is in the edge', false, true);
3125 assertMsgOptions(y
>= 1 && y
<= target
.getHeight() - 2, 'Pixel is in the edge', false, true);
3127 for (var dy
= -1; dy
< 2; dy
++)
3128 for (var dx
= -1; dx
< 2; dx
++) {
3129 var targetCmpCoverage
= target
.getPixelUintRGB8(x
+ dx
, y
+ dy
) != 0x000000; // Pixel is not black
3130 if (targetCmpCoverage
== coverage
)
3138 * @param {string} imageSetName
3139 * @param {string} imageSetDesc
3140 * @param {tcuSurface.Surface} reference
3141 * @param {tcuSurface.Surface} result
3142 * @param {Array<number>} compareThreshold
3143 * @param {Array<number>} renderTargetThreshold
3144 * @param {number} maxAllowedInvalidPixels
3147 glsDrawTests
.edgeRelaxedImageCompare = function(imageSetName
, imageSetDesc
, reference
, result
, compareThreshold
, renderTargetThreshold
, maxAllowedInvalidPixels
) {
3148 assertMsgOptions(result
.getWidth() == reference
.getWidth() && result
.getHeight() == reference
.getHeight(), 'Reference and result images have different dimensions', false, true);
3150 /** @type {Array<number>} */ var green
= [0, 255, 0, 255];
3151 /** @type {Array<number>} */ var errorColor
= [255, 0, 0, 255];
3152 /** @type {number} */ var width
= reference
.getWidth();
3153 /** @type {number} */ var height
= reference
.getHeight();
3154 /** @type {tcuSurface.Surface} */ var errorMask
= new tcuSurface
.Surface(width
, height
);
3155 /** @type {number} */ var numFailingPixels
= 0;
3157 // clear errormask edges which would otherwise be transparent
3159 tcuTextureUtil
.getSubregion(errorMask
.getAccess(), 0, 0, 0, width
, 1, 1).clear(green
);
3160 tcuTextureUtil
.getSubregion(errorMask
.getAccess(), 0, height
- 1, 0, width
, 1, 1).clear(green
);
3161 tcuTextureUtil
.getSubregion(errorMask
.getAccess(), 0, 0, 0, 1, height
, 1).clear(green
);
3162 tcuTextureUtil
.getSubregion(errorMask
.getAccess(), width
- 1, 0, 0, 1, height
, 1).clear(green
);
3164 // skip edge pixels since coverage on edge cannot be verified
3166 for (var y
= 1; y
< height
- 1; ++y
)
3167 for (var x
= 1; x
< width
- 1; ++x
) {
3168 /** @type {number} */ var refPixel
= reference
.getPixelUintRGB8(x
, y
);
3169 /** @type {number} */ var screenPixel
= result
.getPixelUintRGB8(x
, y
);
3170 /** @type {boolean} */ var isOkReferencePixel
= glsDrawTests
.pixelNeighborhoodContainsColor(result
, x
, y
, refPixel
, compareThreshold
); // screen image has a matching pixel nearby (~= If something is drawn on reference, it must be drawn to screen too.)
3171 /** @type {boolean} */ var isOkScreenPixel
= glsDrawTests
.pixelNeighborhoodContainsColor(reference
, x
, y
, screenPixel
, compareThreshold
); // reference image has a matching pixel nearby (~= If something is drawn on screen, it must be drawn to reference too.)
3173 if (isOkScreenPixel
&& isOkReferencePixel
) {
3174 // pixel valid, write greenish pixels to make the result image easier to read
3175 /** @type {number} */ var grayscaleValue
= glsDrawTests
.getVisualizationGrayscaleColorUintRGB8(screenPixel
);
3176 errorMask
.getAccess().setPixel([grayscaleValue
/ 255, 1, grayscaleValue
/ 255, 1], x
, y
);
3177 } else if (!glsDrawTests
.pixelNearEdge(x
, y
, reference
, renderTargetThreshold
)) {
3178 // non-edge pixel values must be within threshold of the reference values
3179 errorMask
.getAccess().setPixel(deMath
.scale(errorColor
, 1 / 255), x
, y
);
3182 // we are on/near an edge, verify only coverage (coverage == not background colored)
3183 /** @type {boolean} */ var referenceCoverage
= refPixel
!= 0x000000; // Not black
3184 /** @type {boolean} */ var screenCoverage
= screenPixel
!= 0x000000; // Not black
3185 /** @type {boolean} */ var isOkReferenceCoverage
= glsDrawTests
.pixelNeighborhoodContainsCoverage(result
, x
, y
, referenceCoverage
); // Check reference pixel against screen pixel
3186 /** @type {boolean} */ var isOkScreenCoverage
= glsDrawTests
.pixelNeighborhoodContainsCoverage(reference
, x
, y
, screenCoverage
); // Check screen pixels against reference pixel
3188 if (isOkScreenCoverage
&& isOkReferenceCoverage
) {
3189 // pixel valid, write greenish pixels to make the result image easier to read
3190 var grayscaleValue
= glsDrawTests
.getVisualizationGrayscaleColorUintRGB8(screenPixel
);
3191 errorMask
.getAccess().setPixel([grayscaleValue
/ 255, 1, grayscaleValue
/ 255, 1], x
, y
);
3193 // coverage does not match
3194 errorMask
.getAccess().setPixel(deMath
.scale(errorColor
, 1 / 255), x
, y
);
3200 bufferedLogToConsole(
3201 'Comparing images:</br>' +
3202 '<span> </span>allowed deviation in pixel positions = 1</br>' +
3203 '<span> </span>number of allowed invalid pixels = ' + maxAllowedInvalidPixels
+ '</br>' +
3204 '<span> </span>number of invalid pixels = ' + numFailingPixels
3207 if (numFailingPixels
> maxAllowedInvalidPixels
) {
3208 debug('Image comparison failed. Color threshold = (' + compareThreshold
[0] + ', ' + compareThreshold
[1] + ', ' + compareThreshold
[2] + ')');
3209 tcuImageCompare
.displayImages(result
.getAccess(), reference
.getAccess(), errorMask
.getAccess());
3218 * @param {string} imageSetName
3219 * @param {string} imageSetDesc
3220 * @param {tcuSurface.Surface} reference
3221 * @param {tcuSurface.Surface} result
3222 * @param {Array<number>} compareThreshold
3223 * @param {number} maxAllowedInvalidPixels
3226 glsDrawTests
.intersectionRelaxedLineImageCompare = function(imageSetName
, imageSetDesc
, reference
, result
, compareThreshold
, maxAllowedInvalidPixels
) {
3227 assertMsgOptions(result
.getWidth() == reference
.getWidth() && result
.getHeight() == reference
.getHeight(), 'Reference and result images have different dimensions', false, true);
3229 /** @type {Array<number>} */ var green
= [0, 255, 0, 255];
3230 /** @type {Array<number>} */ var errorColor
= [255, 0, 0, 255];
3231 var width
= reference
.getWidth();
3232 var height
= reference
.getHeight();
3233 /** @type {tcuSurface.Surface} */ var errorMask
= new tcuSurface
.Surface(width
, height
);
3234 /** @type {number} */ var numFailingPixels
= 0;
3236 // clear errormask edges which would otherwise be transparent
3238 tcuTextureUtil
.getSubregion(errorMask
.getAccess(), 0, 0, 0, width
, 1, 1).clear(green
);
3239 tcuTextureUtil
.getSubregion(errorMask
.getAccess(), 0, height
- 1, 0, width
, 1, 1).clear(green
);
3240 tcuTextureUtil
.getSubregion(errorMask
.getAccess(), 0, 0, 0, 1, height
, 1).clear(green
);
3241 tcuTextureUtil
.getSubregion(errorMask
.getAccess(), width
- 1, 0, 0, 1, height
, 1).clear(green
);
3243 // skip edge pixels since coverage on edge cannot be verified
3245 for (var y
= 1; y
< height
- 1; ++y
)
3246 for (var x
= 1; x
< width
- 1; ++x
) {
3247 /** @type {number} */ var refPixel
= reference
.getPixelUintRGB8(x
, y
);
3248 /** @type {number} */ var screenPixel
= result
.getPixelUintRGB8(x
, y
);
3249 /** @type {boolean} */ var isOkScreenPixel
= glsDrawTests
.pixelNeighborhoodContainsColor(reference
, x
, y
, screenPixel
, compareThreshold
); // reference image has a matching pixel nearby (~= If something is drawn on screen, it must be drawn to reference too.)
3250 /** @type {boolean} */ var isOkReferencePixel
= glsDrawTests
.pixelNeighborhoodContainsColor(result
, x
, y
, refPixel
, compareThreshold
); // screen image has a matching pixel nearby (~= If something is drawn on reference, it must be drawn to screen too.)
3252 /** @type {number} */ var grayscaleValue
;
3254 if (isOkScreenPixel
&& isOkReferencePixel
) {
3255 // pixel valid, write greenish pixels to make the result image easier to read
3256 grayscaleValue
= glsDrawTests
.getVisualizationGrayscaleColorUintRGB8(screenPixel
);
3257 errorMask
.getAccess().setPixel([grayscaleValue
/ 255, 1, grayscaleValue
/ 255, 1], x
, y
);
3258 } else if (!glsDrawTests
.pixelNearLineIntersection(x
, y
, reference
) &&
3259 !glsDrawTests
.pixelNearLineIntersection(x
, y
, result
)) {
3260 // non-intersection pixel values must be within threshold of the reference values
3261 errorMask
.getAccess().setPixel(deMath
.scale(errorColor
, 1 / 255), x
, y
);
3264 // pixel is near a line intersection
3265 // we are on/near an edge, verify only coverage (coverage == not background colored)
3266 /** @type {boolean} */ var referenceCoverage
= refPixel
!= 0x000000; // Not Black
3267 /** @type {boolean} */ var screenCoverage
= screenPixel
!= 0x000000; // Not Black
3268 /** @type {boolean} */ var isOkScreenCoverage
= glsDrawTests
.pixelNeighborhoodContainsCoverage(reference
, x
, y
, screenCoverage
); // Check screen pixels against reference pixel
3269 /** @type {boolean} */ var isOkReferenceCoverage
= glsDrawTests
.pixelNeighborhoodContainsCoverage(result
, x
, y
, referenceCoverage
); // Check reference pixel against screen pixel
3271 if (isOkScreenCoverage
&& isOkReferenceCoverage
) {
3272 // pixel valid, write greenish pixels to make the result image easier to read
3273 grayscaleValue
= glsDrawTests
.getVisualizationGrayscaleColorUintRGB8(screenPixel
);
3274 errorMask
.getAccess().setPixel([grayscaleValue
/ 255, 1, grayscaleValue
/ 255, 1], x
, y
);
3276 // coverage does not match
3277 errorMask
.getAccess().setPixel(deMath
.scale(errorColor
, 1 / 255), x
, y
);
3283 bufferedLogToConsole(
3284 'Comparing images:</br>' +
3285 '<span> </span>allowed deviation in pixel positions = 1</br>' +
3286 '<span> </span>number of allowed invalid pixels = ' + maxAllowedInvalidPixels
+ '</br>' +
3287 '<span> </span>number of invalid pixels = ' + numFailingPixels
3290 if (numFailingPixels
> maxAllowedInvalidPixels
) {
3291 debug('Image comparison failed. Color threshold = (' + compareThreshold
[0] + ', ' + compareThreshold
[1] + ', ' + compareThreshold
[2] + ')');
3292 tcuImageCompare
.displayImages(result
.getAccess(), reference
.getAccess(), errorMask
.getAccess());
3301 * @param {?glsDrawTests.DrawTestSpec.Primitive} primitiveType
3304 glsDrawTests
.DrawTest
.prototype.compare = function(primitiveType
) {
3305 /** @type {tcuSurface.Surface} */ var ref
= this.m_rrArrayPack
.getSurface();
3306 /** @type {tcuSurface.Surface} */ var screen
= this.m_glArrayPack
.getSurface();
3308 if (/** @type {number} */ (gl
.getParameter(gl
.SAMPLES
)) > 1) {
3309 // \todo [mika] Improve compare when using multisampling
3310 bufferedLogToConsole('Warning: Comparision of result from multisample render targets are not as strict as without multisampling. Might produce false positives!');
3311 return tcuImageCompare
.fuzzyCompare('Compare Results', 'Compare Results', ref
.getAccess(), screen
.getAccess(), 0.3, tcuImageCompare
.CompareLogMode
.RESULT
);
3313 /** @type {glsDrawTests.PrimitiveClass} */ var primitiveClass
= glsDrawTests
.getDrawPrimitiveClass(primitiveType
);
3315 switch (primitiveClass
) {
3316 case glsDrawTests
.PrimitiveClass
.POINT
: {
3317 // Point are extremely unlikely to have overlapping regions, don't allow any no extra / missing pixels
3318 /**@type {number} */ var maxAllowedInvalidPixelsWithPoints
= 0;
3319 return tcuImageCompare
.intThresholdPositionDeviationErrorThresholdCompare(
3321 'Result of rendering',
3324 [this.m_maxDiffRed
, this.m_maxDiffGreen
, this.m_maxDiffBlue
, 256],
3325 [1, 1, 0], //!< 3x3 search kernel
3326 true, //!< relax comparison on the image boundary
3327 maxAllowedInvalidPixelsWithPoints
//!< error threshold
3331 case glsDrawTests
.PrimitiveClass
.LINE
: {
3332 // Lines can potentially have a large number of overlapping pixels. Pixel comparison may potentially produce
3333 // false negatives in such pixels if for example the pixel in question is overdrawn by another line in the
3334 // reference image but not in the resultin image. Relax comparison near line intersection points (areas) and
3335 // compare only coverage, not color, in such pixels
3336 /**@type {number} */ var maxAllowedInvalidPixelsWithLines
= 15; // line are allowed to have a few bad pixels
3337 return glsDrawTests
.intersectionRelaxedLineImageCompare(
3339 'Result of rendering',
3342 [this.m_maxDiffRed
, this.m_maxDiffGreen
, this.m_maxDiffBlue
],
3343 maxAllowedInvalidPixelsWithLines
3347 case glsDrawTests
.PrimitiveClass
.TRIANGLE
: {
3348 // Triangles are likely to partially or fully overlap. Pixel difference comparison is fragile in pixels
3349 // where there could be potential overlapping since the pixels might be covered by one triangle in the
3350 // reference image and by the other in the result image. Relax comparsion near primitive edges and
3351 // compare only coverage, not color, in such pixels.
3352 /** @type {number} */ var maxAllowedInvalidPixelsWithTriangles
= 10;
3355 var renderTargetThreshold = //TODO: get color threshold from the pixel format --> m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold().toIVec().xyz();
3358 /** @type {Array<number>} */ var renderTargetThreshold
= [3, 3, 3, 3];
3360 return glsDrawTests
.edgeRelaxedImageCompare(
3362 'Result of rendering',
3365 [this.m_maxDiffRed
, this.m_maxDiffGreen
, this.m_maxDiffBlue
],
3366 renderTargetThreshold
,
3367 maxAllowedInvalidPixelsWithTriangles
3372 throw new Error('Invalid primitive class');
3378 * @param {glsDrawTests.DrawTestSpec} spec
3381 glsDrawTests
.DrawTest
.prototype.getCoordScale = function(spec
) {
3384 for (var arrayNdx
= 0; arrayNdx
< spec
.attribs
.length
; arrayNdx
++) {
3385 /** @type {glsDrawTests.DrawTestSpec.AttributeSpec} */ var attribSpec
= spec
.attribs
[arrayNdx
];
3386 /** @type {boolean} */ var isPositionAttr
= (arrayNdx
== 0) || (attribSpec
.additionalPositionAttribute
);
3387 /** @type {number} */ var attrMaxValue
= 0;
3389 if (!isPositionAttr
)
3392 if (attribSpec
.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT_2_10_10_10
) {
3393 if (attribSpec
.normalize
)
3394 attrMaxValue
+= 1.0;
3396 attrMaxValue
+= 1024.0;
3397 } else if (attribSpec
.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.INT_2_10_10_10
) {
3398 if (attribSpec
.normalize
)
3399 attrMaxValue
+= 1.0;
3401 attrMaxValue
+= 512.0;
3403 var max
= glsDrawTests
.GLValue
.getMaxValue(attribSpec
.inputType
).getValue();
3405 attrMaxValue
+= (attribSpec
.normalize
&& !glsDrawTests
.inputTypeIsFloatType(attribSpec
.inputType
)) ? (1.0) : (max
* 1.1);
3408 if (attribSpec
.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.VEC3
|| attribSpec
.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.VEC4
||
3409 attribSpec
.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.IVEC3
|| attribSpec
.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.IVEC4
||
3410 attribSpec
.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.UVEC3
|| attribSpec
.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.UVEC4
)
3413 maxValue
+= attrMaxValue
;
3416 return 1.0 / maxValue
;
3420 * @param {glsDrawTests.DrawTestSpec} spec
3423 glsDrawTests
.DrawTest
.prototype.getColorScale = function(spec
) {
3424 var colorScale
= 1.0;
3426 for (var arrayNdx
= 1; arrayNdx
< spec
.attribs
.length
; arrayNdx
++) {
3427 /** @type {glsDrawTests.DrawTestSpec.AttributeSpec} */ var attribSpec
= spec
.attribs
[arrayNdx
];
3428 /** @type {boolean} */ var isPositionAttr
= (arrayNdx
== 0) || (attribSpec
.additionalPositionAttribute
);
3433 if (attribSpec
.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.UNSIGNED_INT_2_10_10_10
) {
3434 if (!attribSpec
.normalize
)
3435 colorScale
*= 1.0 / 1024.0;
3436 } else if (attribSpec
.inputType
== glsDrawTests
.DrawTestSpec
.InputType
.INT_2_10_10_10
) {
3437 if (!attribSpec
.normalize
)
3438 colorScale
*= 1.0 / 512.0;
3440 var max
= glsDrawTests
.GLValue
.getMaxValue(attribSpec
.inputType
).toFloat();
3442 colorScale
*= (attribSpec
.normalize
&& !glsDrawTests
.inputTypeIsFloatType(attribSpec
.inputType
) ? 1.0 : (1.0 / max
));
3443 if (attribSpec
.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.VEC4
||
3444 attribSpec
.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.UVEC4
||
3445 attribSpec
.outputType
== glsDrawTests
.DrawTestSpec
.OutputType
.IVEC4
)
3446 colorScale
*= (attribSpec
.normalize
&& !glsDrawTests
.inputTypeIsFloatType(attribSpec
.inputType
) ? 1.0 : 1.0 / max
);