summaryrefslogtreecommitdiffstats
path: root/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3')
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/00_test_list.txt80
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/attriblocation.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/booleanstatequery.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/buffercopy.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/bufferobjectquery.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/00_test_list.txt55
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/abs.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/acos.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/acosh.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/add.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/asin.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/asinh.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/atan.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/atan2.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/atanh.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/builtinprecision_test_generator.py143
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/ceil.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/clamp.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/cos.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/cosh.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/cross.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/degrees.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/determinant.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/distance.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/div.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/dot.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/exp.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/exp2.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/faceforward.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/floor.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/fract.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/inverse.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/inversesqrt.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/length.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/log.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/log2.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/matrixcompmult.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/max.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/min.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/mix.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/mod.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/modf.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/mul.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/normalize.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/outerproduct.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/pow.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/radians.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/reflect.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/refract.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/round.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/roundeven.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sign.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sin.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sinh.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/smoothstep.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sqrt.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/step.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sub.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/tan.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/tanh.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/transpose.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/trunc.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/clipping.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/defaultvertexattribute.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/00_test_list.txt7
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_arrays.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_arrays_instanced.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_elements.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_elements_instanced.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_range_elements.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_test_generator.py89
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/instancing.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/random.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fApiCase.js161
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fAttribLocationTests.js267
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBooleanStateQuery.js372
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBufferCopyTests.js355
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBufferObjectQueryTests.js177
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBuiltinPrecisionTests.js87
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fClippingTests.js406
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fDefaultVertexAttributeTests.js546
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fDrawTests.js1155
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboColorbufferTests.js1049
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboCompletenessTests.js567
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboDepthbufferTests.js385
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboInvalidateTests.js1471
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboMultisampleTests.js377
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboRenderTest.js2389
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboStateQueryTests.js796
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboStencilbufferTests.js325
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboTestCase.js483
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboTestUtil.js1324
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFloatStateQueryTests.js431
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFragDepthTests.js593
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFragmentOutputTests.js1398
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFramebufferBlitTests.js1261
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fIndexedStateQueryTests.js409
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fInstancedRenderingTests.js711
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fIntegerStateQueryTests.js2049
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fInternalFormatQueryTests.js173
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fLifetimeTests.js471
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fMultisampleTests.js1744
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeBufferApiTests.js1104
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeFragmentApiTests.js339
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeShaderApiTests.js1195
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeStateApiTests.js927
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeTextureApiTests.js3002
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeVertexArrayApiTests.js906
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fOcclusionQueryTests.js511
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fPixelBufferObjectTest.js585
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fPrimitiveRestartTests.js709
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fRasterizerDiscardTests.js485
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fRboStateQueryTests.js308
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fReadPixelTests.js517
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fSamplerObjectTests.js313
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fSamplerStateQueryTests.js205
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderApiTests.js650
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderBuiltinVarTests.js1109
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderCommonFunctionTests.js1973
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderDerivateTests.js1696
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderIndexingTests.js1278
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderLoopTests.js1251
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderMatrixTest.js1852
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderOperatorTests.js3252
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderPackingFunctionTests.js791
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderPrecisionTests.js947
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderStateQueryTests.js2205
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderStructTests.js1957
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderSwitchTests.js492
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderTextureFunctionTests.js2709
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fStringQueryTests.js111
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fSyncTests.js330
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureFilteringTests.js2282
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureFormatTests.js1185
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureShadowTests.js898
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureSpecificationTests.js7456
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureStateQuery.js376
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureWrapTests.js434
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTransformFeedbackTests.js1914
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fUniformApiTests.js3203
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fUniformBlockTests.js748
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fVertexArrayObjectTests.js875
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fVertexArrayTests.js1103
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/00_test_list.txt26
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/blend.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/clear.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/fbocolorbuffer_test_generator.py116
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_00.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_01.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_02.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_03.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_04.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_05.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_00.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_01.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_02.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_03.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_04.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_05.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_00.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_01.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_02.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_03.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_04.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_05.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_00.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_01.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_02.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_03.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_04.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_05.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocompleteness.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbodepthbuffer.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/00_test_list.txt7
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/default.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/fboinvalidate_test_generator.py114
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/format_00.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/format_01.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/format_02.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/sub.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/target.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/whole.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbomultisample.2_samples.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbomultisample.4_samples.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbomultisample.8_samples.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/00_test_list.txt18
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/fborender_test_generator.py117
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_05.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_06.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_depth_stencil.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_clear.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_depth_stencil.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/stencil_clear.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbostatequery.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbostencilbuffer.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/floatstatequery.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragdepth.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/00_test_list.txt11
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.fixed.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.float.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.int.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.uint.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.fixed.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.float.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.int.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.uint.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/fragmentoutput_test_generator.py93
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/random_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/random_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/random_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/00_test_list.txt50
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_05.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_06.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_07.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_08.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_09.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_10.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_11.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_12.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_13.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_14.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_15.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_16.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_17.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_18.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_19.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_20.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_21.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_22.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_23.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_24.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_25.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_26.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_27.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_28.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_29.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_30.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_31.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_32.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_33.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_34.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_05.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_06.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/depth_stencil.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/frambufferblit_test_generator.py111
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_05.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_06.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/indexedstatequery.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/instancedrendering.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/integerstatequery.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/internalformatquery.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/lifetime.html34
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/00_test_list.txt6
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/default_fbo.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/fbo_4_samples.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/fbo_8_samples.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/fbo_max_samples.html31
-rwxr-xr-xdom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/multisample_test_generator.py98
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativebufferapi.html30
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativefragmentapi.html23
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativeshaderapi.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativestateapi.html23
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativetextureapi.html30
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativevertexarrayapi.html30
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/occlusionquery_conservative.html26
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/occlusionquery_strict.html26
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/pixelbufferobject.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/00_test_list.txt8
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/05.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/06.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/07.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/primitiverestart_test_generator.py84
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/rasterizerdiscard.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/rbostatequery.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/readpixel.html26
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/samplerobject.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/samplerstatequery.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderapi.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderbuiltinvar.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadercommonfunction.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderderivate_dfdx.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderderivate_dfdy.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderderivate_fwidth.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/00_test_list.txt9
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/mat_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/mat_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/mat_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/shaderindexing_test_generator.py97
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/tmp.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/uniform.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/varying.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/vec2.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/vec3.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/vec4.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderloop_do_while.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderloop_for.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderloop_while.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/00_test_list.txt33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_assign.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_const.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_dynamic.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_uniform.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/determinant.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_assign.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_const.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_dynamic.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_uniform.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/inverse.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/matrixcompmult.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_assign.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_const_highp.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_const_lowp.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_const_mediump.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_dynamic_highp.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_dynamic_lowp.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_dynamic_mediump.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_uniform_highp.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_uniform_lowp.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_uniform_mediump.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/negation.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/outerproduct.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/post_decrement.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/post_increment.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/pre_decrement.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/pre_increment.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/shadermatrix_test_generator.py121
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_assign.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_const.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_dynamic.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_uniform.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/transpose.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/unary_addition.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/00_test_list.txt37
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_00.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_01.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_02.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_03.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_00.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_01.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_02.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_03.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_04.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_05.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_06.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_07.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_08.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_09.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_10.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_11.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_12.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_13.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_14.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_15.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/bool_compare.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_00.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_01.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_02.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_03.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_04.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_05.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_06.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/exponential.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/float_compare.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/geometric.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/int_compare.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/selection.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/sequence.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/shaderoperator_test_generator.py127
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/unary_operator_00.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/unary_operator_01.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/unary_operator_02.html33
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderpackingfunction.html26
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderprecision_float.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderprecision_int.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderprecision_uint.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderstatequery.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderstruct.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderswitch.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/00_test_list.txt15
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/shadertexturefunction_test_generator.py103
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texelfetch.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texelfetchoffset.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texture.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturegrad.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturegradoffset.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturelod.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturelodoffset.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureoffset.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureproj.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojgrad.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojgradoffset.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojlod.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojlodoffset.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojoffset.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturesize.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/stringquery.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/sync.html32
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/00_test_list.txt116
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_05.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_05.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_06.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_07.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_08.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_09.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_05.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_05.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_06.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_07.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_08.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_09.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_05.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_05.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_06.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_07.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_08.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_09.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_10.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_11.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_12.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_13.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_14.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_15.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_16.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_17.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_18.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_19.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_20.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_21.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_22.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_23.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_24.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_25.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_26.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_27.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_28.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_29.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_30.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_31.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_32.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_33.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_34.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_35.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_05.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_06.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_07.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_08.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_09.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_05.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_05.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_06.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_07.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_08.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_09.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_no_edges_visible.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/texturefiltering_test_generator.py138
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/00_test_list.txt38
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/compressed_2d.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/compressed_cube.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_depth_stencil.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/textureformat_test_generator.py126
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/unsized_2d.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/unsized_2d_array.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/unsized_3d.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/00_test_list.txt144
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_always.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less_or_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_never.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_not_equal.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/textureshadow_test_generator.py116
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/00_test_list.txt90
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_copyteximage2d.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_copytexsubimage2d.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_2d_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_2d_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/random_teximage2d_2d.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/random_teximage2d_cube.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_align.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_depth.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_depth_pbo.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_params.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_unpack_params.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_depth.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_depth_pbo.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_params.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_unpack_params.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_2d_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_2d_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_2d_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_depth_stencil.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_size.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_depth_stencil.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_size.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_align.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_depth.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_empty_tex.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_02.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_03.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_04.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_params.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_unpack_params.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_depth.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_00.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_01.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_params.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_unpack_params.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texturespecification_test_generator.py178
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturestatequery.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/00_test_list.txt22
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_r11_npot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_r11_pot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_rg11_npot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_rg11_pot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_r11_npot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_r11_pot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_rg11_npot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_rg11_pot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_rgba8_npot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_rgba8_pot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_npot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_pot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_npot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_pot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_npot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_pot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_npot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_pot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_npot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_pot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/rgba8_npot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/rgba8_pot.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/texturewrap_test_generator.py110
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/00_test_list.txt29
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_interleaved_lines.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_interleaved_points.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_interleaved_triangles.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_separate_lines.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_separate_points.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_separate_triangles.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_interleaved_lines.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_interleaved_points.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_interleaved_triangles.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_separate_lines.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_separate_points.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_separate_triangles.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_interleaved_lines.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_interleaved_points.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_interleaved_triangles.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_separate_lines.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_separate_points.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_separate_triangles.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/interpolation_centroid.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/interpolation_flat.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/interpolation_smooth.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/point_size.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/position.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_interleaved_lines.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_interleaved_points.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_interleaved_triangles.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_separate_lines.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_separate_points.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_separate_triangles.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/transformfeedback_test_generator.py118
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/00_test_list.txt4
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/info_query.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/random.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/uniformapi_test_generator.py92
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/value_assigned.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/value_initial.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/00_test_list.txt10
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/instance_array_basic_type.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/multi_basic_types.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/multi_nested_struct.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/random.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_basic_array.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_basic_type.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_nested_struct.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_nested_struct_array.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_struct.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_struct_array.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/uniformbuffers_test_generator.py98
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrayobject.html24
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/00_test_list.txt27
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.count.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.output.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.storage.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.stride.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.first.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.normalize.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.offset.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.byte.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.float.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.half.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.int.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.int_2_10_10_10.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.short.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_byte.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int_2_10_10_10.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_short.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.stride.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_copy.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_draw.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_read.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.static_copy.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.static_draw.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.static_read.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_copy.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_draw.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_read.html31
-rw-r--r--dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/vertexarrays_test_generator.py110
932 files changed, 104619 insertions, 0 deletions
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/00_test_list.txt
new file mode 100644
index 0000000000..5a6d768f62
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/00_test_list.txt
@@ -0,0 +1,80 @@
+# The builtinprecision tests are not correct. Errors were introduced when
+# porting the tests from C++ to JavaScript. Tests that fail here pass in
+# the C++ version of dEQP ported to WASM. The tests are disabled here until
+# they can be fixed.
+# --min-version 2.0.1 builtinprecision/00_test_list.txt
+draw/00_test_list.txt
+fbocolorbuffer/00_test_list.txt
+fboinvalidate/00_test_list.txt
+fborender/00_test_list.txt
+fragmentoutput/00_test_list.txt
+framebufferblit/00_test_list.txt
+multisample/00_test_list.txt
+primitiverestart/00_test_list.txt
+shaderindexing/00_test_list.txt
+shadermatrix/00_test_list.txt
+shaderoperator/00_test_list.txt
+shadertexturefunction/00_test_list.txt
+texturefiltering/00_test_list.txt
+textureformat/00_test_list.txt
+textureshadow/00_test_list.txt
+texturespecification/00_test_list.txt
+texturewrap/00_test_list.txt
+transformfeedback/00_test_list.txt
+uniformapi/00_test_list.txt
+uniformbuffers/00_test_list.txt
+vertexarrays/00_test_list.txt
+attriblocation.html
+booleanstatequery.html
+buffercopy.html
+bufferobjectquery.html
+clipping.html
+defaultvertexattribute.html
+fbocompleteness.html
+fbodepthbuffer.html
+fbomultisample.2_samples.html
+fbomultisample.4_samples.html
+fbomultisample.8_samples.html
+fbostatequery.html
+fbostencilbuffer.html
+floatstatequery.html
+fragdepth.html
+indexedstatequery.html
+instancedrendering.html
+integerstatequery.html
+internalformatquery.html
+lifetime.html
+negativebufferapi.html
+negativefragmentapi.html
+negativeshaderapi.html
+negativestateapi.html
+negativetextureapi.html
+negativevertexarrayapi.html
+occlusionquery_strict.html
+occlusionquery_conservative.html
+pixelbufferobject.html
+rasterizerdiscard.html
+rbostatequery.html
+readpixel.html
+samplerobject.html
+samplerstatequery.html
+shaderapi.html
+shaderbuiltinvar.html
+shadercommonfunction.html
+shaderderivate_dfdx.html
+shaderderivate_dfdy.html
+shaderderivate_fwidth.html
+shaderloop_for.html
+shaderloop_while.html
+shaderloop_do_while.html
+shaderpackingfunction.html
+shaderprecision_float.html
+shaderprecision_int.html
+shaderprecision_uint.html
+shaderstatequery.html
+shaderstruct.html
+shaderswitch.html
+stringquery.html
+sync.html
+texturestatequery.html
+vertexarrayobject.html
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/attriblocation.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/attriblocation.html
new file mode 100644
index 0000000000..5eb12e7782
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/attriblocation.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Attribute Location Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fAttribLocationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fAttribLocationTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/booleanstatequery.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/booleanstatequery.html
new file mode 100644
index 0000000000..0423dd44f8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/booleanstatequery.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Boolean State Query Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBooleanStateQuery');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {stencil: true}, 2);
+
+functional.gles3.es3fBooleanStateQuery.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/buffercopy.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/buffercopy.html
new file mode 100644
index 0000000000..04c1d11bfa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/buffercopy.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Buffer Copy Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBufferCopyTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBufferCopyTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/bufferobjectquery.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/bufferobjectquery.html
new file mode 100644
index 0000000000..b0fa2f358c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/bufferobjectquery.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Buffer Object Query Tests Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBufferObjectQueryTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBufferObjectQueryTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/00_test_list.txt
new file mode 100644
index 0000000000..6ac29a3862
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/00_test_list.txt
@@ -0,0 +1,55 @@
+add.html
+sub.html
+mul.html
+div.html
+radians.html
+degrees.html
+sin.html
+cos.html
+tan.html
+asin.html
+acos.html
+atan.html
+atan2.html
+sinh.html
+cosh.html
+tanh.html
+asinh.html
+acosh.html
+atanh.html
+pow.html
+exp.html
+exp2.html
+log.html
+log2.html
+sqrt.html
+inversesqrt.html
+abs.html
+sign.html
+floor.html
+trunc.html
+round.html
+roundeven.html
+ceil.html
+fract.html
+mod.html
+modf.html
+min.html
+max.html
+mix.html
+step.html
+smoothstep.html
+clamp.html
+length.html
+distance.html
+dot.html
+cross.html
+normalize.html
+faceforward.html
+reflect.html
+refract.html
+matrixcompmult.html
+outerproduct.html
+transpose.html
+determinant.html
+inverse.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/abs.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/abs.html
new file mode 100644
index 0000000000..1c395e94de
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/abs.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 26);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/acos.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/acos.html
new file mode 100644
index 0000000000..3c27d4a350
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/acos.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 10);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/acosh.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/acosh.html
new file mode 100644
index 0000000000..6931a60260
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/acosh.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 17);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/add.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/add.html
new file mode 100644
index 0000000000..5817299349
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/add.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 0);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/asin.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/asin.html
new file mode 100644
index 0000000000..7b8bd1a838
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/asin.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 9);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/asinh.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/asinh.html
new file mode 100644
index 0000000000..ee84df94a8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/asinh.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 16);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/atan.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/atan.html
new file mode 100644
index 0000000000..00f50c03cb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/atan.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 11);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/atan2.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/atan2.html
new file mode 100644
index 0000000000..196de0060f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/atan2.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 12);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/atanh.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/atanh.html
new file mode 100644
index 0000000000..d117666e8e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/atanh.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 18);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/builtinprecision_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/builtinprecision_test_generator.py
new file mode 100644
index 0000000000..ba44b2fc48
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/builtinprecision_test_generator.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for builtinprecision* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, %(index)s);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'add',
+ 'sub',
+ 'mul',
+ 'div',
+ 'radians',
+ 'degrees',
+ 'sin',
+ 'cos',
+ 'tan',
+ 'asin',
+ 'acos',
+ 'atan',
+ 'atan2',
+ 'sinh',
+ 'cosh',
+ 'tanh',
+ 'asinh',
+ 'acosh',
+ 'atanh',
+ 'pow',
+ 'exp',
+ 'exp2',
+ 'log',
+ 'log2',
+ 'sqrt',
+ 'inversesqrt',
+ 'abs',
+ 'sign',
+ 'floor',
+ 'trunc',
+ 'round',
+ 'roundeven',
+ 'ceil',
+ 'fract',
+ 'mod',
+ 'modf',
+ 'min',
+ 'max',
+ 'mix',
+ 'step',
+ 'smoothstep',
+ 'clamp',
+ 'length',
+ 'distance',
+ 'dot',
+ 'cross',
+ 'normalize',
+ 'faceforward',
+ 'reflect',
+ 'refract',
+ 'matrixcompmult',
+ 'outerproduct',
+ 'transpose',
+ 'determinant',
+ 'inverse'
+]
+
+def GenerateFilename(group):
+ """Generate test filename."""
+ filename = group
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, index):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'index': index
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ filename = GenerateFilename(_GROUPS[ii])
+ filelist.append(filename)
+ WriteTest(filename, ii)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/ceil.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/ceil.html
new file mode 100644
index 0000000000..e0d5924407
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/ceil.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 32);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/clamp.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/clamp.html
new file mode 100644
index 0000000000..1a820652a1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/clamp.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 41);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/cos.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/cos.html
new file mode 100644
index 0000000000..281419e897
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/cos.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 7);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/cosh.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/cosh.html
new file mode 100644
index 0000000000..ec9c26b637
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/cosh.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 14);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/cross.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/cross.html
new file mode 100644
index 0000000000..1cb96eada4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/cross.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 45);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/degrees.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/degrees.html
new file mode 100644
index 0000000000..a9ed0f80e6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/degrees.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 5);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/determinant.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/determinant.html
new file mode 100644
index 0000000000..56ad04eb41
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/determinant.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 53);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/distance.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/distance.html
new file mode 100644
index 0000000000..1f9cfebaf6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/distance.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 43);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/div.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/div.html
new file mode 100644
index 0000000000..bc2c5ce723
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/div.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 3);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/dot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/dot.html
new file mode 100644
index 0000000000..e06fd395da
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/dot.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 44);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/exp.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/exp.html
new file mode 100644
index 0000000000..11cb6a826f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/exp.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 20);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/exp2.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/exp2.html
new file mode 100644
index 0000000000..3f8755cd24
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/exp2.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 21);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/faceforward.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/faceforward.html
new file mode 100644
index 0000000000..ecabe9cdf9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/faceforward.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 47);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/floor.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/floor.html
new file mode 100644
index 0000000000..1c060f13bb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/floor.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 28);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/fract.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/fract.html
new file mode 100644
index 0000000000..de778f3ab6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/fract.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 33);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/inverse.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/inverse.html
new file mode 100644
index 0000000000..c0b2e5876b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/inverse.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 54);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/inversesqrt.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/inversesqrt.html
new file mode 100644
index 0000000000..f34ec5569c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/inversesqrt.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 25);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/length.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/length.html
new file mode 100644
index 0000000000..949f716c79
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/length.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 42);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/log.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/log.html
new file mode 100644
index 0000000000..0528ceef25
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/log.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 22);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/log2.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/log2.html
new file mode 100644
index 0000000000..6defd59a32
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/log2.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 23);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/matrixcompmult.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/matrixcompmult.html
new file mode 100644
index 0000000000..28c81e75f6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/matrixcompmult.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 50);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/max.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/max.html
new file mode 100644
index 0000000000..95420abe1d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/max.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 37);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/min.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/min.html
new file mode 100644
index 0000000000..0230351426
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/min.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 36);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/mix.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/mix.html
new file mode 100644
index 0000000000..183704370e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/mix.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 38);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/mod.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/mod.html
new file mode 100644
index 0000000000..cbe10773d1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/mod.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 34);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/modf.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/modf.html
new file mode 100644
index 0000000000..a6e3df51a0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/modf.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 35);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/mul.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/mul.html
new file mode 100644
index 0000000000..0473fd8c06
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/mul.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 2);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/normalize.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/normalize.html
new file mode 100644
index 0000000000..82787d7a30
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/normalize.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 46);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/outerproduct.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/outerproduct.html
new file mode 100644
index 0000000000..83e2b6d810
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/outerproduct.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 51);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/pow.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/pow.html
new file mode 100644
index 0000000000..7793d740d5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/pow.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 19);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/radians.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/radians.html
new file mode 100644
index 0000000000..d808acba17
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/radians.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 4);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/reflect.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/reflect.html
new file mode 100644
index 0000000000..87ba13d5e1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/reflect.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 48);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/refract.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/refract.html
new file mode 100644
index 0000000000..68d967d557
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/refract.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 49);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/round.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/round.html
new file mode 100644
index 0000000000..0186d6795c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/round.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 30);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/roundeven.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/roundeven.html
new file mode 100644
index 0000000000..6e1f91eda7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/roundeven.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 31);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sign.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sign.html
new file mode 100644
index 0000000000..6c4cf28ac4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sign.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 27);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sin.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sin.html
new file mode 100644
index 0000000000..ee95d80af4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sin.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 6);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sinh.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sinh.html
new file mode 100644
index 0000000000..e805a703a1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sinh.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 13);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/smoothstep.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/smoothstep.html
new file mode 100644
index 0000000000..4dd4d7c9b2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/smoothstep.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 40);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sqrt.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sqrt.html
new file mode 100644
index 0000000000..707519237b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sqrt.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 24);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/step.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/step.html
new file mode 100644
index 0000000000..7dd143bb49
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/step.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 39);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sub.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sub.html
new file mode 100644
index 0000000000..8e22e94db0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/sub.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 1);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/tan.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/tan.html
new file mode 100644
index 0000000000..a442f83bfc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/tan.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 8);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/tanh.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/tanh.html
new file mode 100644
index 0000000000..04013ed6d6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/tanh.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 15);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/transpose.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/transpose.html
new file mode 100644
index 0000000000..48d55febf8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/transpose.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 52);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/trunc.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/trunc.html
new file mode 100644
index 0000000000..209656d9ac
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/builtinprecision/trunc.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from builtinprecision_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Builtin Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fBuiltinPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fBuiltinPrecisionTests.run(gl, 29);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/clipping.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/clipping.html
new file mode 100644
index 0000000000..ab2b2bd77f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/clipping.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Clipping tests Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fClippingTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="128" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fClippingTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/defaultvertexattribute.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/defaultvertexattribute.html
new file mode 100644
index 0000000000..8bca99ad70
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/defaultvertexattribute.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Default Vertex Attributes Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fDefaultVertexAttributeTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fDefaultVertexAttributeTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/00_test_list.txt
new file mode 100644
index 0000000000..ba28d1bb85
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/00_test_list.txt
@@ -0,0 +1,7 @@
+draw_arrays.html
+draw_elements.html
+draw_arrays_instanced.html
+draw_elements_instanced.html
+draw_range_elements.html
+instancing.html
+random.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_arrays.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_arrays.html
new file mode 100644
index 0000000000..ae9655df14
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_arrays.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from draw_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Draw Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fDrawTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fDrawTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_arrays_instanced.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_arrays_instanced.html
new file mode 100644
index 0000000000..f8219ee073
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_arrays_instanced.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from draw_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Draw Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fDrawTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fDrawTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_elements.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_elements.html
new file mode 100644
index 0000000000..1fb1a5c160
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_elements.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from draw_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Draw Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fDrawTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fDrawTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_elements_instanced.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_elements_instanced.html
new file mode 100644
index 0000000000..e4c4b3b980
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_elements_instanced.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from draw_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Draw Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fDrawTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fDrawTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_range_elements.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_range_elements.html
new file mode 100644
index 0000000000..df2f7a92bb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_range_elements.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from draw_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Draw Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fDrawTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fDrawTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_test_generator.py
new file mode 100644
index 0000000000..d96c767b4d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/draw_test_generator.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for draw* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from draw_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Draw Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fDrawTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fDrawTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'draw_arrays',
+ 'draw_elements',
+ 'draw_arrays_instanced',
+ 'draw_elements_instanced',
+ 'draw_range_elements',
+ 'instancing',
+ 'random',
+]
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ filename = _GROUPS[ii] + '.html'
+ filelist.append(filename)
+ WriteTest(filename, ii, ii + 1)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/instancing.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/instancing.html
new file mode 100644
index 0000000000..df8d7910be
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/instancing.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from draw_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Draw Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fDrawTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fDrawTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/random.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/random.html
new file mode 100644
index 0000000000..1c6f02f9c2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/draw/random.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from draw_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Draw Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fDrawTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fDrawTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fApiCase.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fApiCase.js
new file mode 100644
index 0000000000..3238e6c2ef
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fApiCase.js
@@ -0,0 +1,161 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+'use strict';
+goog.provide('functional.gles3.es3fApiCase');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.opengl.gluStrUtil');
+
+goog.scope(function() {
+
+ var es3fApiCase = functional.gles3.es3fApiCase;
+ var gluStrUtil = framework.opengl.gluStrUtil;
+ var tcuTestCase = framework.common.tcuTestCase;
+
+ // format numbers as they appear in gl.h
+ var getHexStr = function(num) {
+ var numstr = num.toString(16);
+ var prefix = '0x';
+ for (
+ var padding = (num < 0x10000 ? 4 : 8) - numstr.length;
+ padding-- > 0;
+ ) prefix += '0';
+ return prefix + numstr;
+ };
+
+ /**
+ * Base class for all the API tests.
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ */
+ es3fApiCase.ApiCase = function(name, desc, gl) {
+ gl = gl || window.gl;
+ if (this.test === undefined) {
+ throw new Error('Unimplemented virtual function: es3fApiCase.ApiCase.test');
+ }
+ tcuTestCase.DeqpTest.call(this, name, desc);
+
+ this.m_gl = gl;
+ this.m_pass = true;
+ this.m_comment = '';
+
+ };
+
+ es3fApiCase.ApiCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fApiCase.ApiCase.prototype.constructor = es3fApiCase.ApiCase;
+
+ /**
+ * @param {boolean} condition
+ * @param {string=} message
+ */
+ es3fApiCase.ApiCase.prototype.check = function(condition, message) {
+ if (this.m_pass && !condition) {
+ bufferedLogToConsole('Condition is false. Test failed.');
+ if (message)
+ this.m_comment += ' ' + message;
+ this.m_pass = condition;
+ }
+ return condition;
+ };
+
+ es3fApiCase.ApiCase.prototype.iterate = function() {
+
+ this.test();
+
+ if (this.m_pass)
+ testPassed(this.m_comment);
+ else
+ testFailedOptions(this.m_comment, true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @param {Array<number>|number} expected
+ * @return {boolean} returns true if gl.getError returns an expected error code and false otherwise.
+ */
+ es3fApiCase.ApiCase.prototype.expectError = function(expected) {
+ if (expected.constructor === Number)
+ expected = [expected];
+
+ var err = this.m_gl.getError();
+ var conformant = expected.indexOf(err) >= 0;
+
+ if (!conformant) {
+
+ var l = expected.length;
+ var msg = 'Expected ';
+
+ if (l > 1)
+ msg += (l == 2 ? 'either ' : 'one of ');
+
+ for (var i = 0; i < l; ++i) msg += (
+ (gluStrUtil.getErrorName(expected[i]) || getHexStr(expected[i])) +
+ (l - i == 2 ? ' or ' : ', ')
+ );
+
+ msg += 'but got ' + (gluStrUtil.getErrorName(err) || getHexStr(err)) + '.';
+
+ this.testFailed(msg);
+
+ }
+
+ return conformant;
+ };
+
+ es3fApiCase.ApiCase.prototype.testFailed = function(comment) {
+ bufferedLogToConsole(comment);
+ if (this.m_pass) {
+ this.m_comment = comment;
+ this.m_pass = false;
+ }
+ };
+
+ es3fApiCase.ApiCase.prototype.expectThrowNoError = function(f) {
+ try {
+ f();
+ this.testFailed("should have thrown exception");
+ } catch (e) {
+ this.expectError(this.m_gl.NO_ERROR);
+ }
+ }
+
+ /**
+ * Base class for all the API tests.
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {function(this:es3fApiCase.ApiCaseCallback)} callback
+ */
+ es3fApiCase.ApiCaseCallback = function(name, desc, gl, callback) {
+ this.test = callback;
+ es3fApiCase.ApiCase.call(this, name, desc, gl);
+ };
+ es3fApiCase.ApiCaseCallback.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fApiCase.ApiCaseCallback.prototype.constructor = es3fApiCase.ApiCaseCallback;
+
+/*
+ es3fApiCase.ApiCase.prototype.expectError // (error) or (error0, error1)
+ es3fApiCase.ApiCase.prototype.getSupportedExtensions // (number numSupportedValues, number extension, [number] values )
+ es3fApiCase.ApiCase.prototype.checkBooleans // (char value, char expected);
+//*/
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fAttribLocationTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fAttribLocationTests.js
new file mode 100644
index 0000000000..93f91eca1d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fAttribLocationTests.js
@@ -0,0 +1,267 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.0 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Attribute location test
+ *//*--------------------------------------------------------------------*/
+'use strict';
+goog.provide('functional.gles3.es3fAttribLocationTests');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('modules.shared.glsAttributeLocationTests');
+
+goog.scope(function() {
+
+ var es3fAttribLocationTests = functional.gles3.es3fAttribLocationTests;
+ var glsAttributeLocationTests = modules.shared.glsAttributeLocationTests;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+
+ es3fAttribLocationTests.createAttributeLocationTests = function() {
+
+ /** @type {Array<glsAttributeLocationTests.AttribType>} */
+ var types = [
+ new glsAttributeLocationTests.AttribType('float', 1, gl.FLOAT),
+ new glsAttributeLocationTests.AttribType('vec2', 1, gl.FLOAT_VEC2),
+ new glsAttributeLocationTests.AttribType('vec3', 1, gl.FLOAT_VEC3),
+ new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4),
+
+ new glsAttributeLocationTests.AttribType('mat2', 2, gl.FLOAT_MAT2),
+ new glsAttributeLocationTests.AttribType('mat3', 3, gl.FLOAT_MAT3),
+ new glsAttributeLocationTests.AttribType('mat4', 4, gl.FLOAT_MAT4),
+
+ new glsAttributeLocationTests.AttribType('int', 1, gl.INT),
+ new glsAttributeLocationTests.AttribType('ivec2', 1, gl.INT_VEC2),
+ new glsAttributeLocationTests.AttribType('ivec3', 1, gl.INT_VEC3),
+ new glsAttributeLocationTests.AttribType('ivec4', 1, gl.INT_VEC4),
+
+ new glsAttributeLocationTests.AttribType('uint', 1, gl.UNSIGNED_INT),
+ new glsAttributeLocationTests.AttribType('uvec2', 1, gl.UNSIGNED_INT_VEC2),
+ new glsAttributeLocationTests.AttribType('uvec3', 1, gl.UNSIGNED_INT_VEC3),
+ new glsAttributeLocationTests.AttribType('uvec4', 1, gl.UNSIGNED_INT_VEC4),
+
+ new glsAttributeLocationTests.AttribType('mat2x2', 2, gl.FLOAT_MAT2),
+ new glsAttributeLocationTests.AttribType('mat2x3', 2, gl.FLOAT_MAT2x3),
+ new glsAttributeLocationTests.AttribType('mat2x4', 2, gl.FLOAT_MAT2x4),
+
+ new glsAttributeLocationTests.AttribType('mat3x2', 3, gl.FLOAT_MAT3x2),
+ new glsAttributeLocationTests.AttribType('mat3x3', 3, gl.FLOAT_MAT3),
+ new glsAttributeLocationTests.AttribType('mat3x4', 3, gl.FLOAT_MAT3x4),
+
+ new glsAttributeLocationTests.AttribType('mat4x2', 4, gl.FLOAT_MAT4x2),
+ new glsAttributeLocationTests.AttribType('mat4x3', 4, gl.FLOAT_MAT4x3),
+ new glsAttributeLocationTests.AttribType('mat4x4', 4, gl.FLOAT_MAT4)
+ ];
+
+ /** @type {Array<glsAttributeLocationTests.AttribType>} */
+ var es2Types = [
+ new glsAttributeLocationTests.AttribType('float', 1, gl.FLOAT),
+ new glsAttributeLocationTests.AttribType('vec2', 1, gl.FLOAT_VEC2),
+ new glsAttributeLocationTests.AttribType('vec3', 1, gl.FLOAT_VEC3),
+ new glsAttributeLocationTests.AttribType('vec4', 1, gl.FLOAT_VEC4),
+
+ new glsAttributeLocationTests.AttribType('mat2', 2, gl.FLOAT_MAT2),
+ new glsAttributeLocationTests.AttribType('mat3', 3, gl.FLOAT_MAT3),
+ new glsAttributeLocationTests.AttribType('mat4', 4, gl.FLOAT_MAT4)
+ ];
+
+ /** @type {tcuTestCase.DeqpTest} */
+ var root = tcuTestCase.newTest('attribute_location', 'Attribute location tests');
+
+ /** @type {number} */ var typeNdx;
+ /** @type {glsAttributeLocationTests.AttribType} */ var type;
+
+ // Basic bind attribute tests
+ /** @type {tcuTestCase.DeqpTest} */
+ var bindAttributeGroup = tcuTestCase.newTest('bind', 'Basic bind attribute location tests.');
+
+ root.addChild(bindAttributeGroup);
+
+ for (typeNdx = 0; typeNdx < types.length; typeNdx++) {
+ type = types[typeNdx];
+ bindAttributeGroup.addChild(new glsAttributeLocationTests.BindAttributeTest(type));
+ }
+
+ // Bind max number of attributes
+ /** @type {tcuTestCase.DeqpTest} */
+ var bindMaxAttributeGroup = tcuTestCase.newTest('bind_max_attributes', 'Use bind with maximum number of attributes.');
+
+ root.addChild(bindMaxAttributeGroup);
+
+ for (typeNdx = 0; typeNdx < types.length; typeNdx++) {
+ type = types[typeNdx];
+ bindMaxAttributeGroup.addChild(new glsAttributeLocationTests.BindMaxAttributesTest(type));
+ }
+
+ // Test filling holes in attribute location
+ /** @type {tcuTestCase.DeqpTest} */
+ var holeGroup = tcuTestCase.newTest('bind_hole', 'Bind all, but one attribute and leave hole in location space for it.');
+
+ root.addChild(holeGroup);
+
+ for (typeNdx = 0; typeNdx < types.length; typeNdx++) {
+ type = types[typeNdx];
+
+ // Bind first location, leave hole size of type and fill rest of locations
+ holeGroup.addChild(new glsAttributeLocationTests.BindHoleAttributeTest(type));
+ }
+
+ // Test binding at different times
+ /** @type {tcuTestCase.DeqpTest} */
+ var bindTimeGroup = tcuTestCase.newTest('bind_time', 'Bind time tests. Test binding at different stages.');
+
+ root.addChild(bindTimeGroup);
+
+ bindTimeGroup.addChild(new glsAttributeLocationTests.PreAttachBindAttributeTest());
+ bindTimeGroup.addChild(new glsAttributeLocationTests.PreLinkBindAttributeTest());
+ bindTimeGroup.addChild(new glsAttributeLocationTests.PostLinkBindAttributeTest());
+ bindTimeGroup.addChild(new glsAttributeLocationTests.BindRelinkAttributeTest());
+ bindTimeGroup.addChild(new glsAttributeLocationTests.BindReattachAttributeTest());
+
+ // Basic layout location attribute tests
+ /** @type {tcuTestCase.DeqpTest} */
+ var layoutAttributeGroup = tcuTestCase.newTest('layout', 'Basic layout location tests.');
+
+ root.addChild(layoutAttributeGroup);
+
+ for (typeNdx = 0; typeNdx < types.length; typeNdx++) {
+ type = types[typeNdx];
+ layoutAttributeGroup.addChild(new glsAttributeLocationTests.LocationAttributeTest(type));
+ }
+
+ // Test max attributes with layout locations
+ /** @type {tcuTestCase.DeqpTest} */
+ var layoutMaxAttributeGroup = tcuTestCase.newTest('layout_max_attributes', 'Maximum attributes used with layout location qualifiers.');
+
+ root.addChild(layoutMaxAttributeGroup);
+
+ for (typeNdx = 0; typeNdx < types.length; typeNdx++) {
+ type = types[typeNdx];
+ layoutMaxAttributeGroup.addChild(new glsAttributeLocationTests.LocationMaxAttributesTest(type));
+ }
+
+ // Test filling holes in attribute location
+ holeGroup = tcuTestCase.newTest('layout_hole', 'Define layout location for all, but one attribute consuming max attribute locations.');
+
+ root.addChild(holeGroup);
+
+ for (typeNdx = 0; typeNdx < types.length; typeNdx++) {
+ type = types[typeNdx];
+
+ // Location first location, leave hole size of type and fill rest of locations
+ holeGroup.addChild(new glsAttributeLocationTests.LocationHoleAttributeTest(type));
+ }
+
+ // Basic mixed mixed attribute tests
+ /** @type {tcuTestCase.DeqpTest} */
+ var mixedAttributeGroup = tcuTestCase.newTest('mixed', 'Basic mixed location tests.');
+
+ root.addChild(mixedAttributeGroup);
+
+ for (typeNdx = 0; typeNdx < types.length; typeNdx++) {
+ type = types[typeNdx];
+ mixedAttributeGroup.addChild(new glsAttributeLocationTests.MixedAttributeTest(type));
+ }
+
+ /** @type {tcuTestCase.DeqpTest} */
+ var mixedMaxAttributeGroup = tcuTestCase.newTest('mixed_max_attributes', 'Maximum attributes used with mixed binding and layout qualifiers.');
+
+ root.addChild(mixedMaxAttributeGroup);
+
+ for (typeNdx = 0; typeNdx < types.length; typeNdx++) {
+ type = types[typeNdx];
+ mixedMaxAttributeGroup.addChild(new glsAttributeLocationTests.MixedMaxAttributesTest(type));
+ }
+
+ // Test mixed binding at different times
+ /** @type {tcuTestCase.DeqpTest} */
+ var mixedTimeGroup = tcuTestCase.newTest('mixed_time', 'Bind time tests. Test binding at different stages.');
+
+ root.addChild(mixedTimeGroup);
+
+ mixedTimeGroup.addChild(new glsAttributeLocationTests.PreAttachMixedAttributeTest());
+ mixedTimeGroup.addChild(new glsAttributeLocationTests.PreLinkMixedAttributeTest());
+ mixedTimeGroup.addChild(new glsAttributeLocationTests.PostLinkMixedAttributeTest());
+ mixedTimeGroup.addChild(new glsAttributeLocationTests.MixedRelinkAttributeTest());
+ mixedTimeGroup.addChild(new glsAttributeLocationTests.MixedReattachAttributeTest());
+
+ holeGroup = tcuTestCase.newTest('mixed_hole', 'Use layout location qualifiers and binding. Leave hole in location space for only free attribute.');
+
+ root.addChild(holeGroup);
+
+ for (typeNdx = 0; typeNdx < types.length; typeNdx++) {
+ type = types[typeNdx];
+
+ holeGroup.addChild(new glsAttributeLocationTests.MixedHoleAttributeTest(type));
+ }
+
+ // Test hole in location space that moves when relinking
+ /** @type {tcuTestCase.DeqpTest} */
+ var relinkBindHoleGroup = tcuTestCase.newTest('bind_relink_hole', 'Test relinking with moving hole in attribute location space.');
+
+ root.addChild(relinkBindHoleGroup);
+
+ for (typeNdx = 0; typeNdx < types.length; typeNdx++) {
+ type = types[typeNdx];
+
+ relinkBindHoleGroup.addChild(new glsAttributeLocationTests.BindRelinkHoleAttributeTest(type));
+ }
+
+ // Test hole in location space that moves when relinking
+ /** @type {tcuTestCase.DeqpTest} */
+ var relinkMixedHoleGroup = tcuTestCase.newTest('mixed_relink_hole', 'Test relinking with moving hole in attribute location space.');
+
+ root.addChild(relinkMixedHoleGroup);
+
+ for (typeNdx = 0; typeNdx < types.length; typeNdx++) {
+ type = types[typeNdx];
+
+ relinkMixedHoleGroup.addChild(new glsAttributeLocationTests.MixedRelinkHoleAttributeTest(type));
+ }
+
+ return root;
+ };
+
+ es3fAttribLocationTests.run = function(context) {
+ gl = context;
+ //Set up root Test
+ var state = tcuTestCase.runner;
+
+ var test = es3fAttribLocationTests.createAttributeLocationTests();
+ var testName = test.fullName();
+ var testDescription = test.getDescription() === undefined ? '' : test.getDescription();
+
+ state.testName = testName;
+ state.setRoot(test);
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ test.init();
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ bufferedLogToConsole('Exception: ' + err);
+ testFailedOptions('Failed to es3fAttribLocationTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBooleanStateQuery.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBooleanStateQuery.js
new file mode 100644
index 0000000000..173dea0946
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBooleanStateQuery.js
@@ -0,0 +1,372 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fBooleanStateQuery');
+goog.require('framework.common.tcuTestCase');
+goog.require('functional.gles3.es3fApiCase');
+goog.require('modules.shared.glsStateQuery');
+
+goog.scope(function() {
+var es3fBooleanStateQuery = functional.gles3.es3fBooleanStateQuery;
+var tcuTestCase = framework.common.tcuTestCase;
+var glsStateQuery = modules.shared.glsStateQuery;
+var es3fApiCase = functional.gles3.es3fApiCase;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} targetName
+ * @param {boolean} value
+ */
+es3fBooleanStateQuery.IsEnabledStateTestCase = function(name, description, targetName, value) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ this.m_targetName = targetName;
+ this.m_initial = value;
+};
+
+setParentClass(es3fBooleanStateQuery.IsEnabledStateTestCase, es3fApiCase.ApiCase);
+
+es3fBooleanStateQuery.IsEnabledStateTestCase.prototype.test = function() {
+ // check inital value
+ this.m_pass &= glsStateQuery.verify(this.m_targetName, this.m_initial);
+
+ // check toggle
+
+ gl.enable(this.m_targetName);
+
+ this.m_pass &= glsStateQuery.verify(this.m_targetName, true);
+
+ gl.disable(this.m_targetName);
+
+ this.m_pass &= glsStateQuery.verify(this.m_targetName, false);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fBooleanStateQuery.DepthWriteMaskTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fBooleanStateQuery.DepthWriteMaskTestCase, es3fApiCase.ApiCase);
+
+es3fBooleanStateQuery.DepthWriteMaskTestCase.prototype.test = function() {
+ this.m_pass &= glsStateQuery.verify(gl.DEPTH_WRITEMASK, true);
+
+ gl.depthMask(false);
+ this.m_pass &= glsStateQuery.verify(gl.DEPTH_WRITEMASK, false);
+
+ gl.depthMask(true);
+ this.m_pass &= glsStateQuery.verify(gl.DEPTH_WRITEMASK, true);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fBooleanStateQuery.SampleCoverageInvertTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fBooleanStateQuery.SampleCoverageInvertTestCase, es3fApiCase.ApiCase);
+
+es3fBooleanStateQuery.SampleCoverageInvertTestCase.prototype.test = function() {
+ this.m_pass &= glsStateQuery.verify(gl.SAMPLE_COVERAGE_INVERT, false);
+
+ gl.sampleCoverage(1, true);
+ this.m_pass &= glsStateQuery.verify(gl.SAMPLE_COVERAGE_INVERT, true);
+
+ gl.sampleCoverage(1, false);
+ this.m_pass &= glsStateQuery.verify(gl.SAMPLE_COVERAGE_INVERT, false);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} targetName
+ * @param {boolean} value
+ */
+es3fBooleanStateQuery.InitialBooleanTestCase = function(name, description, targetName, value) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ this.m_targetName = targetName;
+ this.m_initial = value;
+};
+
+setParentClass(es3fBooleanStateQuery.InitialBooleanTestCase, es3fApiCase.ApiCase);
+
+es3fBooleanStateQuery.InitialBooleanTestCase.prototype.test = function() {
+ // check inital value
+ this.m_pass &= glsStateQuery.verify(this.m_targetName, this.m_initial);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fBooleanStateQuery.ColorMaskTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fBooleanStateQuery.ColorMaskTestCase, es3fApiCase.ApiCase);
+
+es3fBooleanStateQuery.ColorMaskTestCase.prototype.test = function() {
+ this.m_pass &= glsStateQuery.verify(gl.COLOR_WRITEMASK, [true, true, true, true]);
+
+ var testMasks = [
+ [true, true, true, true],
+ [true, true, true, false],
+ [true, true, false, true],
+ [true, true, false, false],
+ [true, false, true, true],
+ [true, false, true, false],
+ [true, false, false, true],
+ [true, false, false, false],
+ [false, true, true, true],
+ [false, true, true, false],
+ [false, true, false, true],
+ [false, true, false, false],
+ [false, false, true, true],
+ [false, false, true, false],
+ [false, false, false, true],
+ [false, false, false, false]
+ ];
+
+ for (var ndx = 0; ndx < testMasks.length; ndx++) {
+ var mask = testMasks[ndx];
+ gl.colorMask(mask[0], mask[1], mask[2], mask[3]);
+ this.m_pass &= glsStateQuery.verify(gl.COLOR_WRITEMASK, mask);
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fBooleanStateQuery.TransformFeedbackTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {WebGLTransformFeedback} */ this.m_transformfeedback = null;
+};
+
+setParentClass(es3fBooleanStateQuery.TransformFeedbackTestCase, es3fApiCase.ApiCase);
+
+es3fBooleanStateQuery.TransformFeedbackTestCase.prototype.testTransformFeedback = function() {
+ throw new Error('Virtual function.');
+};
+
+es3fBooleanStateQuery.TransformFeedbackTestCase.prototype.test = function() {
+ var transformFeedbackTestVertSource = '#version 300 es\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(0.0);\n' +
+ '}\n';
+ var transformFeedbackTestFragSource = '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ this.m_transformfeedback = gl.createTransformFeedback();
+
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(shaderVert, transformFeedbackTestVertSource);
+ gl.compileShader(shaderVert);
+ this.m_pass &= glsStateQuery.verifyShader(shaderVert, gl.COMPILE_STATUS, true);
+
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(shaderFrag, transformFeedbackTestFragSource);
+ gl.compileShader(shaderFrag);
+ this.m_pass &= glsStateQuery.verifyShader(shaderFrag, gl.COMPILE_STATUS, true);
+
+ var shaderProg = gl.createProgram();
+ gl.attachShader(shaderProg, shaderVert);
+ gl.attachShader(shaderProg, shaderFrag);
+ var transform_feedback_outputs = ['gl_Position'];
+ gl.transformFeedbackVaryings(shaderProg, transform_feedback_outputs, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram(shaderProg);
+ this.m_pass &= glsStateQuery.verifyProgram(shaderProg, gl.LINK_STATUS, true);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, this.m_transformfeedback);
+
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buffer);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 16, gl.DYNAMIC_READ);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
+
+ gl.useProgram(shaderProg);
+
+ this.testTransformFeedback();
+
+ gl.useProgram(null);
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+ gl.deleteTransformFeedback(this.m_transformfeedback);
+ gl.deleteBuffer(buffer);
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(shaderProg);
+};
+
+/**
+ * @constructor
+ * @extends {es3fBooleanStateQuery.TransformFeedbackTestCase}
+ * @param {string} name
+ */
+es3fBooleanStateQuery.TransformFeedbackBasicTestCase = function(name) {
+ es3fBooleanStateQuery.TransformFeedbackTestCase.call(this, name, 'Test TRANSFORM_FEEDBACK_ACTIVE and TRANSFORM_FEEDBACK_PAUSED');
+};
+
+setParentClass(es3fBooleanStateQuery.TransformFeedbackBasicTestCase, es3fBooleanStateQuery.TransformFeedbackTestCase);
+
+es3fBooleanStateQuery.TransformFeedbackBasicTestCase.prototype.testTransformFeedback = function() {
+ gl.beginTransformFeedback(gl.POINTS);
+
+ this.m_pass &= glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_ACTIVE, true);
+ this.m_pass &= glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_PAUSED, false);
+
+ gl.pauseTransformFeedback();
+
+ this.m_pass &= glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_ACTIVE, true);
+ this.m_pass &= glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_PAUSED, true);
+
+ gl.resumeTransformFeedback();
+
+ this.m_pass &= glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_ACTIVE, true);
+ this.m_pass &= glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_PAUSED, false);
+
+ gl.endTransformFeedback();
+
+ this.m_pass &= glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_ACTIVE, false);
+ this.m_pass &= glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_PAUSED, false);
+};
+
+/**
+ * @constructor
+ * @extends {es3fBooleanStateQuery.TransformFeedbackTestCase}
+ * @param {string} name
+ */
+es3fBooleanStateQuery.TransformFeedbackImplicitResumeTestCase = function(name) {
+ es3fBooleanStateQuery.TransformFeedbackTestCase.call(this, name, 'EndTransformFeedback performs an implicit ResumeTransformFeedback.');
+};
+
+setParentClass(es3fBooleanStateQuery.TransformFeedbackImplicitResumeTestCase, es3fBooleanStateQuery.TransformFeedbackTestCase);
+
+es3fBooleanStateQuery.TransformFeedbackImplicitResumeTestCase.prototype.testTransformFeedback = function() {
+ gl.beginTransformFeedback(gl.POINTS);
+
+ this.m_pass &= glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_ACTIVE, true);
+ this.m_pass &= glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_PAUSED, false);
+
+ gl.pauseTransformFeedback();
+
+ this.m_pass &= glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_ACTIVE, true);
+ this.m_pass &= glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_PAUSED, true);
+
+ gl.endTransformFeedback();
+
+ this.m_pass &= glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_ACTIVE, false);
+ this.m_pass &= glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_PAUSED, false);
+};
+
+/**
+* @constructor
+* @extends {tcuTestCase.DeqpTest}
+*/
+es3fBooleanStateQuery.BooleanStateQuery = function() {
+ tcuTestCase.DeqpTest.call(this, 'boolean', 'Boolean State Query tests');
+};
+
+es3fBooleanStateQuery.BooleanStateQuery.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fBooleanStateQuery.BooleanStateQuery.prototype.constructor = es3fBooleanStateQuery.BooleanStateQuery;
+
+es3fBooleanStateQuery.BooleanStateQuery.prototype.init = function() {
+ var testRoot = this;
+ var isEnableds = [
+ ['rasterizer_discard', 'RASTERIZER_DISCARD', gl.RASTERIZER_DISCARD, false],
+ ['cull_face', 'CULL_FACE', gl.CULL_FACE, false],
+ ['polygon_offset_fill', 'POLYGON_OFFSET_FILL', gl.POLYGON_OFFSET_FILL, false],
+ ['sample_alpha_to_coverage', 'SAMPLE_ALPHA_TO_COVERAGE', gl.SAMPLE_ALPHA_TO_COVERAGE, false],
+ ['sample_coverage', 'SAMPLE_COVERAGE', gl.SAMPLE_COVERAGE, false],
+ ['scissor_test', 'SCISSOR_TEST', gl.SCISSOR_TEST, false],
+ ['stencil_test', 'STENCIL_TEST', gl.STENCIL_TEST, false],
+ ['depth_test', 'DEPTH_TEST', gl.DEPTH_TEST, false],
+ ['blend', 'BLEND', gl.BLEND, false],
+ ['dither', 'DITHER', gl.DITHER, true]
+ ];
+ isEnableds.forEach(function(elem) {
+ var name = elem[0];
+ var description = elem[1];
+ var targetName = elem[2];
+ var value = elem[3];
+ testRoot.addChild(new es3fBooleanStateQuery.IsEnabledStateTestCase(name, description, targetName, value));
+ });
+
+ testRoot.addChild(new es3fBooleanStateQuery.ColorMaskTestCase('color_writemask', 'COLOR_WRITEMASK'));
+ testRoot.addChild(new es3fBooleanStateQuery.DepthWriteMaskTestCase('depth_writemask', 'DEPTH_WRITEMASK'));
+ testRoot.addChild(new es3fBooleanStateQuery.SampleCoverageInvertTestCase('sample_coverage_invert', 'SAMPLE_COVERAGE_INVERT'));
+ testRoot.addChild(new es3fBooleanStateQuery.InitialBooleanTestCase('transform_feedback_active_initial', 'initial TRANSFORM_FEEDBACK_ACTIVE', gl.TRANSFORM_FEEDBACK_ACTIVE, false));
+ testRoot.addChild(new es3fBooleanStateQuery.InitialBooleanTestCase('transform_feedback_paused_initial', 'initial TRANSFORM_FEEDBACK_PAUSED', gl.TRANSFORM_FEEDBACK_PAUSED, false));
+ testRoot.addChild(new es3fBooleanStateQuery.TransformFeedbackBasicTestCase('transform_feedback'));
+ testRoot.addChild(new es3fBooleanStateQuery.TransformFeedbackImplicitResumeTestCase('transform_feedback_implicit_resume'));
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fBooleanStateQuery.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fBooleanStateQuery.BooleanStateQuery());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fBooleanStateQuery.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBufferCopyTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBufferCopyTests.js
new file mode 100644
index 0000000000..51186231a6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBufferCopyTests.js
@@ -0,0 +1,355 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fBufferCopyTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('modules.shared.glsBufferTestUtil');
+
+goog.scope(function() {
+
+ var es3fBufferCopyTests = functional.gles3.es3fBufferCopyTests;
+ var glsBufferTestUtil = modules.shared.glsBufferTestUtil;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var deMath = framework.delibs.debase.deMath;
+ var deString = framework.delibs.debase.deString;
+ var deRandom = framework.delibs.debase.deRandom;
+
+ /** @type {WebGL2RenderingContext} */ var gl;
+
+ /**
+ * @constructor
+ * @extends {glsBufferTestUtil.BufferCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} srcTarget
+ * @param {number} srcSize
+ * @param {number} srcHint
+ * @param {number} dstTarget
+ * @param {number} dstSize
+ * @param {number} dstHint
+ * @param {number} copySrcOffset
+ * @param {number} copyDstOffset
+ * @param {number} copySize
+ * @param {glsBufferTestUtil.VerifyType} verifyType
+ */
+ es3fBufferCopyTests.BasicBufferCopyCase = function(name, desc, srcTarget, srcSize, srcHint, dstTarget, dstSize, dstHint, copySrcOffset, copyDstOffset, copySize, verifyType) {
+ glsBufferTestUtil.BufferCase.call(this, name, desc);
+
+ this.m_srcTarget = srcTarget;
+ this.m_srcSize = srcSize;
+ this.m_srcHint = srcHint;
+ this.m_dstTarget = dstTarget;
+ this.m_dstSize = dstSize;
+ this.m_dstHint = dstHint;
+ this.m_copySrcOffset = copySrcOffset;
+ this.m_copyDstOffset = copyDstOffset;
+ this.m_copySize = copySize;
+ this.m_verifyType = verifyType;
+
+ assertMsgOptions(deMath.deInBounds32(this.m_copySrcOffset, 0, this.m_srcSize) && deMath.deInRange32(this.m_copySrcOffset + this.m_copySize, this.m_copySrcOffset, this.m_srcSize), 'Copy parameters are out of buffer\'s range', false, true);
+ assertMsgOptions(deMath.deInBounds32(this.m_copyDstOffset, 0, this.m_dstSize) && deMath.deInRange32(this.m_copyDstOffset + this.m_copySize, this.m_copyDstOffset, this.m_dstSize), 'Copy parameters are out of buffer\'s range', false, true);
+ };
+
+ es3fBufferCopyTests.BasicBufferCopyCase.prototype = Object.create(glsBufferTestUtil.BufferCase.prototype);
+ es3fBufferCopyTests.BasicBufferCopyCase.prototype.constructor = es3fBufferCopyTests.BasicBufferCopyCase;
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fBufferCopyTests.BasicBufferCopyCase.prototype.iterate = function() {
+ /** @type {glsBufferTestUtil.BufferVerifier} */ var verifier = new glsBufferTestUtil.BufferVerifier(this.m_verifyType);
+ var srcRef = new glsBufferTestUtil.ReferenceBuffer();
+ var dstRef = new glsBufferTestUtil.ReferenceBuffer();
+ var srcBuf = 0;
+ var dstBuf = 0;
+ var srcSeed = deMath.binaryOp(deString.deStringHash(this.fullName()), 0xabcd, deMath.BinaryOp.XOR);
+ var dstSeed = deMath.binaryOp(deString.deStringHash(this.fullName()), 0xef01, deMath.BinaryOp.XOR);
+ var isOk = true;
+
+ srcRef.setSize(this.m_srcSize);
+ glsBufferTestUtil.fillWithRandomBytes(srcRef.getPtr(), this.m_srcSize, srcSeed);
+
+ dstRef.setSize(this.m_dstSize);
+ glsBufferTestUtil.fillWithRandomBytes(dstRef.getPtr(), this.m_dstSize, dstSeed);
+
+ // Create source buffer and fill with data.
+ srcBuf = this.genBuffer();
+ gl.bindBuffer(this.m_srcTarget, srcBuf);
+ gl.bufferData(this.m_srcTarget, srcRef.getPtr(), this.m_srcHint);
+
+ // Create destination buffer and fill with data.
+ dstBuf = this.genBuffer();
+ gl.bindBuffer(this.m_dstTarget, dstBuf);
+ gl.bufferData(this.m_dstTarget, dstRef.getPtr(), this.m_dstHint);
+
+ // Verify both buffers before executing copy.
+ isOk = verifier.verify(srcBuf, srcRef.getPtr(), 0, this.m_srcSize, this.m_srcTarget) && isOk;
+ isOk = verifier.verify(dstBuf, dstRef.getPtr(), 0, this.m_dstSize, this.m_dstTarget) && isOk;
+
+ // Execute copy.
+ dstRef.getPtr().set(srcRef.getPtr().subarray(this.m_copySrcOffset, this.m_copySrcOffset + this.m_copySize), this.m_copyDstOffset);
+
+ gl.bindBuffer(this.m_srcTarget, srcBuf);
+ gl.bindBuffer(this.m_dstTarget, dstBuf);
+ gl.copyBufferSubData(this.m_srcTarget, this.m_dstTarget, this.m_copySrcOffset, this.m_copyDstOffset, this.m_copySize);
+
+ // Verify both buffers after copy.
+ isOk = verifier.verify(srcBuf, srcRef.getPtr(), 0, this.m_srcSize, this.m_srcTarget) && isOk;
+ isOk = verifier.verify(dstBuf, dstRef.getPtr(), 0, this.m_dstSize, this.m_dstTarget) && isOk;
+
+ if (isOk)
+ testPassed('');
+ else
+ testFailed('Buffer verification failed');
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ // Case B: same buffer, take range as parameter
+
+ /**
+ * @constructor
+ * @extends {glsBufferTestUtil.BufferCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} srcTarget
+ * @param {number} dstTarget
+ * @param {number} hint
+ * @param {glsBufferTestUtil.VerifyType} verifyType
+ */
+ es3fBufferCopyTests.SingleBufferCopyCase = function(name, desc, srcTarget, dstTarget, hint, verifyType) {
+ glsBufferTestUtil.BufferCase.call(this, name, desc);
+ this.m_srcTarget = srcTarget;
+ this.m_dstTarget = dstTarget;
+ this.m_hint = hint;
+ this.m_verifyType = verifyType;
+ };
+
+ es3fBufferCopyTests.SingleBufferCopyCase.prototype = Object.create(glsBufferTestUtil.BufferCase.prototype);
+ es3fBufferCopyTests.SingleBufferCopyCase.prototype.constructor = es3fBufferCopyTests.SingleBufferCopyCase;
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fBufferCopyTests.SingleBufferCopyCase.prototype.iterate = function() {
+ var size = 1000;
+ /** @type {glsBufferTestUtil.BufferVerifier} */ var verifier = new glsBufferTestUtil.BufferVerifier(this.m_verifyType);
+ var ref = new glsBufferTestUtil.ReferenceBuffer();
+ var baseSeed = deString.deStringHash(this.fullName());
+ var isOk = true;
+
+ ref.setSize(size);
+
+ // Create buffer.
+ var buf = this.genBuffer();
+ gl.bindBuffer(this.m_srcTarget, buf);
+
+ /** @type {Array<{srcOffset: number, dstOffset: number, copySize: number}>} */
+ var copyRanges = [{
+ srcOffset: 57, dstOffset: 701, copySize: 101 // Non-adjecent, from low to high.
+ },{
+ srcOffset: 640, dstOffset: 101, copySize: 101 // Non-adjecent, from high to low.
+ },{
+ srcOffset: 0, dstOffset: 500, copySize: 500 // Lower half to upper half.
+ },{
+ srcOffset: 500, dstOffset: 0, copySize: 500 // Upper half to lower half.
+ }];
+
+ for (var ndx = 0; ndx < copyRanges.length && isOk; ndx++) {
+ var srcOffset = copyRanges[ndx].srcOffset;
+ var dstOffset = copyRanges[ndx].dstOffset;
+ var copySize = copyRanges[ndx].copySize;
+
+ glsBufferTestUtil.fillWithRandomBytes(ref.getPtr(), size, deMath.binaryOp(baseSeed, deMath.deMathHash(ndx), deMath.BinaryOp.XOR));
+
+ // Fill with data.
+ gl.bindBuffer(this.m_srcTarget, buf);
+ gl.bufferData(this.m_srcTarget, ref.getPtr(), this.m_hint);
+
+ // Execute copy.
+ ref.getPtr().set(ref.getPtr().subarray(srcOffset, srcOffset + copySize), dstOffset);
+
+ gl.bindBuffer(this.m_dstTarget, buf);
+ gl.copyBufferSubData(this.m_srcTarget, this.m_dstTarget, srcOffset, dstOffset, copySize);
+
+ // Verify buffer after copy.
+ isOk = verifier.verify(buf, ref.getPtr(), 0, size, this.m_dstTarget) && isOk;
+ }
+
+ if (isOk)
+ testPassed('');
+ else
+ testFailed('Buffer verification failed');
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fBufferCopyTests.BufferCopyTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'copy', 'Buffer copy tests');
+ this.makeExecutable();
+ };
+
+ es3fBufferCopyTests.BufferCopyTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fBufferCopyTests.BufferCopyTests.prototype.constructor = es3fBufferCopyTests.BufferCopyTests;
+
+ es3fBufferCopyTests.BufferCopyTests.prototype.init = function() {
+ /** @type {glsBufferTestUtil.VerifyType} */ var verify;
+
+ var bufferTargets = [
+ gl.ARRAY_BUFFER,
+ gl.COPY_READ_BUFFER,
+ gl.COPY_WRITE_BUFFER,
+ gl.ELEMENT_ARRAY_BUFFER,
+ gl.PIXEL_PACK_BUFFER,
+ gl.PIXEL_UNPACK_BUFFER,
+ gl.TRANSFORM_FEEDBACK_BUFFER,
+ gl.UNIFORM_BUFFER
+ ];
+
+ // .basic
+
+ var basicGroup = new tcuTestCase.DeqpTest('basic', 'Basic buffer copy cases');
+ this.addChild(basicGroup);
+
+ for (var srcTargetNdx = 0; srcTargetNdx < bufferTargets.length; srcTargetNdx++) {
+ for (var dstTargetNdx = 0; dstTargetNdx < bufferTargets.length; dstTargetNdx++) {
+ if (srcTargetNdx == dstTargetNdx)
+ continue;
+
+ // In WebGL 2, a copy between an ELEMENT_ARRAY_BUFFER and other data buffer
+ // (not COPY_WRITE_BUFFER nor COPY_READ_BUFFER nor ELEMENT_ARRAY_BUFFER)
+ // cannot be made, so let's skip those cases.
+ if (bufferTargets[srcTargetNdx] == gl.ELEMENT_ARRAY_BUFFER ||
+ bufferTargets[dstTargetNdx] == gl.ELEMENT_ARRAY_BUFFER)
+ continue;
+
+ var srcTarget = bufferTargets[srcTargetNdx];
+ var dstTarget = bufferTargets[dstTargetNdx];
+ var size = 1017;
+ var hint = gl.STATIC_DRAW;
+ verify = glsBufferTestUtil.VerifyType.AS_VERTEX_ARRAY;
+ var name = glsBufferTestUtil.getBufferTargetName(srcTarget) + '_' + glsBufferTestUtil.getBufferTargetName(dstTarget);
+
+ basicGroup.addChild(new es3fBufferCopyTests.BasicBufferCopyCase(name, '', srcTarget, size, hint, dstTarget, size, hint, 0, 0, size, verify));
+ }
+ }
+
+ // .subrange
+
+ var subrangeGroup = new tcuTestCase.DeqpTest('subrange', 'Buffer subrange copy tests');
+ this.addChild(subrangeGroup);
+
+ /**
+ * @type {Array<{name: string, srcSize: number, dstSize: number, srcOffset: number, dstOffset: number, copySize: number}>}
+ */
+ var cases = [{
+ name: 'middle', srcSize: 1000, dstSize: 1000, srcOffset: 250, dstOffset: 250, copySize: 500
+ },{
+ name: 'small_to_large', srcSize: 100, dstSize: 1000, srcOffset: 0, dstOffset: 409, copySize: 100
+ },{
+ name: 'large_to_small', srcSize: 1000, dstSize: 100, srcOffset: 409, dstOffset: 0, copySize: 100
+ },{
+ name: 'low_to_high_1', srcSize: 1000, dstSize: 1000, srcOffset: 0, dstOffset: 500, copySize: 500
+ },{
+ name: 'low_to_high_2', srcSize: 997, dstSize: 1027, srcOffset: 0, dstOffset: 701, copySize: 111
+ },{
+ name: 'high_to_low_1', srcSize: 1000, dstSize: 1000, srcOffset: 500, dstOffset: 0, copySize: 500
+ },{
+ name: 'high_to_low_2', srcSize: 1027, dstSize: 997, srcOffset: 701, dstOffset: 17, copySize: 111
+ }];
+
+ for (var ndx = 0; ndx < cases.length; ndx++) {
+ var srcTarget = gl.COPY_READ_BUFFER;
+ var dstTarget = gl.COPY_WRITE_BUFFER;
+ var hint = gl.STATIC_DRAW;
+ verify = glsBufferTestUtil.VerifyType.AS_VERTEX_ARRAY;
+
+ subrangeGroup.addChild(
+ new es3fBufferCopyTests.BasicBufferCopyCase(
+ cases[ndx].name, '',
+ srcTarget, cases[ndx].srcSize, hint,
+ dstTarget, cases[ndx].dstSize, hint,
+ cases[ndx].srcOffset, cases[ndx].dstOffset, cases[ndx].copySize,
+ verify
+ )
+ );
+ }
+
+ // .single_buffer
+
+ var singleBufGroup = new tcuTestCase.DeqpTest('single_buffer', 'Copies within single buffer');
+ this.addChild(singleBufGroup);
+
+ for (var srcTargetNdx = 0; srcTargetNdx < bufferTargets.length; srcTargetNdx++) {
+ for (var dstTargetNdx = 0; dstTargetNdx < bufferTargets.length; dstTargetNdx++) {
+ if (srcTargetNdx == dstTargetNdx)
+ continue;
+
+ // In WebGL 2, we can't rebind an ELEMENT_ARRAY_BUFFER or TRANSFORM_FEEDBACK_BUFFER as a
+ // different type of buffer, so we skip those cases.
+ if (bufferTargets[srcTargetNdx] == gl.ELEMENT_ARRAY_BUFFER || bufferTargets[srcTargetNdx] == gl.TRANSFORM_FEEDBACK_BUFFER ||
+ bufferTargets[dstTargetNdx] == gl.ELEMENT_ARRAY_BUFFER || bufferTargets[dstTargetNdx] == gl.TRANSFORM_FEEDBACK_BUFFER)
+ continue;
+
+ var srcTarget = bufferTargets[srcTargetNdx];
+ var dstTarget = bufferTargets[dstTargetNdx];
+ var hint = gl.STATIC_DRAW;
+ verify = glsBufferTestUtil.VerifyType.AS_VERTEX_ARRAY;
+ var name = glsBufferTestUtil.getBufferTargetName(srcTarget) + '_' + glsBufferTestUtil.getBufferTargetName(dstTarget);
+
+ singleBufGroup.addChild(new es3fBufferCopyTests.SingleBufferCopyCase(name, '', srcTarget, dstTarget, hint, verify));
+ }
+ }
+ };
+
+ /**
+ * Create and execute the test cases
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fBufferCopyTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+
+ state.setRoot(new es3fBufferCopyTests.BufferCopyTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBufferObjectQueryTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBufferObjectQueryTests.js
new file mode 100644
index 0000000000..a4384d3ae7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBufferObjectQueryTests.js
@@ -0,0 +1,177 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fBufferObjectQueryTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('functional.gles3.es3fApiCase');
+
+goog.scope(function() {
+var es3fBufferObjectQueryTests = functional.gles3.es3fBufferObjectQueryTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var es3fApiCase = functional.gles3.es3fApiCase;
+var deRandom = framework.delibs.debase.deRandom;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fBufferObjectQueryTests.BufferCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fBufferObjectQueryTests.BufferCase, es3fApiCase.ApiCase);
+
+es3fBufferObjectQueryTests.BufferCase.prototype.test = function() {
+ var bufferTargets = [
+ gl.ARRAY_BUFFER, gl.COPY_READ_BUFFER,
+ gl.TRANSFORM_FEEDBACK_BUFFER, gl.UNIFORM_BUFFER,
+
+ gl.COPY_WRITE_BUFFER, gl.ELEMENT_ARRAY_BUFFER,
+ gl.PIXEL_PACK_BUFFER, gl.PIXEL_UNPACK_BUFFER
+ ];
+
+ // most test need only to be run with a subset of targets
+ var targets = this.m_testAllTargets ? bufferTargets.length : 4;
+
+ for (var ndx = 0; ndx < targets; ++ndx) {
+ this.m_bufferTarget = bufferTargets[ndx];
+
+ var bufferId = gl.createBuffer();
+ gl.bindBuffer(this.m_bufferTarget, bufferId);
+
+ this.testBuffer();
+
+ gl.bindBuffer(this.m_bufferTarget, null);
+ gl.deleteBuffer(bufferId);
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fBufferObjectQueryTests.BufferCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fBufferObjectQueryTests.BufferSizeCase = function(name, description) {
+ es3fBufferObjectQueryTests.BufferCase.call(this, name, description);
+ this.m_testAllTargets = true;
+};
+
+setParentClass(es3fBufferObjectQueryTests.BufferSizeCase, es3fBufferObjectQueryTests.BufferCase);
+
+es3fBufferObjectQueryTests.BufferSizeCase.prototype.testBuffer = function() {
+ var rnd = new deRandom.Random(0xabcdef);
+
+ var size = /** type {number} */ (gl.getBufferParameter(this.m_bufferTarget, gl.BUFFER_SIZE));
+ this.check(size == 0, 'Initial size should be 0; got ' + size);
+
+ var numIterations = 16;
+ for (var i = 0; i < numIterations; ++i) {
+ var len = rnd.getInt(0, 1024);
+ gl.bufferData(this.m_bufferTarget, len, gl.STREAM_DRAW);
+
+ size = /** type {number} */ (gl.getBufferParameter(this.m_bufferTarget, gl.BUFFER_SIZE));
+ this.check(size == len, 'Buffer size should be ' + len + ' ; got ' + size);
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fBufferObjectQueryTests.BufferCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fBufferObjectQueryTests.BufferUsageCase = function(name, description) {
+ es3fBufferObjectQueryTests.BufferCase.call(this, name, description);
+ this.m_testAllTargets = false;
+};
+
+setParentClass(es3fBufferObjectQueryTests.BufferUsageCase, es3fBufferObjectQueryTests.BufferCase);
+
+es3fBufferObjectQueryTests.BufferUsageCase.prototype.testBuffer = function() {
+ var usage = /** type {number} */ (gl.getBufferParameter(this.m_bufferTarget, gl.BUFFER_USAGE));
+ this.check(usage == gl.STATIC_DRAW, 'Initial usage should be STATIC_DRAW; got ' + wtu.glEnumToString(gl, usage));
+
+ var usages = [
+ gl.STREAM_DRAW, gl.STREAM_READ,
+ gl.STREAM_COPY, gl.STATIC_DRAW,
+ gl.STATIC_READ, gl.STATIC_COPY,
+ gl.DYNAMIC_DRAW, gl.DYNAMIC_READ,
+ gl.DYNAMIC_COPY
+ ];
+
+ for (var ndx = 0; ndx < usages.length; ++ndx) {
+ gl.bufferData(this.m_bufferTarget, 16, usages[ndx]);
+
+ usage = /** type {number} */ (gl.getBufferParameter(this.m_bufferTarget, gl.BUFFER_USAGE));
+ this.check(usage == usages[ndx], 'Buffer usage should be ' + wtu.glEnumToString(gl, usages[ndx]) + ' ; got ' + wtu.glEnumToString(gl, usage));
+ }
+};
+
+/**
+* @constructor
+* @extends {tcuTestCase.DeqpTest}
+*/
+es3fBufferObjectQueryTests.BufferObjectQueryTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'buffer_object', 'Buffer Object Query tests');
+};
+
+es3fBufferObjectQueryTests.BufferObjectQueryTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fBufferObjectQueryTests.BufferObjectQueryTests.prototype.constructor = es3fBufferObjectQueryTests.BufferObjectQueryTests;
+
+es3fBufferObjectQueryTests.BufferObjectQueryTests.prototype.init = function() {
+ this.addChild(new es3fBufferObjectQueryTests.BufferSizeCase('buffer_size' , 'BUFFER_SIZE'));
+ this.addChild(new es3fBufferObjectQueryTests.BufferUsageCase('buffer_usage' , 'BUFFER_USAGE'));
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fBufferObjectQueryTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fBufferObjectQueryTests.BufferObjectQueryTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fBufferObjectQueryTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBuiltinPrecisionTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBuiltinPrecisionTests.js
new file mode 100644
index 0000000000..d5786180b3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fBuiltinPrecisionTests.js
@@ -0,0 +1,87 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.0 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Tests for precision and range of GLSL builtins and types.
+ *//*--------------------------------------------------------------------*/
+'use strict';
+goog.provide('functional.gles3.es3fBuiltinPrecisionTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('modules.shared.glsBuiltinPrecisionTests');
+
+goog.scope(function() {
+
+ var es3fBuiltinPrecisionTests = functional.gles3.es3fBuiltinPrecisionTests;
+ var glsBuiltinPrecisionTests = modules.shared.glsBuiltinPrecisionTests;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+
+ /**
+ * @param {*} context
+ * @param {number} caseId test case Id
+ * @return {tcuTestCase.DeqpTest}
+ */
+ es3fBuiltinPrecisionTests.createBuiltinPrecisionTests = function(context, caseId) {
+ /** @type {tcuTestCase.DeqpTest} */
+ var group = tcuTestCase.newTest('precision', 'Builtin precision tests');
+
+ /** @type {Array<gluShaderProgram.shaderType>} */ var shaderTypes = [];
+ var es3Cases = glsBuiltinPrecisionTests.createES3BuiltinCases(caseId);
+
+ shaderTypes.push(gluShaderProgram.shaderType.VERTEX);
+ shaderTypes.push(gluShaderProgram.shaderType.FRAGMENT);
+
+ glsBuiltinPrecisionTests.addBuiltinPrecisionTests(es3Cases, shaderTypes, group);
+ return group;
+ };
+
+ /**
+ * Create and execute the test cases
+ * @param {WebGL2RenderingContext} context
+ * @param {number} caseId test case Id
+ */
+ es3fBuiltinPrecisionTests.run = function(context, caseId) {
+ gl = context;
+ // Set up root Test
+ var state = tcuTestCase.runner;
+
+ var test = es3fBuiltinPrecisionTests.createBuiltinPrecisionTests(context, caseId);
+ var testName = test.fullName();
+ var testDescription = test.getDescription() === undefined ? '' : test.getDescription();
+
+ state.testName = testName;
+ state.setRoot(test);
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ test.init();
+ //Run test cases
+ tcuTestCase.runTestCases();
+ } catch (err) {
+ bufferedLogToConsole('Exception: ' + err);
+ testFailedOptions('Failed to es3fAttribLocationTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fClippingTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fClippingTests.js
new file mode 100644
index 0000000000..e261cdea63
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fClippingTests.js
@@ -0,0 +1,406 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fClippingTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.referencerenderer.rrUtil');
+goog.require('functional.gles3.es3fFboTestCase');
+goog.require('functional.gles3.es3fFboTestUtil');
+
+goog.scope(function() {
+var es3fClippingTests = functional.gles3.es3fClippingTests;
+var tcuImageCompare = framework.common.tcuImageCompare;
+var tcuTestCase = framework.common.tcuTestCase;
+var es3fFboTestCase = functional.gles3.es3fFboTestCase;
+var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
+var rrUtil = framework.referencerenderer.rrUtil;
+var gluShaderUtil = framework.opengl.gluShaderUtil;
+var deRandom = framework.delibs.debase.deRandom;
+var deMath = framework.delibs.debase.deMath;
+var tcuRGBA = framework.common.tcuRGBA;
+
+/** @type {WebGL2RenderingContext} */ var gl;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {Array<number>} viewport
+ * @param {Array<number>} rangeX
+ * @param {Array<number>} rangeY
+ * @param {Array<number>} rangeZ
+ */
+es3fClippingTests.TriangleCase = function(name, desc, viewport, rangeX, rangeY, rangeZ) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_viewport = viewport;
+ this.m_rangeX = rangeX;
+ this.m_rangeY = rangeY;
+ this.m_rangeZ = rangeZ;
+};
+
+setParentClass(es3fClippingTests.TriangleCase, es3fFboTestCase.FboTestCase);
+
+es3fClippingTests.TriangleCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var x = this.m_viewport[0];
+ var y = this.m_viewport[1];
+ var width = this.m_viewport[2];
+ var height = this.m_viewport[3];
+ ctx.viewport(x, y, width, height);
+ ctx.clearColor(0, 0, 0, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT);
+
+ var shader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var program = ctx.createProgram(shader);
+ shader.setGradient(ctx, program, [0, 0, 0, 0], [1, 1, 1, 1]);
+
+ rrUtil.drawQuad(ctx, program,
+ [this.m_rangeX[0], this.m_rangeY[0], this.m_rangeZ[0]],
+ [this.m_rangeX[1], this.m_rangeY[1], this.m_rangeZ[1]]);
+ dst.readViewport(ctx, this.m_viewport);
+};
+
+/**
+ * Move the vertex coordinate to pixel center
+ */
+var center = function(x, width) {
+ var half = width / 2;
+ var pos = half + x * half;
+ // almost to the center to avoid problems when rounding
+ // the position the pixel edge
+ pos = Math.round(pos) + 0.49;
+ return (pos - half) / half;
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {Array<number>} viewport
+ * @param {number} lineWidth
+ */
+es3fClippingTests.LinesCase = function(name, desc, viewport, lineWidth) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_viewport = viewport;
+ this.m_lineWidth = lineWidth;
+};
+
+setParentClass(es3fClippingTests.LinesCase, es3fFboTestCase.FboTestCase);
+
+es3fClippingTests.LinesCase.prototype.compare = function(reference, result) {
+ return tcuImageCompare.bilinearCompare('Result', 'Image comparison result',
+ reference.getAccess(),
+ result.getAccess(),
+ tcuRGBA.newRGBAComponents(3, 3, 3, 3));
+};
+
+es3fClippingTests.LinesCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var x = this.m_viewport[0];
+ var y = this.m_viewport[1];
+ var width = this.m_viewport[2];
+ var height = this.m_viewport[3];
+ ctx.viewport(x, y, width, height);
+ ctx.clearColor(0, 0, 0, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT);
+
+ var shader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var program = ctx.createProgram(shader);
+ shader.setGradient(ctx, program, [0, 0, 0, 0], [1, 1, 1, 1]);
+
+ // positions
+ var posLoc = ctx.getAttribLocation(program, 'a_position');
+ if (posLoc == -1)
+ throw new Error('a_position attribute is not defined.');
+
+ var buffer = ctx.createBuffer();
+ ctx.bindBuffer(gl.ARRAY_BUFFER, buffer);
+
+ ctx.lineWidth(this.m_lineWidth);
+
+ var y1 = center(-0.5, height);
+ var y2 = center(-0.2, height);
+ var y3 = center(0.2, height);
+ var y4 = center(0.5, height);
+ var y5 = center(0, height);
+ var x1 = center(-0.5, width);
+ var x2 = center(-0.2, width);
+ var x3 = center(0.2, width);
+ var x4 = center(0.5, width);
+ var positions = [
+ // horizontal check
+ // both ends outside viewport
+ -1 - 1 / width, y1, 0, 1,
+ 1 + 1 / width, y1, 0, 1,
+ // one end inside viewport
+ -1 + 1 / width, y2, 0, 1,
+ 1 + 1 / width, y2, 0, 1,
+
+ -1 - 1 / width, y3, 0, 1,
+ 1 - 1 / width, y3, 0, 1,
+ // both ends inside viewport
+
+ -1 + 1 / width, y4, 0, 1,
+ 1 - 1 / width, y4, 0, 1,
+
+ //vertical check
+ // both ends outside viewport
+ x1, -1 - 1 / height, 0, 1,
+ x1, 1 + 1 / height, 0, 1,
+
+ // one end inside viewport
+ x2, -1 + 1 / height, 0, 1,
+ x2, 1 + 1 / height, 0, 1,
+
+ x3, -1 - 1 / height, 0, 1,
+ x3, 1 - 1 / height, 0, 1,
+ //both ends inside viewport
+ x4, -1 + 1 / height, 0, 1,
+ x4, 1 - 1 / height, 0, 1,
+
+ //depth check
+ -1, y5, -1.5, 1,
+ 1, y5, 1.1, 1
+ ];
+ var numVertices = positions.length / 4;
+
+ ctx.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
+
+ ctx.enableVertexAttribArray(posLoc);
+ ctx.vertexAttribPointer(posLoc, 4, gl.FLOAT, false, 0, 0);
+
+ //colors
+ var coordLoc = ctx.getAttribLocation(program, 'a_coord');
+ if (coordLoc == -1)
+ throw new Error('a_coord attribute is not defined.');
+
+ var buffer2 = ctx.createBuffer();
+ ctx.bindBuffer(gl.ARRAY_BUFFER, buffer2);
+
+ var coords = [];
+ for (var i = 0; i < numVertices / 2; i++) {
+ coords.push(0, 0, 1, 1);
+ }
+ ctx.bufferData(gl.ARRAY_BUFFER, new Float32Array(coords), gl.STATIC_DRAW);
+
+ ctx.enableVertexAttribArray(coordLoc);
+ ctx.vertexAttribPointer(coordLoc, 2, gl.FLOAT, false, 0, 0);
+
+ ctx.drawArrays(gl.LINES, 0, numVertices);
+ ctx.disableVertexAttribArray(posLoc);
+ ctx.disableVertexAttribArray(coordLoc);
+ ctx.bindBuffer(gl.ARRAY_BUFFER, null);
+ ctx.deleteBuffer(buffer);
+ ctx.deleteBuffer(buffer2);
+ dst.readViewport(ctx, this.m_viewport);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {Array<number>} viewport
+ * @param {number} pointSize
+ */
+es3fClippingTests.PointsCase = function(name, desc, viewport, pointSize) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_viewport = viewport;
+ this.m_pointSize = pointSize;
+};
+
+setParentClass(es3fClippingTests.PointsCase, es3fFboTestCase.FboTestCase);
+
+es3fClippingTests.PointsCase.prototype.compare = function(reference, result) {
+ return tcuImageCompare.bilinearCompare('Result', 'Image comparison result',
+ reference.getAccess(),
+ result.getAccess(),
+ tcuRGBA.newRGBAComponents(3, 3, 3, 3));
+};
+
+es3fClippingTests.PointsCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var x = this.m_viewport[0];
+ var y = this.m_viewport[1];
+ var width = this.m_viewport[2];
+ var height = this.m_viewport[3];
+ ctx.viewport(x, y, width, height);
+ ctx.clearColor(0, 0, 0, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT);
+
+ var shader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4, this.m_pointSize);
+ var program = ctx.createProgram(shader);
+ shader.setColor(ctx, program, [0, 1, 0, 1]);
+
+ // positions
+ var posLoc = ctx.getAttribLocation(program, 'a_position');
+ if (posLoc == -1)
+ throw new Error('a_position attribute is not defined.');
+
+ var buffer = ctx.createBuffer();
+ ctx.bindBuffer(gl.ARRAY_BUFFER, buffer);
+
+ var positions = [
+ // clipping in X axis
+ -1 - 1 / width, -0.5, 0, 1,
+ -1, 0, 0, 1,
+ -1 + 1 / width, 0.5, 0, 1,
+ 1 + 1 / width, -0.5, 0, 1,
+ 1, 0, 0, 1,
+ 1 - 1 / width, 0.5, 0, 1,
+ // clipping in Y axis
+ -0.5, -1 - 1 / height, 0, 1,
+ 0, -1, 0, 1,
+ 0.5, -1 + 1 / height, 0, 1,
+ -0.5, 1 - 1 / height, 0, 1,
+ 0, 1, 0, 1,
+ 0.5, 1 + 1 / height, 0, 1,
+ // clipping in Z axis
+ -0.5, -0.5, -1.5, 1,
+ 0, 0, 0, 1,
+ 0.5, 0.5, 1.5, 1
+ ];
+ // move the vertices to pixel centers to avoid off-by-1 differences
+ for (var i = 0; i < positions.length; i += 4) {
+ positions[i + 0] = center(positions[i + 0], width);
+ positions[i + 1] = center(positions[i + 1], height);
+ }
+ // positions = [-1 + 3/width + 0.001, 1 + 1/height + 0.001, 0, 1];
+ // positions = [-1, -1, 0, 1];
+
+ var numVertices = positions.length / 4;
+
+ ctx.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
+
+ ctx.enableVertexAttribArray(posLoc);
+ ctx.vertexAttribPointer(posLoc, 4, gl.FLOAT, false, 0, 0);
+
+ ctx.drawArrays(gl.POINTS, 0, numVertices);
+ ctx.disableVertexAttribArray(posLoc);
+ ctx.bindBuffer(gl.ARRAY_BUFFER, null);
+ ctx.deleteBuffer(buffer);
+ dst.readViewport(ctx, this.m_viewport);
+};
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+es3fClippingTests.ClippingTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'clipping', 'Clipping tests');
+};
+
+es3fClippingTests.ClippingTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fClippingTests.ClippingTests.prototype.constructor = es3fClippingTests.ClippingTests;
+
+es3fClippingTests.ClippingTests.prototype.init = function() {
+ var width = gl.drawingBufferWidth;
+ var height = gl.drawingBufferHeight;
+ /** @const */ var WIDE_POINT = 5;
+ /** @const */ var WIDE_LINE = 5;
+ var viewports = [{ name: 'full_viewport', v: [0, 0, width, height] }, {
+ name: 'partial_viewport', v: [width * 0.3 , height * 0.2 , width * 0.6, height * 0.5] }
+ ];
+ var pointSizeRange = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
+ var lineWidthRange = gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE);
+
+ for (var i = 0; i < viewports.length; i++) {
+ var v = viewports[i].v.map(Math.floor);
+ var vName = viewports[i].name;
+ this.addChild(new es3fClippingTests.LinesCase('narrow_lines_' + vName, 'lines', v, 1));
+ if (lineWidthRange[1] >= WIDE_LINE)
+ this.addChild(new es3fClippingTests.LinesCase('wide_lines_' + vName, 'lines', v, WIDE_LINE));
+ this.addChild(new es3fClippingTests.PointsCase('small_points_' + vName, 'points', v, 1));
+ if (pointSizeRange[1] >= WIDE_POINT)
+ this.addChild(new es3fClippingTests.PointsCase('wide_points_' + vName, 'points', v, WIDE_POINT));
+ }
+
+ var rangesX = [
+ [-1.2, 1.2],
+ [-1.2, 0.8],
+ [-0.8, 1.2]
+ ];
+ var rangesY = [
+ [-1.2, 1.2],
+ [-1.2, 0.8],
+ [-0.8, 1.2]
+ ];
+ var rangesZ = [
+ [-1.2, 1.2],
+ [1.2, -1.2]
+ ];
+ for (var i = 0; i < viewports.length; i++) {
+ var v = viewports[i].v.map(Math.floor);
+ var vName = viewports[i].name;
+ for (var x = 0; x < rangesX.length; x++)
+ for (var y = 0; y < rangesY.length; y++)
+ for (var z = 0; z < rangesZ.length; z++) {
+ var rangeX = rangesX[x];
+ var rangeY = rangesY[y];
+ var rangeZ = rangesZ[z];
+ var name = 'triangles_' + viewports[i].name + '_' +
+ '(' + rangeX[0] + ',' + rangeY[0] + ',' + rangeZ[0] + ')-' +
+ '(' + rangeX[1] + ',' + rangeY[1] + ',' + rangeZ[1] + ')';
+ this.addChild(new es3fClippingTests.TriangleCase(name, 'triangles', v,
+ rangeX,
+ rangeY,
+ rangeZ));
+ }
+ }
+};
+
+/**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+es3fClippingTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fClippingTests.ClippingTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fClippingTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fDefaultVertexAttributeTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fDefaultVertexAttributeTests.js
new file mode 100644
index 0000000000..863bc4deda
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fDefaultVertexAttributeTests.js
@@ -0,0 +1,546 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fDefaultVertexAttributeTests');
+goog.require('framework.common.tcuLogImage');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluShaderUtil');
+
+goog.scope(function() {
+var es3fDefaultVertexAttributeTests = functional.gles3.es3fDefaultVertexAttributeTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var tcuSurface = framework.common.tcuSurface;
+var deMath = framework.delibs.debase.deMath;
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+var gluShaderUtil = framework.opengl.gluShaderUtil;
+var tcuLogImage = framework.common.tcuLogImage;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+/**
+ * @constructor
+ */
+es3fDefaultVertexAttributeTests.LoaderVertexAttrib1f = function() {
+ this.caseName = 'vertex_attrib_1f';
+ this.name = 'VertexAttrib1f';
+ this.signed = true;
+ this.load = function(index, value) {
+ gl.vertexAttrib1f(index, value[0]);
+ return [value[0], 0, 0, 1];
+ };
+};
+
+/**
+ * @constructor
+ */
+es3fDefaultVertexAttributeTests.LoaderVertexAttrib2f = function() {
+ this.caseName = 'vertex_attrib_2f';
+ this.name = 'VertexAttrib2f';
+ this.signed = true;
+ this.load = function(index, value) {
+ gl.vertexAttrib2f(index, value[0], value[1]);
+ return [value[0], value[1], 0, 1];
+ };
+};
+
+/**
+ * @constructor
+ */
+es3fDefaultVertexAttributeTests.LoaderVertexAttrib3f = function() {
+ this.caseName = 'vertex_attrib_3f';
+ this.name = 'VertexAttrib3f';
+ this.signed = true;
+ this.load = function(index, value) {
+ gl.vertexAttrib3f(index, value[0], value[1], value[2]);
+ return [value[0], value[1], value[2], 1];
+ };
+};
+
+/**
+ * @constructor
+ */
+es3fDefaultVertexAttributeTests.LoaderVertexAttrib4f = function() {
+ this.caseName = 'vertex_attrib_4f';
+ this.name = 'VertexAttrib4f';
+ this.signed = true;
+ this.load = function(index, value) {
+ gl.vertexAttrib4f(index, value[0], value[1], value[2], value[3]);
+ return [value[0], value[1], value[2], value[3]];
+ };
+};
+
+/**
+ * @constructor
+ */
+es3fDefaultVertexAttributeTests.LoaderVertexAttrib1fv = function() {
+ this.caseName = 'vertex_attrib_1fv';
+ this.name = 'VertexAttrib1fv';
+ this.signed = true;
+ this.load = function(index, value) {
+ gl.vertexAttrib1fv(index, value.slice(0, 1));
+ return [value[0], 0, 0, 1];
+ };
+};
+
+/**
+ * @constructor
+ */
+es3fDefaultVertexAttributeTests.LoaderVertexAttrib2fv = function() {
+ this.caseName = 'vertex_attrib_2fv';
+ this.name = 'VertexAttrib2fv';
+ this.signed = true;
+ this.load = function(index, value) {
+ gl.vertexAttrib2fv(index, value.slice(0, 2));
+ return [value[0], value[1], 0, 1];
+ };
+};
+
+/**
+ * @constructor
+ */
+es3fDefaultVertexAttributeTests.LoaderVertexAttrib3fv = function() {
+ this.caseName = 'vertex_attrib_3fv';
+ this.name = 'VertexAttrib3fv';
+ this.signed = true;
+ this.load = function(index, value) {
+ gl.vertexAttrib3fv(index, value.slice(0, 3));
+ return [value[0], value[1], value[2], 1];
+ };
+};
+
+/**
+ * @constructor
+ */
+es3fDefaultVertexAttributeTests.LoaderVertexAttrib4fv = function() {
+ this.caseName = 'vertex_attrib_4fv';
+ this.name = 'VertexAttrib4fv';
+ this.signed = true;
+ this.load = function(index, value) {
+ gl.vertexAttrib4fv(index, value.slice(0, 4));
+ return [value[0], value[1], value[2], value[3]];
+ };
+};
+
+/**
+ * @constructor
+ */
+es3fDefaultVertexAttributeTests.LoaderVertexAttribI4i = function() {
+ this.caseName = 'vertex_attrib_4i';
+ this.name = 'VertexAttribI4i';
+ this.signed = true;
+ this.load = function(index, value) {
+ var v = new Int32Array(value);
+ gl.vertexAttribI4i(index, v[0], v[1], v[2], v[3]);
+ return [v[0], v[1], v[2], v[3]];
+ };
+};
+
+/**
+ * @constructor
+ */
+es3fDefaultVertexAttributeTests.LoaderVertexAttribI4iv = function() {
+ this.caseName = 'vertex_attrib_4iv';
+ this.name = 'VertexAttribI4iv';
+ this.signed = true;
+ this.load = function(index, value) {
+ var v = new Int32Array(value);
+ gl.vertexAttribI4iv(index, v);
+ return [v[0], v[1], v[2], v[3]];
+ };
+};
+
+/**
+ * @constructor
+ */
+es3fDefaultVertexAttributeTests.LoaderVertexAttribI4ui = function() {
+ this.caseName = 'vertex_attrib_4ui';
+ this.name = 'VertexAttribI4ui';
+ this.signed = false;
+ this.load = function(index, value) {
+ var v = new Uint32Array(value);
+ gl.vertexAttribI4ui(index, v[0], v[1], v[2], v[3]);
+ return [v[0], v[1], v[2], v[3]];
+ };
+};
+
+/**
+ * @constructor
+ */
+es3fDefaultVertexAttributeTests.LoaderVertexAttribI4uiv = function() {
+ this.caseName = 'vertex_attrib_4uiv';
+ this.name = 'VertexAttribI4uiv';
+ this.signed = false;
+ this.load = function(index, value) {
+ var v = new Uint32Array(value);
+ gl.vertexAttribI4uiv(index, v);
+ return [v[0], v[1], v[2], v[3]];
+ };
+};
+
+/** @const */ var RENDER_SIZE = 32;
+/** @const */ var s_valueRange = 10;
+/** @const */ var s_passThroughFragmentShaderSource = '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;\n' +
+ 'in mediump vec4 v_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = v_color;\n' +
+ '}\n';
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+es3fDefaultVertexAttributeTests.AttributeCase = function(loaderType, dataType) {
+ var loader = new loaderType();
+ var name = loader.caseName;
+ var description = 'Test ' + loader.name;
+ tcuTestCase.DeqpTest.call(this, name, description);
+ this.m_funcName = loader.name;
+ this.m_useNegativeValues = loader.signed;
+ this.m_dataType = dataType;
+ this.m_allIterationsPassed = true;
+ this.m_loader = loader;
+ this.m_iteration = 0;
+};
+
+setParentClass(es3fDefaultVertexAttributeTests.AttributeCase, tcuTestCase.DeqpTest);
+
+es3fDefaultVertexAttributeTests.AttributeCase.prototype.init = function() {
+ // log test info
+
+ var maxRange = s_valueRange;
+ var minRange = (this.m_useNegativeValues) ? (-maxRange) : (0.0);
+
+ bufferedLogToConsole(
+ 'Loading attribute values using ' + this.m_funcName + '\n' +
+ 'Attribute type: ' + gluShaderUtil.getDataTypeName(this.m_dataType) + '\n' +
+ 'Attribute value range: [' + minRange + ', ' + maxRange + ']');
+
+ // gen shader and base quad
+
+ this.m_program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(this.genVertexSource(), s_passThroughFragmentShaderSource));
+ if (!this.m_program.isOk())
+ testFailedOptions('could not build program', true);
+
+ var fullscreenQuad = [
+ 1.0, 1.0, 0.0, 1.0,
+ 1.0, -1.0, 0.0, 1.0,
+ -1.0, 1.0, 0.0, 1.0,
+ -1.0, -1.0, 0.0, 1.0
+ ];
+
+ this.m_bufID = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.m_bufID);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(fullscreenQuad), gl.STATIC_DRAW);
+};
+
+es3fDefaultVertexAttributeTests.AttributeCase.prototype.deinit = function() {
+ this.m_loader = null;
+
+ gl.useProgram(null);
+ this.m_program = null;
+
+ if (this.m_bufID) {
+ gl.deleteBuffer(this.m_bufID);
+ this.m_bufID = null;
+ }
+};
+
+es3fDefaultVertexAttributeTests.AttributeCase.prototype.iterate = function() {
+ var testValues = [
+ [0.0, 0.5, 0.2, 1.0],
+ [0.1, 0.7, 1.0, 0.6],
+ [0.4, 0.2, 0.0, 0.5],
+ [0.5, 0.0, 0.9, 0.1],
+ [0.6, 0.2, 0.2, 0.9],
+ [0.9, 1.0, 0.0, 0.0],
+ [1.0, 0.5, 0.3, 0.8]
+ ];
+
+ bufferedLogToConsole('Iteration ' + (this.m_iteration + 1) + '/' + testValues.length);
+
+ var testValue = this.m_useNegativeValues ?
+ deMath.subScalar(deMath.scale(testValues[this.m_iteration], 2), 1) :
+ deMath.scale(testValues[this.m_iteration], s_valueRange);
+
+ if (!this.renderWithValue(testValue))
+ this.m_allIterationsPassed = false;
+
+ // continue
+
+ if (++this.m_iteration < testValues.length)
+ return tcuTestCase.IterateResult.CONTINUE;
+
+ if (this.m_allIterationsPassed)
+ testPassed();
+ else
+ testFailed('Got unexpected values');
+
+ return tcuTestCase.IterateResult.STOP;
+};
+
+es3fDefaultVertexAttributeTests.AttributeCase.prototype.genVertexSource = function() {
+ var vectorSize = (gluShaderUtil.isDataTypeMatrix(this.m_dataType)) ? (gluShaderUtil.getDataTypeMatrixNumRows(this.m_dataType)) : (gluShaderUtil.isDataTypeVector(this.m_dataType)) ? (gluShaderUtil.getDataTypeScalarSize(this.m_dataType)) : (-1);
+ var vectorType = gluShaderUtil.getDataTypeName((gluShaderUtil.isDataTypeMatrix(this.m_dataType)) ? (gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.FLOAT, vectorSize)) : (gluShaderUtil.isDataTypeVector(this.m_dataType)) ? (gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.FLOAT, vectorSize)) : (gluShaderUtil.DataType.FLOAT));
+ var components = (gluShaderUtil.isDataTypeMatrix(this.m_dataType)) ? (gluShaderUtil.getDataTypeMatrixNumRows(this.m_dataType)) : (gluShaderUtil.getDataTypeScalarSize(this.m_dataType));
+
+ var buf = '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in highp ' + gluShaderUtil.getDataTypeName(this.m_dataType) + ' a_value;\n' +
+ 'out highp vec4 v_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ '\n';
+
+ buf += ' highp ' + vectorType + ' normalizedValue = ' + ((gluShaderUtil.getDataTypeScalarType(this.m_dataType) == gluShaderUtil.DataType.FLOAT) ? ('') : (vectorType)) + '(a_value' + ((gluShaderUtil.isDataTypeMatrix(this.m_dataType)) ? ('[1]') : ('')) + ') / float(' + s_valueRange + ');\n';
+
+ if (this.m_useNegativeValues)
+ buf += ' highp ' + vectorType + ' positiveNormalizedValue = (normalizedValue + ' + vectorType + '(1.0)) / 2.0;\n';
+ else
+ buf += ' highp ' + vectorType + ' positiveNormalizedValue = normalizedValue;\n';
+
+ if (components == 1)
+ buf += ' v_color = vec4(positiveNormalizedValue, 0.0, 0.0, 1.0);\n';
+ else if (components == 2)
+ buf += ' v_color = vec4(positiveNormalizedValue.xy, 0.0, 1.0);\n';
+ else if (components == 3)
+ buf += ' v_color = vec4(positiveNormalizedValue.xyz, 1.0);\n';
+ else if (components == 4)
+ buf += ' v_color = vec4((positiveNormalizedValue.xy + positiveNormalizedValue.zz) / 2.0, positiveNormalizedValue.w, 1.0);\n';
+ else
+ throw new Error('Wrong component size: ' + components);
+
+ buf += '}\n';
+
+ return buf;
+};
+
+es3fDefaultVertexAttributeTests.AttributeCase.prototype.renderWithValue = function(v) {
+ var positionIndex = gl.getAttribLocation(this.m_program.getProgram(), 'a_position');
+ var valueIndex = gl.getAttribLocation(this.m_program.getProgram(), 'a_value');
+ var dest = new tcuSurface.Surface(RENDER_SIZE, RENDER_SIZE);
+
+ gl.clearColor(0.0, 0.0, 0.0, 0.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.viewport(0, 0, RENDER_SIZE, RENDER_SIZE);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.m_bufID);
+ gl.vertexAttribPointer(positionIndex, 4, gl.FLOAT, false, 0, 0);
+ gl.enableVertexAttribArray(positionIndex);
+
+ // transfer test value. Load to the second column in the matrix case
+ var loadedValue = this.m_loader.load((gluShaderUtil.isDataTypeMatrix(this.m_dataType)) ? (valueIndex + 1) : (valueIndex), v);
+
+ gl.useProgram(this.m_program.getProgram());
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
+ gl.useProgram(null);
+ // The original c++ test does not disable vertex attrib array, which is wrong.
+ // On most drivers all tests pass because a_position is assigned location 0.
+ // On MacOSX some tests fail because a_value is assigned location 0 and vertex
+ // attrib array is left enabled and affects later tests.
+ gl.disableVertexAttribArray(positionIndex);
+ dest.readViewport(gl);
+
+ // check whole result is colored correctly
+ return this.verifyUnicoloredBuffer(dest, this.computeColor(loadedValue));
+};
+
+es3fDefaultVertexAttributeTests.AttributeCase.prototype.computeColor = function(value) {
+ var normalizedValue = deMath.scale(value, 1 / s_valueRange);
+ var positiveNormalizedValue = this.m_useNegativeValues ?
+ deMath.scale(deMath.addScalar(normalizedValue, 1), 0.5) :
+ normalizedValue;
+ var components = (gluShaderUtil.isDataTypeMatrix(this.m_dataType)) ? (gluShaderUtil.getDataTypeMatrixNumRows(this.m_dataType)) : (gluShaderUtil.getDataTypeScalarSize(this.m_dataType));
+
+ if (components == 1)
+ return [positiveNormalizedValue[0], 0.0, 0.0, 1.0];
+ else if (components == 2)
+ return [positiveNormalizedValue[0], positiveNormalizedValue[1], 0.0, 1.0];
+ else if (components == 3)
+ return [positiveNormalizedValue[0], positiveNormalizedValue[1], positiveNormalizedValue[2], 1.0];
+ else if (components == 4)
+ return [(positiveNormalizedValue[0] + positiveNormalizedValue[2]) / 2.0, (positiveNormalizedValue[1] + positiveNormalizedValue[2]) / 2.0, positiveNormalizedValue[3], 1.0];
+ else
+ throw new Error('Wrong component size: ' + components);
+};
+
+/**
+ * @param {tcuSurface.Surface} scene
+ * @param {Array<number>} refColor
+ * @return {boolean}
+ */
+es3fDefaultVertexAttributeTests.AttributeCase.prototype.verifyUnicoloredBuffer = function(scene, refColor) {
+ var access = scene.getAccess();
+ var errorMask = new tcuSurface.Surface(RENDER_SIZE, RENDER_SIZE);
+ var colorThreshold = [6, 6, 6, 6];
+ var error = false;
+
+ errorMask.getAccess().clear([0, 1, 0, 1]);
+
+ bufferedLogToConsole('Verifying rendered image. Expecting color ' + refColor + ', threshold ' + colorThreshold);
+
+ for (var y = 0; y < RENDER_SIZE; ++y)
+ for (var x = 0; x < RENDER_SIZE; ++x) {
+ var color = access.getPixel(x, y);
+
+ if (Math.abs(color[0] - refColor[0]) > colorThreshold[0] ||
+ Math.abs(color[1] - refColor[1]) > colorThreshold[1] ||
+ Math.abs(color[2] - refColor[2]) > colorThreshold[2]) {
+
+ // first error
+ if (!error)
+ debug('Found invalid pixel(s). Pixel at (' + x + ', ' + y + ') color: ' + color);
+
+ error = true;
+ errorMask.setPixel(x, y, [1, 0, 0, 1]);
+ }
+ }
+
+ if (!error)
+ bufferedLogToConsole('Rendered image is valid.');
+ else {
+ tcuLogImage.logImage('Result', '', access);
+ tcuLogImage.logImage('Error mask', '', errorMask.getAccess());
+ }
+
+ return !error;
+};
+
+/**
+* @constructor
+* @extends {tcuTestCase.DeqpTest}
+*/
+es3fDefaultVertexAttributeTests.DefaultVertexAttributeTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'default_vertex_attrib', 'Test default vertex attributes');
+};
+
+es3fDefaultVertexAttributeTests.DefaultVertexAttributeTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fDefaultVertexAttributeTests.DefaultVertexAttributeTests.prototype.constructor = es3fDefaultVertexAttributeTests.DefaultVertexAttributeTests;
+
+es3fDefaultVertexAttributeTests.DefaultVertexAttributeTests.prototype.init = function() {
+ var tests = this;
+ var floatTargets = [
+ ['float', gluShaderUtil.DataType.FLOAT, false],
+ ['vec2', gluShaderUtil.DataType.FLOAT_VEC2, true],
+ ['vec3', gluShaderUtil.DataType.FLOAT_VEC3, true],
+ ['vec4', gluShaderUtil.DataType.FLOAT_VEC4, false],
+ ['mat2', gluShaderUtil.DataType.FLOAT_MAT2, true],
+ ['mat2x3', gluShaderUtil.DataType.FLOAT_MAT2X3, true],
+ ['mat2x4', gluShaderUtil.DataType.FLOAT_MAT2X4, true],
+ ['mat3', gluShaderUtil.DataType.FLOAT_MAT3, true],
+ ['mat3x2', gluShaderUtil.DataType.FLOAT_MAT3X2, true],
+ ['mat3x4', gluShaderUtil.DataType.FLOAT_MAT3X4, true],
+ ['mat4', gluShaderUtil.DataType.FLOAT_MAT4, false],
+ ['mat4x2', gluShaderUtil.DataType.FLOAT_MAT4X2, true],
+ ['mat4x3', gluShaderUtil.DataType.FLOAT_MAT4X3, true]
+ ];
+
+ floatTargets.forEach(function(elem) {
+ var name = elem[0];
+ var dataType = elem[1];
+ var reduced = elem[2];
+ var group = new tcuTestCase.DeqpTest(name, 'test with ' + name);
+ tests.addChild(group);
+ group.addChild(new es3fDefaultVertexAttributeTests.AttributeCase(es3fDefaultVertexAttributeTests.LoaderVertexAttrib1f, dataType));
+ if (!reduced) {
+ group.addChild(new es3fDefaultVertexAttributeTests.AttributeCase(es3fDefaultVertexAttributeTests.LoaderVertexAttrib2f, dataType));
+ group.addChild(new es3fDefaultVertexAttributeTests.AttributeCase(es3fDefaultVertexAttributeTests.LoaderVertexAttrib3f, dataType));
+ }
+ group.addChild(new es3fDefaultVertexAttributeTests.AttributeCase(es3fDefaultVertexAttributeTests.LoaderVertexAttrib4f, dataType));
+
+ group.addChild(new es3fDefaultVertexAttributeTests.AttributeCase(es3fDefaultVertexAttributeTests.LoaderVertexAttrib1fv, dataType));
+ if (!reduced) {
+ group.addChild(new es3fDefaultVertexAttributeTests.AttributeCase(es3fDefaultVertexAttributeTests.LoaderVertexAttrib2fv, dataType));
+ group.addChild(new es3fDefaultVertexAttributeTests.AttributeCase(es3fDefaultVertexAttributeTests.LoaderVertexAttrib3fv, dataType));
+ }
+ group.addChild(new es3fDefaultVertexAttributeTests.AttributeCase(es3fDefaultVertexAttributeTests.LoaderVertexAttrib4fv, dataType));
+
+ });
+
+ var intTargets = [
+ ['int', gluShaderUtil.DataType.INT, false],
+ ['ivec2', gluShaderUtil.DataType.INT_VEC2, true],
+ ['ivec3', gluShaderUtil.DataType.INT_VEC3, true],
+ ['ivec4', gluShaderUtil.DataType.INT_VEC4, false]
+ ];
+
+ intTargets.forEach(function(elem) {
+ var name = elem[0];
+ var dataType = elem[1];
+ var reduced = elem[2];
+ var group = new tcuTestCase.DeqpTest(name, 'test with ' + name);
+ tests.addChild(group);
+ group.addChild(new es3fDefaultVertexAttributeTests.AttributeCase(es3fDefaultVertexAttributeTests.LoaderVertexAttribI4i, dataType));
+ group.addChild(new es3fDefaultVertexAttributeTests.AttributeCase(es3fDefaultVertexAttributeTests.LoaderVertexAttribI4iv, dataType));
+ });
+
+ var uintTargets = [
+ ['uint', gluShaderUtil.DataType.UINT, false],
+ ['uvec2', gluShaderUtil.DataType.UINT_VEC2, true],
+ ['uvec3', gluShaderUtil.DataType.UINT_VEC3, true],
+ ['uvec4', gluShaderUtil.DataType.UINT_VEC4, false]
+ ];
+
+ uintTargets.forEach(function(elem) {
+ var name = elem[0];
+ var dataType = elem[1];
+ var reduced = elem[2];
+ var group = new tcuTestCase.DeqpTest(name, 'test with ' + name);
+ tests.addChild(group);
+ group.addChild(new es3fDefaultVertexAttributeTests.AttributeCase(es3fDefaultVertexAttributeTests.LoaderVertexAttribI4ui, dataType));
+ group.addChild(new es3fDefaultVertexAttributeTests.AttributeCase(es3fDefaultVertexAttributeTests.LoaderVertexAttribI4uiv, dataType));
+ });
+
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fDefaultVertexAttributeTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fDefaultVertexAttributeTests.DefaultVertexAttributeTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fDefaultVertexAttributeTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fDrawTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fDrawTests.js
new file mode 100644
index 0000000000..df42ac8193
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fDrawTests.js
@@ -0,0 +1,1155 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fDrawTests');
+goog.require('framework.common.tcuLogImage');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.delibs.debase.deUtil');
+goog.require('framework.opengl.gluDrawUtil');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTexture');
+goog.require('framework.opengl.gluVarType');
+goog.require('framework.opengl.simplereference.sglrGLContext');
+goog.require('framework.opengl.simplereference.sglrShaderProgram');
+goog.require('framework.referencerenderer.rrFragmentOperations');
+goog.require('framework.referencerenderer.rrGenericVector');
+goog.require('framework.referencerenderer.rrShadingContext');
+goog.require('framework.referencerenderer.rrVertexAttrib');
+goog.require('framework.referencerenderer.rrVertexPacket');
+goog.require('modules.shared.glsDrawTests');
+
+goog.scope(function() {
+
+ var es3fDrawTests = functional.gles3.es3fDrawTests;
+ var gluDrawUtil = framework.opengl.gluDrawUtil;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var gluTexture = framework.opengl.gluTexture;
+ var gluVarType = framework.opengl.gluVarType;
+ var tcuLogImage = framework.common.tcuLogImage;
+ var tcuRGBA = framework.common.tcuRGBA;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuTexture = framework.common.tcuTexture;
+ var deMath = framework.delibs.debase.deMath;
+ var deString = framework.delibs.debase.deString;
+ var deRandom = framework.delibs.debase.deRandom;
+ var deUtil = framework.delibs.debase.deUtil;
+ var glsDrawTests = modules.shared.glsDrawTests;
+ var sglrShaderProgram = framework.opengl.simplereference.sglrShaderProgram;
+ var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
+ var rrFragmentOperations = framework.referencerenderer.rrFragmentOperations;
+ var rrGenericVector = framework.referencerenderer.rrGenericVector;
+ var rrShadingContext = framework.referencerenderer.rrShadingContext;
+ var rrVertexAttrib = framework.referencerenderer.rrVertexAttrib;
+ var rrVertexPacket = framework.referencerenderer.rrVertexPacket;
+
+ /** @type {WebGL2RenderingContext}*/ var gl;
+
+ /**
+ * @enum
+ */
+ es3fDrawTests.TestIterationType = {
+ DRAW_COUNT: 0, // !< test with 2, 6, and 26 primitives
+ INSTANCE_COUNT: 1, // !< test with 2, 4, and 12 instances
+ INDEX_RANGE: 2
+ };
+
+ /**
+ * @param {glsDrawTests.DrawTest} test
+ * @param {glsDrawTests.DrawTestSpec} baseSpec
+ * @param {?es3fDrawTests.TestIterationType} type
+ */
+ es3fDrawTests.addTestIterations = function(test, baseSpec, type) {
+ var spec = /** @type {glsDrawTests.DrawTestSpec} */ (deUtil.clone(baseSpec));
+
+ if (type == es3fDrawTests.TestIterationType.DRAW_COUNT) {
+ spec.primitiveCount = 1;
+ test.addIteration(spec, 'draw count = ' + spec.primitiveCount);
+
+ spec.primitiveCount = 5;
+ test.addIteration(spec, 'draw count = ' + spec.primitiveCount);
+
+ spec.primitiveCount = 25;
+ test.addIteration(spec, 'draw count = ' + spec.primitiveCount);
+ } else if (type == es3fDrawTests.TestIterationType.INSTANCE_COUNT) {
+ spec.instanceCount = 1;
+ test.addIteration(spec, 'instance count = ' + spec.instanceCount);
+
+ spec.instanceCount = 4;
+ test.addIteration(spec, 'instance count = ' + spec.instanceCount);
+
+ spec.instanceCount = 11;
+ test.addIteration(spec, 'instance count = ' + spec.instanceCount);
+ } else if (type == es3fDrawTests.TestIterationType.INDEX_RANGE) {
+ spec.indexMin = 0;
+ spec.indexMax = 23;
+ test.addIteration(spec, 'index range = [' + spec.indexMin + ', ' + spec.indexMax + ']');
+
+ spec.indexMin = 23;
+ spec.indexMax = 40;
+ test.addIteration(spec, 'index range = [' + spec.indexMin + ', ' + spec.indexMax + ']');
+
+ // Only makes sense with points
+ if (spec.primitive == glsDrawTests.DrawTestSpec.Primitive.POINTS) {
+ spec.indexMin = 5;
+ spec.indexMax = 5;
+ test.addIteration(spec, 'index range = [' + spec.indexMin + ', ' + spec.indexMax + ']');
+ }
+ } else
+ throw new Error('Invalid test iteration type');
+ };
+
+ /**
+ * @param {glsDrawTests.DrawTestSpec} spec
+ * @param {?glsDrawTests.DrawTestSpec.DrawMethod} method
+ */
+ es3fDrawTests.genBasicSpec = function(spec, method) {
+ //spec.apiType = glu::ApiType::es(3,0);
+ spec.primitive = glsDrawTests.DrawTestSpec.Primitive.TRIANGLES;
+ spec.primitiveCount = 6;
+ spec.drawMethod = method;
+ spec.indexType = null;
+ spec.indexPointerOffset = 0;
+ spec.indexStorage = null;
+ spec.first = 0;
+ spec.indexMin = 0;
+ spec.indexMax = 0;
+ spec.instanceCount = 1;
+
+ spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
+
+ spec.attribs[0].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
+ spec.attribs[0].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
+ spec.attribs[0].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
+ spec.attribs[0].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
+ spec.attribs[0].componentCount = 4;
+ spec.attribs[0].offset = 0;
+ spec.attribs[0].stride = 0;
+ spec.attribs[0].normalize = false;
+ spec.attribs[0].instanceDivisor = 0;
+ spec.attribs[0].useDefaultAttribute = false;
+
+ spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
+
+ spec.attribs[1].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
+ spec.attribs[1].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
+ spec.attribs[1].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
+ spec.attribs[1].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
+ spec.attribs[1].componentCount = 2;
+ spec.attribs[1].offset = 0;
+ spec.attribs[1].stride = 0;
+ spec.attribs[1].normalize = false;
+ spec.attribs[1].instanceDivisor = 0;
+ spec.attribs[1].useDefaultAttribute = false;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} descr
+ * @param {?glsDrawTests.DrawTestSpec.DrawMethod} drawMethod
+ * @param {?glsDrawTests.DrawTestSpec.Primitive} primitive
+ * @param {?glsDrawTests.DrawTestSpec.IndexType} indexType
+ * @param {?glsDrawTests.DrawTestSpec.Storage} indexStorage
+ */
+ es3fDrawTests.AttributeGroup = function(name, descr, drawMethod, primitive, indexType, indexStorage) {
+ tcuTestCase.DeqpTest.call(this, name, descr);
+ this.m_method = drawMethod;
+ this.m_primitive = primitive;
+ this.m_indexType = indexType;
+ this.m_indexStorage = indexStorage;
+ this.makeExecutable();
+ };
+
+ es3fDrawTests.AttributeGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fDrawTests.AttributeGroup.prototype.constructor = es3fDrawTests.AttributeGroup;
+
+ es3fDrawTests.AttributeGroup.prototype.init = function() {
+ // select test type
+ /** @type {boolean} */ var instanced = this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS_INSTANCED ||
+ this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_INSTANCED;
+ /** @type {boolean} */ var ranged = this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED;
+ /** @type {es3fDrawTests.TestIterationType} */ var testType = instanced ? es3fDrawTests.TestIterationType.INSTANCE_COUNT :
+ (ranged ? es3fDrawTests.TestIterationType.INDEX_RANGE : es3fDrawTests.TestIterationType.DRAW_COUNT);
+
+ // Single attribute
+ /** @type {glsDrawTests.DrawTest} */ var test = new glsDrawTests.DrawTest(null, 'single_attribute', 'Single attribute array.');
+ /** @type {glsDrawTests.DrawTestSpec} */ var spec = new glsDrawTests.DrawTestSpec();
+
+ //spec.apiType = glu::ApiType::es(3,0);
+ spec.primitive = this.m_primitive;
+ spec.primitiveCount = 5;
+ spec.drawMethod = this.m_method;
+ spec.indexType = this.m_indexType;
+ spec.indexPointerOffset = 0;
+ spec.indexStorage = this.m_indexStorage;
+ spec.first = 0;
+ spec.indexMin = 0;
+ spec.indexMax = 0;
+ spec.instanceCount = 1;
+
+ spec.attribs.length = 0;
+
+ spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
+ spec.attribs[0].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
+ spec.attribs[0].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
+ spec.attribs[0].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
+ spec.attribs[0].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
+ spec.attribs[0].componentCount = 2;
+ spec.attribs[0].offset = 0;
+ spec.attribs[0].stride = 0;
+ spec.attribs[0].normalize = false;
+ spec.attribs[0].instanceDivisor = 0;
+ spec.attribs[0].useDefaultAttribute = false;
+
+ es3fDrawTests.addTestIterations(test, spec, testType);
+
+ this.addChild(test);
+
+ // Multiple attribute
+
+ test = new glsDrawTests.DrawTest(null, 'multiple_attributes', 'Multiple attribute arrays.');
+ spec.primitive = this.m_primitive;
+ spec.primitiveCount = 5;
+ spec.drawMethod = this.m_method;
+ spec.indexType = this.m_indexType;
+ spec.indexPointerOffset = 0;
+ spec.indexStorage = this.m_indexStorage;
+ spec.first = 0;
+ spec.indexMin = 0;
+ spec.indexMax = 0;
+ spec.instanceCount = 1;
+
+ spec.attribs.length = 0;
+
+ spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
+ spec.attribs[0].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
+ spec.attribs[0].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
+ spec.attribs[0].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
+ spec.attribs[0].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
+ spec.attribs[0].componentCount = 4;
+ spec.attribs[0].offset = 0;
+ spec.attribs[0].stride = 0;
+ spec.attribs[0].normalize = false;
+ spec.attribs[0].instanceDivisor = 0;
+ spec.attribs[0].useDefaultAttribute = false;
+
+ spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
+ spec.attribs[1].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
+ spec.attribs[1].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
+ spec.attribs[1].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
+ spec.attribs[1].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
+ spec.attribs[1].componentCount = 2;
+ spec.attribs[1].offset = 0;
+ spec.attribs[1].stride = 0;
+ spec.attribs[1].normalize = false;
+ spec.attribs[1].instanceDivisor = 0;
+ spec.attribs[1].useDefaultAttribute = false;
+
+ es3fDrawTests.addTestIterations(test, spec, testType);
+
+ this.addChild(test);
+
+ // Multiple attribute, second one divided
+
+ test = new glsDrawTests.DrawTest(null, 'instanced_attributes', 'Instanced attribute array.');
+
+ //spec.apiType = glu::ApiType::es(3,0);
+ spec.primitive = this.m_primitive;
+ spec.primitiveCount = 5;
+ spec.drawMethod = this.m_method;
+ spec.indexType = this.m_indexType;
+ spec.indexPointerOffset = 0;
+ spec.indexStorage = this.m_indexStorage;
+ spec.first = 0;
+ spec.indexMin = 0;
+ spec.indexMax = 0;
+ spec.instanceCount = 1;
+
+ spec.attribs.length = 0;
+
+ spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
+ spec.attribs[0].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
+ spec.attribs[0].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
+ spec.attribs[0].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
+ spec.attribs[0].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
+ spec.attribs[0].componentCount = 4;
+ spec.attribs[0].offset = 0;
+ spec.attribs[0].stride = 0;
+ spec.attribs[0].normalize = false;
+ spec.attribs[0].instanceDivisor = 0;
+ spec.attribs[0].useDefaultAttribute = false;
+
+ // Add another position component so the instances wont be drawn on each other
+ spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
+ spec.attribs[1].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
+ spec.attribs[1].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
+ spec.attribs[1].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
+ spec.attribs[1].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
+ spec.attribs[1].componentCount = 2;
+ spec.attribs[1].offset = 0;
+ spec.attribs[1].stride = 0;
+ spec.attribs[1].normalize = false;
+ spec.attribs[1].instanceDivisor = 1;
+ spec.attribs[1].useDefaultAttribute = false;
+ spec.attribs[1].additionalPositionAttribute = true;
+
+ // Instanced color
+ spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
+ spec.attribs[2].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
+ spec.attribs[2].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
+ spec.attribs[2].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
+ spec.attribs[2].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
+ spec.attribs[2].componentCount = 3;
+ spec.attribs[2].offset = 0;
+ spec.attribs[2].stride = 0;
+ spec.attribs[2].normalize = false;
+ spec.attribs[2].instanceDivisor = 1;
+ spec.attribs[2].useDefaultAttribute = false;
+
+ es3fDrawTests.addTestIterations(test, spec, testType);
+
+ this.addChild(test);
+
+ // Multiple attribute, second one default
+ test = new glsDrawTests.DrawTest(null, 'default_attribute', 'Attribute specified with glVertexAttrib*.');
+
+ //spec.apiType = glu::ApiType::es(3,0);
+ spec.primitive = this.m_primitive;
+ spec.primitiveCount = 5;
+ spec.drawMethod = this.m_method;
+ spec.indexType = this.m_indexType;
+ spec.indexPointerOffset = 0;
+ spec.indexStorage = this.m_indexStorage;
+ spec.first = 0;
+ spec.indexMin = 0;
+ spec.indexMax = 17; // \note addTestIterations is not called for the spec, so we must ensure [indexMin, indexMax] is a good range
+ spec.instanceCount = 1;
+
+ spec.attribs.length = 0;
+
+ spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
+ spec.attribs[0].inputType = glsDrawTests.DrawTestSpec.InputType.FLOAT;
+ spec.attribs[0].outputType = glsDrawTests.DrawTestSpec.OutputType.VEC2;
+ spec.attribs[0].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
+ spec.attribs[0].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
+ spec.attribs[0].componentCount = 2;
+ spec.attribs[0].offset = 0;
+ spec.attribs[0].stride = 0;
+ spec.attribs[0].normalize = false;
+ spec.attribs[0].instanceDivisor = 0;
+ spec.attribs[0].useDefaultAttribute = false;
+
+ /** @type {Array<{input:?glsDrawTests.DrawTestSpec.InputType, output:?glsDrawTests.DrawTestSpec.OutputType, componentCount:number}>} */ var iopairs = [
+ {input: glsDrawTests.DrawTestSpec.InputType.FLOAT, output: glsDrawTests.DrawTestSpec.OutputType.VEC2, componentCount: 4},
+ {input: glsDrawTests.DrawTestSpec.InputType.FLOAT, output: glsDrawTests.DrawTestSpec.OutputType.VEC4, componentCount: 2},
+ {input: glsDrawTests.DrawTestSpec.InputType.INT, output: glsDrawTests.DrawTestSpec.OutputType.IVEC3, componentCount: 4},
+ {input: glsDrawTests.DrawTestSpec.InputType.UNSIGNED_INT, output: glsDrawTests.DrawTestSpec.OutputType.UVEC2, componentCount: 4}
+ ];
+
+ spec.attribs.push(new glsDrawTests.DrawTestSpec.AttributeSpec());
+ for (var ioNdx = 0; ioNdx < iopairs.length; ++ioNdx) {
+ /** @type {string} */ var desc = glsDrawTests.DrawTestSpec.inputTypeToString(iopairs[ioNdx].input) + iopairs[ioNdx].componentCount + ' to ' + glsDrawTests.DrawTestSpec.outputTypeToString(iopairs[ioNdx].output);
+
+ spec.attribs[1].inputType = iopairs[ioNdx].input;
+ spec.attribs[1].outputType = iopairs[ioNdx].output;
+ spec.attribs[1].storage = glsDrawTests.DrawTestSpec.Storage.BUFFER;
+ spec.attribs[1].usage = glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW;
+ spec.attribs[1].componentCount = iopairs[ioNdx].componentCount;
+ spec.attribs[1].offset = 0;
+ spec.attribs[1].stride = 0;
+ spec.attribs[1].normalize = false;
+ spec.attribs[1].instanceDivisor = 0;
+ spec.attribs[1].useDefaultAttribute = true;
+
+ test.addIteration(spec, desc);
+ }
+
+ this.addChild(test);
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} descr
+ * @param {?glsDrawTests.DrawTestSpec.DrawMethod} drawMethod
+ */
+ es3fDrawTests.IndexGroup = function(name, descr, drawMethod) {
+ tcuTestCase.DeqpTest.call(this, name, descr);
+ /** @type {?glsDrawTests.DrawTestSpec.DrawMethod} */ this.m_method = drawMethod;
+ this.makeExecutable();
+ };
+
+ es3fDrawTests.IndexGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fDrawTests.IndexGroup.prototype.constructor = es3fDrawTests.IndexGroup;
+
+ es3fDrawTests.IndexGroup.prototype.init = function() {
+ /** @type {Array<{storage: ?glsDrawTests.DrawTestSpec.Storage, type: ?glsDrawTests.DrawTestSpec.IndexType, aligned: boolean, offsets: Array<number>}>} */ var tests = [
+ {storage: glsDrawTests.DrawTestSpec.Storage.BUFFER, type: glsDrawTests.DrawTestSpec.IndexType.BYTE, aligned: true, offsets: [0, 1, -1]},
+ {storage: glsDrawTests.DrawTestSpec.Storage.BUFFER, type: glsDrawTests.DrawTestSpec.IndexType.SHORT, aligned: true, offsets: [0, 2, -1]},
+ {storage: glsDrawTests.DrawTestSpec.Storage.BUFFER, type: glsDrawTests.DrawTestSpec.IndexType.INT, aligned: true, offsets: [0, 4, -1]},
+
+ {storage: glsDrawTests.DrawTestSpec.Storage.BUFFER, type: glsDrawTests.DrawTestSpec.IndexType.SHORT, aligned: false, offsets: [1, 3, -1]},
+ {storage: glsDrawTests.DrawTestSpec.Storage.BUFFER, type: glsDrawTests.DrawTestSpec.IndexType.INT, aligned: false, offsets: [2, 3, -1]}
+ ];
+
+ /** @type {glsDrawTests.DrawTestSpec} */ var spec = new glsDrawTests.DrawTestSpec();
+ es3fDrawTests.genBasicSpec(spec, this.m_method);
+
+ /** @type {tcuTestCase.DeqpTest} */ var bufferGroup = new tcuTestCase.DeqpTest('buffer', 'buffer');
+ /** @type {tcuTestCase.DeqpTest} */ var unalignedBufferGroup = new tcuTestCase.DeqpTest('unaligned_buffer', 'unaligned buffer');
+
+ this.addChild(bufferGroup);
+ this.addChild(unalignedBufferGroup);
+
+ for (var testNdx = 0; testNdx < tests.length; ++testNdx) {
+ /** @type {{storage: ?glsDrawTests.DrawTestSpec.Storage, type: ?glsDrawTests.DrawTestSpec.IndexType, aligned: boolean, offsets: Array<number>}} */
+ var indexTest = tests[testNdx];
+ /** @type {tcuTestCase.DeqpTest} */ var group = indexTest.aligned ? bufferGroup : unalignedBufferGroup;
+
+ /** @type {string} */ var name = 'index_' + glsDrawTests.DrawTestSpec.indexTypeToString(indexTest.type);
+ /** @type {string} */ var desc = 'index ' + glsDrawTests.DrawTestSpec.indexTypeToString(indexTest.type) + ' in ' + glsDrawTests.DrawTestSpec.storageToString(indexTest.storage);
+ /** @type {glsDrawTests.DrawTest} */ var test = new glsDrawTests.DrawTest(null, name, desc);
+
+ spec.indexType = indexTest.type;
+ spec.indexStorage = indexTest.storage;
+
+ for (var iterationNdx = 0; iterationNdx < indexTest.offsets.length && indexTest.offsets[iterationNdx] != -1; ++iterationNdx) {
+ /** @type {string} */ var iterationDesc = 'offset ' + indexTest.offsets[iterationNdx];
+ spec.indexPointerOffset = indexTest.offsets[iterationNdx];
+ test.addIteration(spec, iterationDesc);
+ }
+
+ if (spec.isCompatibilityTest() != glsDrawTests.DrawTestSpec.CompatibilityTestType.UNALIGNED_OFFSET &&
+ spec.isCompatibilityTest() != glsDrawTests.DrawTestSpec.CompatibilityTestType.UNALIGNED_STRIDE)
+ group.addChild(test);
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} descr
+ * @param {?glsDrawTests.DrawTestSpec.DrawMethod} drawMethod
+ */
+ es3fDrawTests.FirstGroup = function(name, descr, drawMethod) {
+ tcuTestCase.DeqpTest.call(this, name, descr);
+ /** @type {?glsDrawTests.DrawTestSpec.DrawMethod} */ this.m_method = drawMethod;
+ this.makeExecutable();
+ };
+
+ es3fDrawTests.FirstGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fDrawTests.FirstGroup.prototype.constructor = es3fDrawTests.FirstGroup;
+
+ /**
+ * init
+ */
+ es3fDrawTests.FirstGroup.prototype.init = function() {
+ var firsts =
+ [
+ 1, 3, 17
+ ];
+
+ /** @type {glsDrawTests.DrawTestSpec} */ var spec = new glsDrawTests.DrawTestSpec();
+ es3fDrawTests.genBasicSpec(spec, this.m_method);
+
+ for (var firstNdx = 0; firstNdx < firsts.length; ++firstNdx) {
+ var name = 'first_' + firsts[firstNdx];
+ var desc = 'first ' + firsts[firstNdx];
+ /** @type {glsDrawTests.DrawTest} */ var test = new glsDrawTests.DrawTest(null, name, desc);
+
+ spec.first = firsts[firstNdx];
+
+ es3fDrawTests.addTestIterations(test, spec, es3fDrawTests.TestIterationType.DRAW_COUNT);
+
+ this.addChild(test);
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} descr
+ * @param {?glsDrawTests.DrawTestSpec.DrawMethod} drawMethod
+ */
+ es3fDrawTests.MethodGroup = function(name, descr, drawMethod) {
+ tcuTestCase.DeqpTest.call(this, name, descr);
+ /** @type {?glsDrawTests.DrawTestSpec.DrawMethod} */ this.m_method = drawMethod;
+ this.makeExecutable();
+ };
+
+ es3fDrawTests.MethodGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fDrawTests.MethodGroup.prototype.constructor = es3fDrawTests.MethodGroup;
+
+ /**
+ * init
+ */
+ es3fDrawTests.MethodGroup.prototype.init = function() {
+ var indexed = (this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS) || (this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_INSTANCED) || (this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED);
+ var hasFirst = (this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS) || (this.m_method == glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS_INSTANCED);
+
+ var primitive =
+ [
+ glsDrawTests.DrawTestSpec.Primitive.POINTS,
+ glsDrawTests.DrawTestSpec.Primitive.TRIANGLES,
+ glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_FAN,
+ glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_STRIP,
+ glsDrawTests.DrawTestSpec.Primitive.LINES,
+ glsDrawTests.DrawTestSpec.Primitive.LINE_STRIP,
+ glsDrawTests.DrawTestSpec.Primitive.LINE_LOOP
+ ];
+
+ if (hasFirst) {
+ // First-tests
+ this.addChild(new es3fDrawTests.FirstGroup('first', 'First tests', this.m_method));
+ }
+
+ if (indexed) {
+ // Index-tests
+ if (this.m_method != glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED)
+ this.addChild(new es3fDrawTests.IndexGroup('indices', 'Index tests', this.m_method));
+ }
+
+ for (var ndx = 0; ndx < primitive.length; ++ndx) {
+ var name = glsDrawTests.DrawTestSpec.primitiveToString(primitive[ndx]);
+ var desc = glsDrawTests.DrawTestSpec.primitiveToString(primitive[ndx]);
+
+ this.addChild(new es3fDrawTests.AttributeGroup(name, desc, this.m_method, primitive[ndx], glsDrawTests.DrawTestSpec.IndexType.SHORT, glsDrawTests.DrawTestSpec.Storage.BUFFER));
+ }
+ };
+
+ /**
+ * es3fDrawTests.GridProgram
+ * @constructor
+ * @extends {sglrShaderProgram.ShaderProgram}
+ */
+ es3fDrawTests.GridProgram = function() {
+ /** @type {sglrShaderProgram.ShaderProgramDeclaration} */ var decl = new sglrShaderProgram.ShaderProgramDeclaration();
+
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_offset', rrGenericVector.GenericVecType.FLOAT));
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_color', rrGenericVector.GenericVecType.FLOAT));
+
+ decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
+ decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(rrGenericVector.GenericVecType.FLOAT));
+
+ decl.pushVertexSource(new sglrShaderProgram.VertexSource(
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in highp vec4 a_offset;\n' +
+ 'in highp vec4 a_color;\n' +
+ 'out mediump vec4 v_color;\n' +
+ 'void main(void)\n' +
+ '{\n' +
+ ' gl_Position = a_position + a_offset;\n' +
+ ' v_color = a_color;\n' +
+ '}\n'
+ ));
+ decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 dEQP_FragColor;\n' +
+ 'in mediump vec4 v_color;\n' +
+ 'void main(void)\n' +
+ '{\n' +
+ ' dEQP_FragColor = v_color;\n' +
+ '}\n'
+ ));
+
+ sglrShaderProgram.ShaderProgram.call(this, decl);
+ };
+
+ es3fDrawTests.GridProgram.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
+ es3fDrawTests.GridProgram.prototype.constructor = es3fDrawTests.GridProgram;
+
+ /**
+ * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
+ * @param {Array<rrVertexPacket.VertexPacket>} packets
+ * @param {number} numPackets
+ */
+ es3fDrawTests.GridProgram.prototype.shadeVertices = function(inputs, packets, numPackets) {
+ for (var ndx = 0; ndx < numPackets; ++ndx) {
+ packets[ndx].position = deMath.add(
+ rrVertexAttrib.readVertexAttrib(inputs[0], packets[ndx].instanceNdx, packets[ndx].vertexNdx, rrGenericVector.GenericVecType.FLOAT),
+ rrVertexAttrib.readVertexAttrib(inputs[1], packets[ndx].instanceNdx, packets[ndx].vertexNdx, rrGenericVector.GenericVecType.FLOAT)
+ );
+ packets[ndx].outputs[0] = rrVertexAttrib.readVertexAttrib(inputs[2], packets[ndx].instanceNdx, packets[ndx].vertexNdx, rrGenericVector.GenericVecType.FLOAT);
+ }
+ };
+
+ /**
+ * @param {Array<rrFragmentOperations.Fragment>} packets
+ * @param {rrShadingContext.FragmentShadingContext} context
+ */
+ es3fDrawTests.GridProgram.prototype.shadeFragments = function(packets, context) {
+ for (var packetNdx = 0; packetNdx < packets.length; ++packetNdx)
+ for (var fragNdx = 0; fragNdx < 4; ++fragNdx)
+ packets[packetNdx].value = rrShadingContext.readTriangleVarying(packets[packetNdx], context, fragNdx);
+ };
+
+ /**
+ * InstancedGridRenderTest
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} gridSide
+ * @param {boolean} useIndices
+ */
+ es3fDrawTests.InstancedGridRenderTest = function(name, desc, gridSide, useIndices) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ this.m_gridSide = gridSide;
+ this.m_useIndices = useIndices;
+ };
+
+ es3fDrawTests.InstancedGridRenderTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fDrawTests.InstancedGridRenderTest.prototype.constructor = es3fDrawTests.InstancedGridRenderTest;
+
+ /**
+ * iterate
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fDrawTests.InstancedGridRenderTest.prototype.iterate = function() {
+ var renderTargetWidth = Math.min(1024, gl.canvas.width);
+ var renderTargetHeight = Math.min(1024, gl.canvas.height);
+
+ /** @type {sglrGLContext.GLContext} */ var ctx = new sglrGLContext.GLContext(gl);
+ /** @type {tcuSurface.Surface} */ var surface = new tcuSurface.Surface(renderTargetWidth, renderTargetHeight);
+ /** @type {es3fDrawTests.GridProgram} */ var program = new es3fDrawTests.GridProgram();
+
+ // render
+
+ this.renderTo(ctx, program, surface);
+
+ // verify image
+
+ if (this.verifyImage(surface))
+ testPassed('');
+ else
+ testFailed('Incorrect rendering result');
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @param {sglrGLContext.GLContext} ctx
+ * @param {sglrShaderProgram.ShaderProgram} program
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fDrawTests.InstancedGridRenderTest.prototype.renderTo = function(ctx, program, dst) {
+ var green = [0, 1, 0, 1];
+ var yellow = [1, 1, 0, 1];
+
+ /** @type {WebGLBuffer} */ var positionBuf = null;
+ /** @type {WebGLBuffer} */ var offsetBuf = null;
+ /** @type {WebGLBuffer} */ var colorBuf = null;
+ /** @type {WebGLBuffer} */ var indexBuf = null;
+ /** @type {WebGLProgram} */ var programID = ctx.createProgram(program);
+ /** @type {number} */ var posLocation = ctx.getAttribLocation(/** @type {WebGLProgram} */ (programID), 'a_position');
+ /** @type {number} */ var offsetLocation = ctx.getAttribLocation(/** @type {WebGLProgram} */ (programID), 'a_offset');
+ /** @type {number} */ var colorLocation = ctx.getAttribLocation(/** @type {WebGLProgram} */ (programID), 'a_color');
+
+ var cellW = 2.0 / this.m_gridSide;
+ var cellH = 2.0 / this.m_gridSide;
+ var vertexPositions = new Float32Array([
+ 0, 0, 0, 1,
+ cellW, 0, 0, 1,
+ 0, cellH, 0, 1,
+
+ 0, cellH, 0, 1,
+ cellW, 0, 0, 1,
+ cellW, cellH, 0, 1
+ ]);
+
+ var indices = new Uint16Array([
+ 0, 4, 3,
+ 2, 1, 5
+ ]);
+
+ var offsets = [];
+ for (var x = 0; x < this.m_gridSide; ++x)
+ for (var y = 0; y < this.m_gridSide; ++y) {
+ offsets.push(x * cellW - 1.0);
+ offsets.push(y * cellW - 1.0);
+ offsets.push(0, 0);
+ }
+ offsets = new Float32Array(offsets);
+
+ var colors = [];
+ for (var x = 0; x < this.m_gridSide; ++x)
+ for (var y = 0; y < this.m_gridSide; ++y) {
+ var colorToPush = ((x + y) % 2 == 0) ? (green) : (yellow);
+ colors.push(colorToPush[0]);
+ colors.push(colorToPush[1]);
+ colors.push(colorToPush[2]);
+ colors.push(colorToPush[3]);
+ }
+ colors = new Float32Array(colors);
+
+ positionBuf = ctx.createBuffer();
+ ctx.bindBuffer(gl.ARRAY_BUFFER, positionBuf);
+ ctx.bufferData(gl.ARRAY_BUFFER, vertexPositions, gl.STATIC_DRAW);
+ ctx.vertexAttribPointer(posLocation, 4, gl.FLOAT, false, 0, 0);
+ ctx.vertexAttribDivisor(posLocation, 0);
+ ctx.enableVertexAttribArray(posLocation);
+
+ offsetBuf = ctx.createBuffer();
+ ctx.bindBuffer(gl.ARRAY_BUFFER, offsetBuf);
+ ctx.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);
+ ctx.vertexAttribPointer(offsetLocation, 4, gl.FLOAT, false, 0, 0);
+ ctx.vertexAttribDivisor(offsetLocation, 1);
+ ctx.enableVertexAttribArray(offsetLocation);
+
+ colorBuf = ctx.createBuffer();
+ ctx.bindBuffer(gl.ARRAY_BUFFER, colorBuf);
+ ctx.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
+ ctx.vertexAttribPointer(colorLocation, 4, gl.FLOAT, false, 0, 0);
+ ctx.vertexAttribDivisor(colorLocation, 1);
+ ctx.enableVertexAttribArray(colorLocation);
+
+ if (this.m_useIndices) {
+ indexBuf = ctx.createBuffer();
+ ctx.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuf);
+ ctx.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
+ }
+
+ ctx.clearColor(0, 0, 0, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT);
+
+ ctx.viewport(0, 0, dst.getWidth(), dst.getHeight());
+
+ ctx.useProgram(programID);
+ if (this.m_useIndices)
+ ctx.drawElementsInstanced(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0, this.m_gridSide * this.m_gridSide);
+ else
+ ctx.drawArraysInstanced(gl.TRIANGLES, 0, 6, this.m_gridSide * this.m_gridSide);
+ ctx.useProgram(null);
+
+ if (this.m_useIndices)
+ ctx.deleteBuffer(indexBuf);
+ ctx.deleteBuffer(colorBuf);
+ ctx.deleteBuffer(offsetBuf);
+ ctx.deleteBuffer(positionBuf);
+ ctx.deleteProgram(programID);
+
+ ctx.finish();
+ dst.readViewport(ctx, [0 , 0, dst.getWidth(), dst.getHeight()]);
+ };
+
+ /**
+ * @param {tcuSurface.Surface} image
+ * @return {boolean}
+ */
+ es3fDrawTests.InstancedGridRenderTest.prototype.verifyImage = function(image) {
+ // \note the green/yellow pattern is only for clarity. The test will only verify that all instances were drawn by looking for anything non-green/yellow.
+
+ var green = [0, 255, 0, 255];
+ var yellow = [255, 255, 0, 255];
+ var colorThreshold = 20;
+
+ /** @type {tcuSurface.Surface} */ var error = new tcuSurface.Surface(image.getWidth(), image.getHeight());
+ var isOk = true;
+
+ for (var y = 1; y < image.getHeight() - 1; y++)
+ for (var x = 1; x < image.getWidth() - 1; x++) {
+ /** @type {tcuRGBA.RGBA} */ var pixel = new tcuRGBA.RGBA(image.getPixel(x, y));
+ var pixelOk = true;
+
+ // Any pixel with !(G ~= 255) is faulty (not a linear combinations of green and yellow)
+ if (Math.abs(pixel.getGreen() - 255) > colorThreshold)
+ pixelOk = false;
+
+ // Any pixel with !(B ~= 0) is faulty (not a linear combinations of green and yellow)
+ if (Math.abs(pixel.getBlue() - 0) > colorThreshold)
+ pixelOk = false;
+
+ error.setPixel(x, y, pixelOk ? [0, 255, 0, 255] : [255, 0, 0, 255]);
+ isOk = isOk && pixelOk;
+ }
+
+ if (!isOk) {
+ bufferedLogToConsole('Image verification failed.');
+ debug('Verfication result');
+ tcuLogImage.logImageWithInfo(image.getAccess(), 'Result');
+ tcuLogImage.logImageWithInfo(error.getAccess(), 'Error mask');
+ } else {
+ debug('Verfication result');
+ }
+
+ return isOk;
+ };
+
+ /**
+ * InstancingGroup
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fDrawTests.InstancingGroup = function(name, descr) {
+ tcuTestCase.DeqpTest.call(this, name, descr);
+ this.makeExecutable();
+ };
+
+ es3fDrawTests.InstancingGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fDrawTests.InstancingGroup.prototype.constructor = es3fDrawTests.InstancingGroup;
+
+ /**
+ * init
+ */
+ es3fDrawTests.InstancingGroup.prototype.init = function() {
+ var gridWidths = [
+ 2,
+ 5,
+ 10,
+ 32,
+ 100
+ ];
+
+ // drawArrays
+ for (var ndx = 0; ndx < gridWidths.length; ++ndx) {
+ var name = 'draw_arrays_instanced_grid_' + gridWidths[ndx] + 'x' + gridWidths[ndx];
+ var desc = 'DrawArraysInstanced, Grid size ' + gridWidths[ndx] + 'x' + gridWidths[ndx];
+
+ this.addChild(new es3fDrawTests.InstancedGridRenderTest(name, desc, gridWidths[ndx], false));
+ }
+
+ // drawElements
+ for (var ndx = 0; ndx < gridWidths.length; ++ndx) {
+ var name = 'draw_elements_instanced_grid_' + gridWidths[ndx] + 'x' + gridWidths[ndx];
+ var desc = 'DrawElementsInstanced, Grid size ' + gridWidths[ndx] + 'x' + gridWidths[ndx];
+
+ this.addChild(new es3fDrawTests.InstancedGridRenderTest(name, desc, gridWidths[ndx], true));
+ }
+ };
+
+ /**
+ * @constructor
+ * @param {number} size
+ */
+ es3fDrawTests.UniformWeightArray = function(size) {
+ this.weights = [];
+
+ for (var i = 0; i < size; ++i)
+ this.weights[i] = 1.0;
+ };
+
+ /**
+ * RandomGroup
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} descr
+ */
+ es3fDrawTests.RandomGroup = function(name, descr) {
+ tcuTestCase.DeqpTest.call(this, name, descr);
+ this.makeExecutable();
+ };
+
+ es3fDrawTests.RandomGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fDrawTests.RandomGroup.prototype.constructor = es3fDrawTests.RandomGroup;
+
+ /**
+ * init
+ */
+ es3fDrawTests.RandomGroup.prototype.init = function() {
+ /** @type {number} */ var numAttempts = 300;
+
+ /** @type {Array<number>} */ var attribCounts = [1, 2, 5];
+ /** @type {Array<number>} */ var attribWeights = [30, 10, 1];
+ /** @type {Array<number>} */ var primitiveCounts = [2, 6, 64];
+ /** @type {Array<number>} */ var primitiveCountWeights = [20, 10, 1];
+ /** @type {Array<number>} */ var indexOffsets = [0, 7, 13];
+ /** @type {Array<number>} */ var indexOffsetWeights = [20, 20, 1];
+ /** @type {Array<number>} */ var firsts = [0, 6, 12];
+ /** @type {Array<number>} */ var firstWeights = [20, 20, 1];
+ /** @type {Array<number>} */ var instanceCounts = [1, 2, 16, 17];
+ /** @type {Array<number>} */ var instanceWeights = [20, 10, 5, 1];
+ /** @type {Array<number>} */ var indexMins = [0, 1, 3, 9];
+ /** @type {Array<number>} */ var indexMaxs = [5, 9, 129, 257];
+ /** @type {Array<number>} */ var indexWeights = [50, 50, 50, 50];
+ /** @type {Array<number>} */ var offsets = [0, 1, 5, 12];
+ /** @type {Array<number>} */ var offsetWeights = [50, 10, 10, 10];
+ /** @type {Array<number>} */ var strides = [0, 7, 16, 17];
+ /** @type {Array<number>} */ var strideWeights = [50, 10, 10, 10];
+ /** @type {Array<number>} */ var instanceDivisors = [0, 1, 3, 129];
+ /** @type {Array<number>} */ var instanceDivisorWeights = [70, 30, 10, 10];
+
+ /** @type {Array<glsDrawTests.DrawTestSpec.Primitive>} */ var primitives = [
+ glsDrawTests.DrawTestSpec.Primitive.POINTS,
+ glsDrawTests.DrawTestSpec.Primitive.TRIANGLES,
+ glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_FAN,
+ glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_STRIP,
+ glsDrawTests.DrawTestSpec.Primitive.LINES,
+ glsDrawTests.DrawTestSpec.Primitive.LINE_STRIP,
+ glsDrawTests.DrawTestSpec.Primitive.LINE_LOOP
+ ];
+ /** @type {es3fDrawTests.UniformWeightArray} */ var primitiveWeights = new es3fDrawTests.UniformWeightArray(primitives.length);
+
+ /** @type {Array<glsDrawTests.DrawTestSpec.DrawMethod>} */ var drawMethods = [
+ glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS,
+ glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS_INSTANCED,
+ glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS,
+ glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED,
+ glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_INSTANCED
+ ];
+ /** @type {es3fDrawTests.UniformWeightArray} */ var drawMethodWeights = new es3fDrawTests.UniformWeightArray(drawMethods.length);
+
+ /** @type {Array<glsDrawTests.DrawTestSpec.IndexType>} */ var indexTypes = [
+ glsDrawTests.DrawTestSpec.IndexType.BYTE,
+ glsDrawTests.DrawTestSpec.IndexType.SHORT,
+ glsDrawTests.DrawTestSpec.IndexType.INT
+ ];
+ /** @type {es3fDrawTests.UniformWeightArray} */ var indexTypeWeights = new es3fDrawTests.UniformWeightArray(indexTypes.length);
+
+ /** @type {Array<glsDrawTests.DrawTestSpec.Storage>} */ var storages = [
+ //glsDrawTests.DrawTestSpec.Storage.USER,
+ glsDrawTests.DrawTestSpec.Storage.BUFFER
+ ];
+ /** @type {es3fDrawTests.UniformWeightArray} */ var storageWeights = new es3fDrawTests.UniformWeightArray(storages.length);
+
+ /** @type {Array<glsDrawTests.DrawTestSpec.InputType>} */ var inputTypes = [
+ glsDrawTests.DrawTestSpec.InputType.FLOAT,
+ //glsDrawTests.DrawTestSpec.InputType.FIXED,
+ glsDrawTests.DrawTestSpec.InputType.BYTE,
+ glsDrawTests.DrawTestSpec.InputType.SHORT,
+ glsDrawTests.DrawTestSpec.InputType.UNSIGNED_BYTE,
+ glsDrawTests.DrawTestSpec.InputType.UNSIGNED_SHORT,
+ glsDrawTests.DrawTestSpec.InputType.INT,
+ glsDrawTests.DrawTestSpec.InputType.UNSIGNED_INT,
+ glsDrawTests.DrawTestSpec.InputType.HALF,
+ glsDrawTests.DrawTestSpec.InputType.UNSIGNED_INT_2_10_10_10,
+ glsDrawTests.DrawTestSpec.InputType.INT_2_10_10_10
+ ];
+ /** @type {es3fDrawTests.UniformWeightArray} */ var inputTypeWeights = new es3fDrawTests.UniformWeightArray(inputTypes.length);
+
+ /** @type {Array<glsDrawTests.DrawTestSpec.OutputType>} */ var outputTypes = [
+ glsDrawTests.DrawTestSpec.OutputType.FLOAT,
+ glsDrawTests.DrawTestSpec.OutputType.VEC2,
+ glsDrawTests.DrawTestSpec.OutputType.VEC3,
+ glsDrawTests.DrawTestSpec.OutputType.VEC4,
+ glsDrawTests.DrawTestSpec.OutputType.INT,
+ glsDrawTests.DrawTestSpec.OutputType.UINT,
+ glsDrawTests.DrawTestSpec.OutputType.IVEC2,
+ glsDrawTests.DrawTestSpec.OutputType.IVEC3,
+ glsDrawTests.DrawTestSpec.OutputType.IVEC4,
+ glsDrawTests.DrawTestSpec.OutputType.UVEC2,
+ glsDrawTests.DrawTestSpec.OutputType.UVEC3,
+ glsDrawTests.DrawTestSpec.OutputType.UVEC4
+ ];
+ /** @type {es3fDrawTests.UniformWeightArray} */ var outputTypeWeights = new es3fDrawTests.UniformWeightArray(outputTypes.length);
+
+ /** @type {Array<glsDrawTests.DrawTestSpec.Usage>} */ var usages = [
+ glsDrawTests.DrawTestSpec.Usage.DYNAMIC_DRAW,
+ glsDrawTests.DrawTestSpec.Usage.STATIC_DRAW,
+ glsDrawTests.DrawTestSpec.Usage.STREAM_DRAW,
+ glsDrawTests.DrawTestSpec.Usage.STREAM_READ,
+ glsDrawTests.DrawTestSpec.Usage.STREAM_COPY,
+ glsDrawTests.DrawTestSpec.Usage.STATIC_READ,
+ glsDrawTests.DrawTestSpec.Usage.STATIC_COPY,
+ glsDrawTests.DrawTestSpec.Usage.DYNAMIC_READ,
+ glsDrawTests.DrawTestSpec.Usage.DYNAMIC_COPY
+ ];
+ /** @type {es3fDrawTests.UniformWeightArray} */ var usageWeights = new es3fDrawTests.UniformWeightArray(usages.length);
+
+ /** @type {Array<number>} */ var insertedHashes = []; //'set' structure
+ /** @type {number} */ var insertedCount = 0;
+
+ for (var ndx = 0; ndx < numAttempts; ++ndx) {
+ /** @type {deRandom.Random} */ var random = new deRandom.Random(0xc551393 + ndx); // random does not depend on previous cases
+
+ /** @type {number} */ var attributeCount = random.chooseWeighted(attribCounts, attribWeights);
+ /** @type {glsDrawTests.DrawTestSpec} */ var spec = new glsDrawTests.DrawTestSpec();
+
+ //spec.apiType = glu::ApiType::es(3,0);
+ spec.primitive = /** @type {glsDrawTests.DrawTestSpec.Primitive} */ (random.chooseWeighted(primitives, primitiveWeights.weights));
+ spec.primitiveCount = random.chooseWeighted(primitiveCounts, primitiveCountWeights);
+ spec.drawMethod = /** @type {glsDrawTests.DrawTestSpec.DrawMethod} */ (random.chooseWeighted(drawMethods, drawMethodWeights.weights));
+ spec.indexType = /** @type {glsDrawTests.DrawTestSpec.IndexType} */ (random.chooseWeighted(indexTypes, indexTypeWeights.weights));
+ spec.indexPointerOffset = random.chooseWeighted(indexOffsets, indexOffsetWeights);
+ spec.indexStorage = /** @type {glsDrawTests.DrawTestSpec.Storage} */ (random.chooseWeighted(storages, storageWeights.weights));
+ spec.first = random.chooseWeighted(firsts, firstWeights);
+ spec.indexMin = random.chooseWeighted(indexMins, indexWeights);
+ spec.indexMax = random.chooseWeighted(indexMaxs, indexWeights);
+ spec.instanceCount = random.chooseWeighted(instanceCounts, instanceWeights);
+
+ // check spec is legal
+ if (!spec.valid())
+ continue;
+
+ var hasZeroDivisor = false;
+ for (var attrNdx = 0; attrNdx < attributeCount;) {
+ /** @type {boolean} */ var valid;
+ /** @type {glsDrawTests.DrawTestSpec.AttributeSpec} */ var attribSpec = new glsDrawTests.DrawTestSpec.AttributeSpec();
+
+ attribSpec.inputType = /** @type {glsDrawTests.DrawTestSpec.InputType} */ (random.chooseWeighted(inputTypes, inputTypeWeights.weights));
+ attribSpec.outputType = /** @type {glsDrawTests.DrawTestSpec.OutputType} */ (random.chooseWeighted(outputTypes, outputTypeWeights.weights));
+ attribSpec.storage = /** @type {glsDrawTests.DrawTestSpec.Storage} */ (random.chooseWeighted(storages, storageWeights.weights));
+ attribSpec.usage = /** @type {glsDrawTests.DrawTestSpec.Usage} */ (random.chooseWeighted(usages, usageWeights.weights));
+ attribSpec.componentCount = random.getInt(1, 4);
+ attribSpec.offset = random.chooseWeighted(offsets, offsetWeights);
+ attribSpec.stride = random.chooseWeighted(strides, strideWeights);
+ attribSpec.normalize = random.getBool();
+ attribSpec.instanceDivisor = random.chooseWeighted(instanceDivisors, instanceDivisorWeights);
+ attribSpec.useDefaultAttribute = random.getBool();
+
+ // check spec is legal
+ valid = attribSpec.valid(/*spec.apiType*/);
+
+ // we do not want interleaved elements. (Might result in some weird floating point values)
+ if (attribSpec.stride && attribSpec.componentCount * glsDrawTests.DrawTestSpec.inputTypeSize(attribSpec.inputType) > attribSpec.stride)
+ valid = false;
+
+ // try again if not valid
+ if (valid) {
+ spec.attribs.push(attribSpec);
+ ++attrNdx;
+ if (attribSpec.instanceDivisor == 0)
+ hasZeroDivisor = true;
+ }
+ }
+
+ // Do not collapse all vertex positions to a single positions
+ if (spec.primitive != glsDrawTests.DrawTestSpec.Primitive.POINTS) {
+ spec.attribs[0].instanceDivisor = 0;
+ hasZeroDivisor = true;
+ }
+
+ // There should be at least one enabled vertex attribute array that has a divisor of zero in WebGL.
+ // This limitation is added to keep compatible with D3D. It differs from the feature in gles.
+ // See the section <Enabled Attribute> in WebGL spec: https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.6
+ if (hasZeroDivisor == false)
+ continue;
+
+ // Is render result meaningful?
+ // Only one vertex
+ if (spec.drawMethod == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED && spec.indexMin == spec.indexMax && spec.primitive != glsDrawTests.DrawTestSpec.Primitive.POINTS)
+ continue;
+ if (spec.attribs[0].useDefaultAttribute && spec.primitive != glsDrawTests.DrawTestSpec.Primitive.POINTS)
+ continue;
+
+ // Triangle only on one axis
+ if (spec.primitive == glsDrawTests.DrawTestSpec.Primitive.TRIANGLES || spec.primitive == glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_FAN || spec.primitive == glsDrawTests.DrawTestSpec.Primitive.TRIANGLE_STRIP) {
+ if (spec.attribs[0].componentCount == 1)
+ continue;
+ if (spec.attribs[0].outputType == glsDrawTests.DrawTestSpec.OutputType.FLOAT || spec.attribs[0].outputType == glsDrawTests.DrawTestSpec.OutputType.INT || spec.attribs[0].outputType == glsDrawTests.DrawTestSpec.OutputType.UINT)
+ continue;
+ if (spec.drawMethod == glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED && (spec.indexMax - spec.indexMin) < 2)
+ continue;
+ }
+
+ // Add case
+ /** @type {number} */ var hash = spec.hash();
+ for (var attrNdx = 0; attrNdx < attributeCount; ++attrNdx)
+ hash = deMath.binaryOp(deMath.shiftLeft(hash, 2), spec.attribs[attrNdx].hash(), deMath.BinaryOp.XOR);
+
+ if (insertedHashes.indexOf(hash) == -1) {
+ // Only properly aligned
+ if (spec.isCompatibilityTest() != glsDrawTests.DrawTestSpec.CompatibilityTestType.UNALIGNED_OFFSET &&
+ spec.isCompatibilityTest() != glsDrawTests.DrawTestSpec.CompatibilityTestType.UNALIGNED_STRIDE) {
+ this.addChild(new glsDrawTests.DrawTest(spec, insertedCount + '', spec.getDesc()));
+ }
+ deUtil.dePushUniqueToArray(insertedHashes, hash);
+
+ ++insertedCount;
+ }
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fDrawTests.DrawTest = function() {
+ tcuTestCase.DeqpTest.call(this, 'draw', 'Drawing tests');
+ this.makeExecutable();
+ };
+
+ es3fDrawTests.DrawTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fDrawTests.DrawTest.prototype.constructor = es3fDrawTests.DrawTest;
+
+ /**
+ * init
+ */
+ es3fDrawTests.DrawTest.prototype.init = function() {
+ // Basic
+ /** @type {Array<glsDrawTests.DrawTestSpec.DrawMethod>} */ var basicMethods = [
+ glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS,
+ glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS,
+ glsDrawTests.DrawTestSpec.DrawMethod.DRAWARRAYS_INSTANCED,
+ glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_INSTANCED,
+ glsDrawTests.DrawTestSpec.DrawMethod.DRAWELEMENTS_RANGED
+ ];
+
+ for (var ndx = 0; ndx < basicMethods.length; ++ndx) {
+ var name = glsDrawTests.DrawTestSpec.drawMethodToString(basicMethods[ndx]);
+ var desc = glsDrawTests.DrawTestSpec.drawMethodToString(basicMethods[ndx]);
+
+ this.addChild(new es3fDrawTests.MethodGroup(name, desc, basicMethods[ndx]));
+ }
+
+ // extreme instancing
+
+ this.addChild(new es3fDrawTests.InstancingGroup('instancing', 'draw tests with a large instance count.'));
+
+ // Random
+
+ this.addChild(new es3fDrawTests.RandomGroup('random', 'random draw commands.'));
+ };
+
+ /**
+ * Create and execute the test cases
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fDrawTests.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+
+ var rootTest = new es3fDrawTests.DrawTest();
+ state.setRoot(rootTest);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(rootTest.fullName());
+ description(rootTest.getDescription());
+
+ try {
+ if (range) {
+ state.setRange(range);
+ }
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to run draw tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboColorbufferTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboColorbufferTests.js
new file mode 100644
index 0000000000..deb692a7b6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboColorbufferTests.js
@@ -0,0 +1,1049 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fFboColorbufferTests');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('functional.gles3.es3fFboTestCase');
+goog.require('functional.gles3.es3fFboTestUtil');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.referencerenderer.rrUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.opengl.gluShaderUtil');
+
+goog.scope(function() {
+var es3fFboColorbufferTests = functional.gles3.es3fFboColorbufferTests;
+var es3fFboTestCase = functional.gles3.es3fFboTestCase;
+var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
+var tcuTestCase = framework.common.tcuTestCase;
+var tcuSurface = framework.common.tcuSurface;
+var tcuTexture = framework.common.tcuTexture;
+var gluTextureUtil = framework.opengl.gluTextureUtil;
+var tcuRGBA = framework.common.tcuRGBA;
+var deRandom = framework.delibs.debase.deRandom;
+var tcuImageCompare = framework.common.tcuImageCompare;
+var tcuTextureUtil = framework.common.tcuTextureUtil;
+var rrUtil = framework.referencerenderer.rrUtil;
+var deMath = framework.delibs.debase.deMath;
+var gluShaderUtil = framework.opengl.gluShaderUtil;
+
+/** @type {WebGL2RenderingContext} */ var gl;
+
+/** @const*/ var MIN_THRESHOLD = new tcuRGBA.RGBA([12, 12, 12, 12]);
+
+let canvasWH = 256;
+let texPotSize = [128, 128, 5];
+let texNpotSizeA = [129, 117];
+let texNpotSizeB = [99, 128];
+if (tcuTestCase.isQuickMode()) {
+ canvasWH = 32;
+ texPotSize = [16, 16, 5];
+ texNpotSizeA = [12, 11];
+ texNpotSizeB = [9, 16];
+}
+const texW = texPotSize[0];
+const texH = texPotSize[1];
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+/**
+ * @param {deRandom.Random} rnd
+ * @param {Array<number>} minVal
+ * @param {Array<number>} maxVal
+ * @return {Array<number>}
+ */
+es3fFboColorbufferTests.randomVector = function(rnd, minVal, maxVal) {
+ var res = [];
+ for (var ndx = 0; ndx < minVal.length; ndx++)
+ res[ndx] = rnd.getFloat(minVal[ndx], maxVal[ndx]);
+ return res;
+};
+
+/**
+ * @param {deRandom.Random} rnd
+ * @return {Array<number>}
+ */
+es3fFboColorbufferTests.generateRandomColor = function(rnd) {
+ var retVal = [];
+
+ for (var i = 0; i < 3; ++i)
+ retVal[i] = rnd.getFloat();
+ retVal[3] = 1;
+
+ return retVal;
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ */
+es3fFboColorbufferTests.FboColorbufferCase = function(name, desc, format) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_format = format;
+};
+
+setParentClass(es3fFboColorbufferTests.FboColorbufferCase, es3fFboTestCase.FboTestCase);
+
+/**
+ * @param {tcuSurface.Surface} reference
+ * @param {tcuSurface.Surface} result
+ * @return {boolean}
+ */
+es3fFboColorbufferTests.FboColorbufferCase.prototype.compare = function(reference, result) {
+ /** @type {tcuRGBA.RGBA} */ var threshold = tcuRGBA.max(es3fFboTestUtil.getFormatThreshold(this.m_format), MIN_THRESHOLD);
+
+ bufferedLogToConsole('Comparing images, threshold: ' + threshold);
+
+ return tcuImageCompare.bilinearCompare('Result', 'Image comparison result', reference.getAccess(), result.getAccess(), threshold);
+ };
+
+/**
+ * Deinit. Clear some GL state variables
+ */
+es3fFboColorbufferTests.FboColorbufferCase.prototype.deinit = function() {
+ // Texture state
+ {
+ // Only TEXTURE0 and TEXTURE1 are used in this test
+ var numTexUnits = 2;
+
+ for (var ndx = 0; ndx < numTexUnits; ndx++) {
+ gl.activeTexture(gl.TEXTURE0 + ndx);
+
+ // Reset 2D texture
+ gl.bindTexture(gl.TEXTURE_2D, null);
+
+ // Reset cube map texture
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
+
+ // Reset 2D array texture
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
+
+ // Reset 3D texture
+ gl.bindTexture(gl.TEXTURE_3D, null);
+ }
+
+ gl.activeTexture(gl.TEXTURE0);
+ }
+
+ // Pixel operations
+ {
+ gl.disable(gl.SCISSOR_TEST);
+ gl.disable(gl.BLEND);
+ }
+
+ // Framebuffer control
+ {
+ gl.clearColor(0.0, 0.0, 0.0, 0.0);
+ }
+ };
+
+/**
+ * @constructor
+ * @extends {es3fFboColorbufferTests.FboColorbufferCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} width
+ * @param {number} height
+ */
+es3fFboColorbufferTests.FboColorClearCase = function(name, desc, format, width, height) {
+ es3fFboColorbufferTests.FboColorbufferCase.call(this, name, desc, format);
+ this.m_width = width;
+ this.m_height = height;
+};
+
+setParentClass(es3fFboColorbufferTests.FboColorClearCase, es3fFboColorbufferTests.FboColorbufferCase);
+
+es3fFboColorbufferTests.FboColorClearCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_format);
+ return true; // No exception thrown
+ };
+
+es3fFboColorbufferTests.FboColorClearCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var fboFormat = gluTextureUtil.mapGLInternalFormat(this.m_format);
+ var fmtClass = tcuTexture.getTextureChannelClass(fboFormat.type);
+ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(fboFormat);
+ var rnd = new deRandom.Random(17);
+ var numClears = 16;
+
+ var fbo = ctx.createFramebuffer();
+ var rbo = ctx.createRenderbuffer();
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_format, this.m_width, this.m_height);
+ this.checkError();
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.viewport(0, 0, this.m_width, this.m_height);
+
+ // Initialize to transparent black.
+ switch (fmtClass) {
+ case tcuTexture.TextureChannelClass.FLOATING_POINT:
+ case tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT:
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
+ ctx.clearBufferfv(gl.COLOR, 0, new Float32Array(4));
+ break;
+
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
+ ctx.clearBufferuiv(gl.COLOR, 0, new Uint32Array(4));
+ break;
+
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ ctx.clearBufferiv(gl.COLOR, 0, new Int32Array(4));
+ break;
+
+ default:
+ throw new Error('Invalid channelclass ' + fmtClass);
+ }
+
+ // Do random scissored clears.
+ ctx.enable(gl.SCISSOR_TEST);
+ for (var ndx = 0; ndx < numClears; ndx++) {
+ var x = rnd.getInt(0, this.m_width - 1);
+ var y = rnd.getInt(0, this.m_height - 1);
+ var w = rnd.getInt(1, this.m_width - x);
+ var h = rnd.getInt(1, this.m_height - y);
+ var color = es3fFboColorbufferTests.randomVector(rnd, fmtInfo.valueMin, fmtInfo.valueMax);
+
+ ctx.scissor(x, y, w, h);
+
+ switch (fmtClass) {
+ case tcuTexture.TextureChannelClass.FLOATING_POINT:
+ case tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT:
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
+ ctx.clearBufferfv(gl.COLOR, 0, color);
+ break;
+
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
+ ctx.clearBufferuiv(gl.COLOR, 0, color);
+ break;
+
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ ctx.clearBufferiv(gl.COLOR, 0, color);
+ break;
+
+ default:
+ throw new Error('Invalid channelclass ' + fmtClass);
+ }
+ }
+
+ // Read results from renderbuffer.
+ this.readPixelsUsingFormat(dst, 0, 0, this.m_width, this.m_height, fboFormat, fmtInfo.lookupScale, fmtInfo.lookupBias);
+ this.checkError();
+ };
+
+/**
+ * @constructor
+ * @extends {es3fFboColorbufferTests.FboColorbufferCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} tex0Fmt
+ * @param {Array<number>} tex0Size
+ * @param {number} tex1Fmt
+ * @param {Array<number>} tex1Size
+ */
+es3fFboColorbufferTests.FboColorMultiTex2DCase = function(name, desc, tex0Fmt, tex0Size, tex1Fmt, tex1Size) {
+ es3fFboColorbufferTests.FboColorbufferCase.call(this, name, desc, tex0Fmt);
+ this.m_tex0Fmt = tex0Fmt;
+ this.m_tex0Size = tex0Size;
+ this.m_tex1Fmt = tex1Fmt;
+ this.m_tex1Size = tex1Size;
+};
+
+setParentClass(es3fFboColorbufferTests.FboColorMultiTex2DCase, es3fFboColorbufferTests.FboColorbufferCase);
+
+es3fFboColorbufferTests.FboColorMultiTex2DCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_tex0Fmt);
+ this.checkFormatSupport(this.m_tex1Fmt);
+ return true; // No exception thrown
+ };
+
+es3fFboColorbufferTests.FboColorMultiTex2DCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var texFmt0 = gluTextureUtil.mapGLInternalFormat(this.m_tex0Fmt);
+ var texFmt1 = gluTextureUtil.mapGLInternalFormat(this.m_tex1Fmt);
+ var fmtInfo0 = tcuTextureUtil.getTextureFormatInfo(texFmt0);
+ var fmtInfo1 = tcuTextureUtil.getTextureFormatInfo(texFmt1);
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texToFbo0Shader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D], es3fFboTestUtil.getFragmentOutputType(texFmt0),
+ deMath.subtract(fmtInfo0.valueMax, fmtInfo0.valueMin),
+ fmtInfo0.valueMin);
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texToFbo1Shader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D], es3fFboTestUtil.getFragmentOutputType(texFmt1),
+ deMath.subtract(fmtInfo1.valueMax, fmtInfo1.valueMin),
+ fmtInfo1.valueMin);
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var multiTexShader = new es3fFboTestUtil.Texture2DShader(
+ [gluTextureUtil.getSampler2DType(texFmt0), gluTextureUtil.getSampler2DType(texFmt1)],
+ gluShaderUtil.DataType.FLOAT_VEC4);
+
+ var texToFbo0ShaderID = ctx.createProgram(texToFbo0Shader);
+ var texToFbo1ShaderID = ctx.createProgram(texToFbo1Shader);
+ var multiTexShaderID = ctx.createProgram(multiTexShader);
+
+ // Setup shaders
+ multiTexShader.setTexScaleBias(0, deMath.scale(fmtInfo0.lookupScale, 0.5), deMath.scale(fmtInfo0.lookupBias, 0.5));
+ multiTexShader.setTexScaleBias(1, deMath.scale(fmtInfo1.lookupScale, 0.5), deMath.scale(fmtInfo1.lookupBias, 0.5));
+ texToFbo0Shader.setUniforms(ctx, texToFbo0ShaderID);
+ texToFbo1Shader.setUniforms(ctx, texToFbo1ShaderID);
+ multiTexShader.setUniforms(ctx, multiTexShaderID);
+
+ var fbo0 = ctx.createFramebuffer();
+ var fbo1 = ctx.createFramebuffer();
+ var tex0 = ctx.createTexture();
+ var tex1 = ctx.createTexture();
+
+ for (var ndx = 0; ndx < 2; ndx++) {
+ var transferFmt = gluTextureUtil.getTransferFormat(ndx ? texFmt1 : texFmt0);
+ var format = ndx ? this.m_tex1Fmt : this.m_tex0Fmt;
+ var isFilterable = gluTextureUtil.isGLInternalColorFormatFilterable(format);
+ var size = ndx ? this.m_tex1Size : this.m_tex0Size;
+ var fbo = ndx ? fbo1 : fbo0;
+ var tex = ndx ? tex1 : tex0;
+
+ ctx.bindTexture(gl.TEXTURE_2D, tex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, isFilterable ? gl.LINEAR : gl.NEAREST);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, isFilterable ? gl.LINEAR : gl.NEAREST);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, format, size[0], size[1], 0, transferFmt.format, transferFmt.dataType, null);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+ }
+
+ // Render textures to both framebuffers.
+ for (var ndx = 0; ndx < 2; ndx++) {
+ var format = gl.RGBA;
+ var dataType = gl.UNSIGNED_BYTE;
+ var tmpTex;
+ var fbo = ndx ? fbo1 : fbo0;
+ var viewport = ndx ? this.m_tex1Size : this.m_tex0Size;
+ var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), texW, texH, 1);
+
+ if (ndx == 0)
+ tcuTextureUtil.fillWithComponentGradients(data.getAccess(), [0, 0, 0, 0], [1, 1, 1, 1]);
+ else
+ tcuTextureUtil.fillWithGrid(data.getAccess(), 8, [0.2, 0.7, 0.1, 1.0], [0.7, 0.1, 0.5, 0.8]);
+
+ tmpTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, tmpTex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.viewport(0, 0, viewport[0], viewport[1]);
+ rrUtil.drawQuad(ctx, ndx ? texToFbo1ShaderID : texToFbo0ShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]);
+ }
+
+ // Render to framebuffer.
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
+ ctx.viewport(0, 0, ctx.getWidth(), ctx.getHeight());
+ ctx.activeTexture(gl.TEXTURE0);
+ ctx.bindTexture(gl.TEXTURE_2D, tex0);
+ ctx.activeTexture(gl.TEXTURE1);
+ ctx.bindTexture(gl.TEXTURE_2D, tex1);
+ rrUtil.drawQuad(ctx, multiTexShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]);
+
+ this.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight());
+ };
+
+/**
+ * @constructor
+ * @extends {es3fFboColorbufferTests.FboColorbufferCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} texFmt
+ * @param {Array<number>} texSize
+ */
+es3fFboColorbufferTests.FboColorTexCubeCase = function(name, desc, texFmt, texSize) {
+ es3fFboColorbufferTests.FboColorbufferCase.call(this, name, desc, texFmt);
+ this.m_texSize = texSize;
+};
+
+setParentClass(es3fFboColorbufferTests.FboColorTexCubeCase, es3fFboColorbufferTests.FboColorbufferCase);
+
+es3fFboColorbufferTests.FboColorTexCubeCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_format);
+ return true; // No exception thrown
+ };
+
+es3fFboColorbufferTests.FboColorTexCubeCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var texFmt = gluTextureUtil.mapGLInternalFormat(this.m_format);
+ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
+
+ var cubeGLFaces = [
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
+ ];
+
+ var cubeTexFaces = [
+ tcuTexture.CubeFace.CUBEFACE_POSITIVE_X,
+ tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y,
+ tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z,
+ tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X,
+ tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y,
+ tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z
+ ];
+
+ var rnd = new deRandom.Random(21);
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texToFboShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D], es3fFboTestUtil.getFragmentOutputType(texFmt),
+ deMath.subtract(fmtInfo.valueMax, fmtInfo.valueMin),
+ fmtInfo.valueMin);
+
+ /** @type {es3fFboTestUtil.TextureCubeShader} */
+ var cubeTexShader = new es3fFboTestUtil.TextureCubeShader(
+ gluTextureUtil.getSamplerCubeType(texFmt),
+ gluShaderUtil.DataType.FLOAT_VEC4);
+
+ var texToFboShaderID = ctx.createProgram(texToFboShader);
+ var cubeTexShaderID = ctx.createProgram(cubeTexShader);
+
+ // Setup shaders
+ texToFboShader.setUniforms(ctx, texToFboShaderID);
+ cubeTexShader.setTexScaleBias(fmtInfo.lookupScale, fmtInfo.lookupBias);
+
+ // Framebuffers.
+ var fbos = [];
+ var tex;
+
+ var transferFmt = gluTextureUtil.getTransferFormat(texFmt);
+ var isFilterable = gluTextureUtil.isGLInternalColorFormatFilterable(this.m_format);
+ var size = this.m_texSize;
+
+ tex = ctx.createTexture();
+
+ ctx.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ ctx.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, isFilterable ? gl.LINEAR : gl.NEAREST);
+ ctx.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, isFilterable ? gl.LINEAR : gl.NEAREST);
+
+ // Generate an image and FBO for each cube face
+ for (var ndx = 0; ndx < cubeGLFaces.length; ndx++)
+ ctx.texImage2D(cubeGLFaces[ndx], 0, this.m_format, size[0], size[1], 0, transferFmt.format, transferFmt.dataType, null);
+ this.checkError();
+
+ for (var ndx = 0; ndx < cubeGLFaces.length; ndx++) {
+ var layerFbo = ctx.createFramebuffer();
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, layerFbo);
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, cubeGLFaces[ndx], tex, 0);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ fbos.push(layerFbo);
+ }
+
+ // Render test images to random cube faces
+ var order = [];
+
+ for (var n = 0; n < fbos.length; n++)
+ order.push(n);
+ rnd.shuffle(order);
+
+ for (var ndx = 0; ndx < 4; ndx++) {
+ var face = order[ndx];
+ var format = gl.RGBA;
+ var dataType = gl.UNSIGNED_BYTE;
+ var tmpTex;
+ var fbo = fbos[face];
+ var viewport = this.m_texSize;
+ var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), texW, texH, 1);
+
+ tcuTextureUtil.fillWithGrid(data.getAccess(), 8, es3fFboColorbufferTests.generateRandomColor(rnd), [0, 0, 0, 0]);
+
+ tmpTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, tmpTex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.viewport(0, 0, viewport[0], viewport[1]);
+ rrUtil.drawQuad(ctx, texToFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]);
+ this.checkError();
+
+ // Render to framebuffer
+ var p0 = [(ndx % 2) - 1.0, Math.floor(ndx / 2) - 1.0, 0.0];
+ var p1 = deMath.add(p0, [1.0, 1.0, 0.0]);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
+ ctx.viewport(0, 0, ctx.getWidth(), ctx.getHeight());
+
+ ctx.activeTexture(gl.TEXTURE0);
+ ctx.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+
+ cubeTexShader.setFace(cubeTexFaces[face]);
+ cubeTexShader.setUniforms(ctx, cubeTexShaderID);
+
+ rrUtil.drawQuad(ctx, cubeTexShaderID, p0, p1);
+ this.checkError();
+ }
+
+ this.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight());
+ };
+
+/**
+ * @constructor
+ * @extends {es3fFboColorbufferTests.FboColorbufferCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} texFmt
+ * @param {Array<number>} texSize
+ */
+es3fFboColorbufferTests.FboColorTex2DArrayCase = function(name, desc, texFmt, texSize) {
+ es3fFboColorbufferTests.FboColorbufferCase.call(this, name, desc, texFmt);
+ this.m_texSize = texSize;
+};
+
+setParentClass(es3fFboColorbufferTests.FboColorTex2DArrayCase, es3fFboColorbufferTests.FboColorbufferCase);
+
+es3fFboColorbufferTests.FboColorTex2DArrayCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_format);
+ return true; // No exception thrown
+ };
+
+ es3fFboColorbufferTests.FboColorTex2DArrayCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var texFmt = gluTextureUtil.mapGLInternalFormat(this.m_format);
+ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
+ var rnd = new deRandom.Random(100);
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texToFboShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D], es3fFboTestUtil.getFragmentOutputType(texFmt),
+ deMath.subtract(fmtInfo.valueMax, fmtInfo.valueMin),
+ fmtInfo.valueMin);
+
+ /** @type {es3fFboTestUtil.Texture2DArrayShader} */
+ var arrayTexShader = new es3fFboTestUtil.Texture2DArrayShader(
+ gluTextureUtil.getSampler2DArrayType(texFmt),
+ gluShaderUtil.DataType.FLOAT_VEC4);
+
+ var texToFboShaderID = ctx.createProgram(texToFboShader);
+ var arrayTexShaderID = ctx.createProgram(arrayTexShader);
+
+ // Setup textures
+ texToFboShader.setUniforms(ctx, texToFboShaderID);
+ arrayTexShader.setTexScaleBias(fmtInfo.lookupScale, fmtInfo.lookupBias);
+
+ // Framebuffers.
+ var fbos = [];
+ var tex;
+
+ var transferFmt = gluTextureUtil.getTransferFormat(texFmt);
+ var isFilterable = gluTextureUtil.isGLInternalColorFormatFilterable(this.m_format);
+ var size = this.m_texSize;
+
+ tex = ctx.createTexture();
+
+ ctx.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
+ ctx.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, isFilterable ? gl.LINEAR : gl.NEAREST);
+ ctx.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, isFilterable ? gl.LINEAR : gl.NEAREST);
+ ctx.texImage3D(gl.TEXTURE_2D_ARRAY, 0, this.m_format, size[0], size[1], size[2], 0, transferFmt.format, transferFmt.dataType, null);
+
+ // Generate an FBO for each layer
+ for (var ndx = 0; ndx < this.m_texSize[2]; ndx++) {
+ var layerFbo = ctx.createFramebuffer();
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, layerFbo);
+ ctx.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex, 0, ndx);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ fbos.push(layerFbo);
+ }
+
+ // Render test images to random texture layers
+ var order = [];
+
+ for (var n = 0; n < fbos.length; n++)
+ order.push(n);
+ rnd.shuffle(order);
+
+ for (var ndx = 0; ndx < 4; ndx++) {
+ var layer = order[ndx];
+ var format = gl.RGBA;
+ var dataType = gl.UNSIGNED_BYTE;
+ var fbo = fbos[layer];
+ var viewport = this.m_texSize;
+ var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), texW, texH, 1);
+
+ tcuTextureUtil.fillWithGrid(data.getAccess(), 8, es3fFboColorbufferTests.generateRandomColor(rnd), [0, 0, 0, 0]);
+
+ var tmpTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, tmpTex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.viewport(0, 0, viewport[0], viewport[1]);
+ rrUtil.drawQuad(ctx, texToFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]);
+ this.checkError();
+
+ // Render to framebuffer
+ var p0 = [(ndx % 2) - 1.0, Math.floor(ndx / 2) - 1.0, 0.0];
+ var p1 = deMath.add(p0, [1.0, 1.0, 0.0]);
+ debug('Layer:' + layer + ' rectangle: ' + p0 + ' ' + p1);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
+ ctx.viewport(0, 0, ctx.getWidth(), ctx.getHeight());
+
+ ctx.activeTexture(gl.TEXTURE0);
+ ctx.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
+
+ arrayTexShader.setLayer(layer);
+ arrayTexShader.setUniforms(ctx, arrayTexShaderID);
+
+ rrUtil.drawQuad(ctx, arrayTexShaderID, p0, p1);
+ this.checkError();
+ }
+
+ this.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight());
+ };
+
+/**
+ * @constructor
+ * @extends {es3fFboColorbufferTests.FboColorbufferCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} texFmt
+ * @param {Array<number>} texSize
+ */
+es3fFboColorbufferTests.FboColorTex3DCase = function(name, desc, texFmt, texSize) {
+ es3fFboColorbufferTests.FboColorbufferCase.call(this, name, desc, texFmt);
+ this.m_texSize = texSize;
+};
+
+setParentClass(es3fFboColorbufferTests.FboColorTex3DCase, es3fFboColorbufferTests.FboColorbufferCase);
+
+es3fFboColorbufferTests.FboColorTex3DCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_format);
+ return true; // No exception thrown
+ };
+
+ es3fFboColorbufferTests.FboColorTex3DCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var texFmt = gluTextureUtil.mapGLInternalFormat(this.m_format);
+ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
+ var rnd = new deRandom.Random(100);
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texToFboShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D], es3fFboTestUtil.getFragmentOutputType(texFmt),
+ deMath.subtract(fmtInfo.valueMax, fmtInfo.valueMin),
+ fmtInfo.valueMin);
+
+ /** @type {es3fFboTestUtil.Texture3DShader} */
+ var tdTexShader = new es3fFboTestUtil.Texture3DShader(
+ gluTextureUtil.getSampler3D(texFmt),
+ gluShaderUtil.DataType.FLOAT_VEC4);
+
+ var texToFboShaderID = ctx.createProgram(texToFboShader);
+ var tdTexShaderID = ctx.createProgram(tdTexShader);
+
+ // Setup textures
+ texToFboShader.setUniforms(ctx, texToFboShaderID);
+ tdTexShader.setTexScaleBias(fmtInfo.lookupScale, fmtInfo.lookupBias);
+
+ // Framebuffers.
+ var fbos = [];
+ var tex;{
+ var transferFmt = gluTextureUtil.getTransferFormat(texFmt);
+ var size = this.m_texSize;
+
+ tex = ctx.createTexture();
+
+ ctx.bindTexture(gl.TEXTURE_3D, tex);
+ ctx.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ ctx.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ ctx.texImage3D(gl.TEXTURE_3D, 0, this.m_format, size[0], size[1], size[2], 0, transferFmt.format, transferFmt.dataType, null);
+
+ // Generate an FBO for each layer
+ for (var ndx = 0; ndx < this.m_texSize[2]; ndx++) {
+ var layerFbo = ctx.createFramebuffer();
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, layerFbo);
+ ctx.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex, 0, ndx);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ fbos.push(layerFbo);
+ }
+ }
+
+ // Render test images to random texture layers
+ var order = [];
+
+ for (var n = 0; n < fbos.length; n++)
+ order.push(n);
+ rnd.shuffle(order);
+
+ for (var ndx = 0; ndx < 4; ndx++) {
+ var layer = order[ndx];
+ var format = gl.RGBA;
+ var dataType = gl.UNSIGNED_BYTE;
+ var fbo = fbos[layer];
+ var viewport = this.m_texSize;
+ var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), texW, texH, 1);
+
+ tcuTextureUtil.fillWithGrid(data.getAccess(), 8, es3fFboColorbufferTests.generateRandomColor(rnd), [0, 0, 0, 0]);
+
+ var tmpTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, tmpTex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.viewport(0, 0, viewport[0], viewport[1]);
+ rrUtil.drawQuad(ctx, texToFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]);
+ this.checkError();
+
+ // Render to framebuffer
+ var p0 = [(ndx % 2) - 1.0, Math.floor(ndx / 2) - 1.0, 0.0];
+ var p1 = deMath.add(p0, [1.0, 1.0, 0.0]);
+ debug('Layer:' + layer + ' rectangle: ' + p0 + ' ' + p1);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
+ ctx.viewport(0, 0, ctx.getWidth(), ctx.getHeight());
+
+ ctx.activeTexture(gl.TEXTURE0);
+ ctx.bindTexture(gl.TEXTURE_3D, tex);
+
+ tdTexShader.setDepth(layer / (this.m_texSize[2] - 1));
+ tdTexShader.setUniforms(ctx, tdTexShaderID);
+
+ rrUtil.drawQuad(ctx, tdTexShaderID, p0, p1);
+ this.checkError();
+ }
+
+ this.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight());
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboColorbufferTests.FboColorbufferCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {Array<number>} size
+ * @param {number} funcRGB
+ * @param {number} funcAlpha
+ * @param {number} srcRGB
+ * @param {number} dstRGB
+ * @param {number} srcAlpha
+ * @param {number} dstAlpha
+ */
+es3fFboColorbufferTests.FboBlendCase = function(name, desc, format, size, funcRGB, funcAlpha, srcRGB, dstRGB, srcAlpha, dstAlpha) {
+ es3fFboColorbufferTests.FboColorbufferCase.call(this, name, desc, format);
+ this.m_size = size;
+ this.m_funcRGB = funcRGB;
+ this.m_funcAlpha = funcAlpha;
+ this.m_srcRGB = srcRGB;
+ this.m_dstRGB = dstRGB;
+ this.m_srcAlpha = srcAlpha;
+ this.m_dstAlpha = dstAlpha
+};
+
+setParentClass(es3fFboColorbufferTests.FboBlendCase, es3fFboColorbufferTests.FboColorbufferCase);
+
+es3fFboColorbufferTests.FboBlendCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_format);
+ return true; // No exception thrown
+ }
+
+ es3fFboColorbufferTests.FboBlendCase.prototype.render = function(dst) {
+ // \note Assumes floating-point or fixed-point format.
+ var ctx = this.getCurrentContext();
+ var fboFmt = gluTextureUtil.mapGLInternalFormat(this.m_format);
+ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(fboFmt);
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D], gluShaderUtil.DataType.FLOAT_VEC4);
+
+ /** @type {es3fFboTestUtil.GradientShader} */
+ var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
+
+ var texShaderID = ctx.createProgram(texShader);
+ var gradShaderID = ctx.createProgram(gradShader);
+
+ // Setup shaders
+ texShader.setUniforms (ctx, texShaderID);
+ gradShader.setGradient(ctx, gradShaderID, [0, 0, 0, 0], [1, 1, 1, 1]);
+
+ var fbo = ctx.createFramebuffer();
+ var rbo = ctx.createRenderbuffer();
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_format, this.m_size[0], this.m_size[1]);
+ this.checkError();
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.viewport(0, 0, this.m_size[0], this.m_size[1]);
+
+ // Fill framebuffer with grid pattern.
+ var format = gl.RGBA;
+ var dataType = gl.UNSIGNED_BYTE;
+ var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), texW, texH, 1);
+
+ tcuTextureUtil.fillWithGrid(data.getAccess(), 8, [0.2, 0.7, 0.1, 1.0], [0.7, 0.1, 0.5, 0.8]);
+
+ var gridTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, gridTex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
+
+ rrUtil.drawQuad(ctx, texShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]);
+ this.checkError();
+
+ // Setup blend.
+ ctx.enable(gl.BLEND);
+ ctx.blendEquationSeparate(this.m_funcRGB, this.m_funcAlpha);
+ ctx.blendFuncSeparate(this.m_srcRGB, this.m_dstRGB, this.m_srcAlpha, this.m_dstAlpha);
+
+ // Render gradient with blend.
+ rrUtil.drawQuad(ctx, gradShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]);
+
+ es3fFboTestUtil.readPixels(ctx, dst, 0, 0, this.m_size[0], this.m_size[1], fboFmt, [1, 1, 1, 1], [0, 0, 0, 0]);
+ };
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+es3fFboColorbufferTests.FboColorbufferTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'color', 'Colorbuffer tests');
+};
+
+setParentClass(es3fFboColorbufferTests.FboColorbufferTests, tcuTestCase.DeqpTest);
+
+es3fFboColorbufferTests.FboColorbufferTests.prototype.init = function() {
+ var colorFormats = [
+ // RGBA formats
+ gl.RGBA32I,
+ gl.RGBA32UI,
+ gl.RGBA16I,
+ gl.RGBA16UI,
+ gl.RGBA8,
+ gl.RGBA8I,
+ gl.RGBA8UI,
+ gl.SRGB8_ALPHA8,
+ gl.RGB10_A2,
+ gl.RGB10_A2UI,
+ gl.RGBA4,
+ gl.RGB5_A1,
+
+ // RGB formats
+ gl.RGB8,
+ gl.RGB565,
+
+ // RG formats
+ gl.RG32I,
+ gl.RG32UI,
+ gl.RG16I,
+ gl.RG16UI,
+ gl.RG8,
+ gl.RG8I,
+ gl.RG8UI,
+
+ // R formats
+ gl.R32I,
+ gl.R32UI,
+ gl.R16I,
+ gl.R16UI,
+ gl.R8,
+ gl.R8I,
+ gl.R8UI,
+
+ // gl.EXT_color_buffer_float
+ gl.RGBA32F,
+ gl.RGBA16F,
+ gl.R11F_G11F_B10F,
+ gl.RG32F,
+ gl.RG16F,
+ gl.R32F,
+ gl.R16F,
+
+ // gl.EXT_color_buffer_half_float is not exposed in WebGL 2.0.
+ // gl.RGB16F
+ ];
+
+ // .clear
+ var clearGroup = tcuTestCase.newTest("clear", "Color clears");
+ this.addChild(clearGroup);
+
+ for (var ndx = 0; ndx < colorFormats.length; ndx++) {
+ clearGroup.addChild(new es3fFboColorbufferTests.FboColorClearCase(
+ es3fFboTestUtil.getFormatName(colorFormats[ndx]), "", colorFormats[ndx], texNpotSizeA[0], texNpotSizeA[1]));
+ }
+
+ var numGroups = 6;
+
+ // .tex2d
+ var tex2DGroup = [];
+ for (var ii = 0; ii < numGroups; ++ii) {
+ tex2DGroup[ii] = tcuTestCase.newTest("tex2d", "Texture 2D tests");
+ this.addChild(tex2DGroup[ii]);
+ }
+ for (var ndx = 0; ndx < colorFormats.length; ndx++) {
+ tex2DGroup[ndx % numGroups].addChild(new es3fFboColorbufferTests.FboColorMultiTex2DCase(
+ es3fFboTestUtil.getFormatName(colorFormats[ndx]), "", colorFormats[ndx], texNpotSizeA, colorFormats[ndx], texNpotSizeB));
+ }
+
+ // .texcube
+ var texCubeGroup = [];
+ for (var ii = 0; ii < numGroups; ++ii) {
+ texCubeGroup[ii] = tcuTestCase.newTest("texcube", "Texture cube map tests");
+ this.addChild(texCubeGroup[ii]);
+ }
+ for (var ndx = 0; ndx < colorFormats.length; ndx++) {
+ texCubeGroup[ndx % numGroups].addChild(new es3fFboColorbufferTests.FboColorTexCubeCase(
+ es3fFboTestUtil.getFormatName(colorFormats[ndx]), "", colorFormats[ndx], texPotSize));
+ }
+
+ // .tex2darray
+ var tex2DArrayGroup = [];
+ for (var ii = 0; ii < numGroups; ++ii) {
+ tex2DArrayGroup[ii] = tcuTestCase.newTest("tex2darray", "Texture 2D array tests");
+ this.addChild(tex2DArrayGroup[ii]);
+ }
+ for (var ndx = 0; ndx < colorFormats.length; ndx++) {
+ tex2DArrayGroup[ndx % numGroups].addChild(new es3fFboColorbufferTests.FboColorTex2DArrayCase(
+ es3fFboTestUtil.getFormatName(colorFormats[ndx]), "", colorFormats[ndx], texPotSize));
+ }
+
+ // .tex3d
+ var tex3DGroup = [];
+ for (var ii = 0; ii < numGroups; ++ii) {
+ tex3DGroup[ii] = tcuTestCase.newTest("tex3d", "Texture 3D tests");
+ this.addChild(tex3DGroup[ii]);
+ }
+ for (var ndx = 0; ndx < colorFormats.length; ndx++) {
+ tex3DGroup[ndx % numGroups].addChild(new es3fFboColorbufferTests.FboColorTex3DCase(
+ es3fFboTestUtil.getFormatName(colorFormats[ndx]), "", colorFormats[ndx], texPotSize));
+ }
+
+ // .blend
+ var blendGroup = tcuTestCase.newTest("blend", "Blending tests");
+ this.addChild(blendGroup);
+
+ for (var ndx = 0; ndx < colorFormats.length; ndx++) {
+ var format = colorFormats[ndx];
+ var texFmt = gluTextureUtil.mapGLInternalFormat(format);
+ var fmtClass = tcuTexture.getTextureChannelClass(texFmt.type);
+ var fmtName = es3fFboTestUtil.getFormatName(format);
+
+ if (texFmt.type == tcuTexture.ChannelType.FLOAT ||
+ fmtClass == tcuTexture.TextureChannelClass.SIGNED_INTEGER ||
+ fmtClass == tcuTexture.TextureChannelClass.UNSIGNED_INTEGER)
+ continue; // Blending is not supported.
+
+ blendGroup.addChild(new es3fFboColorbufferTests.FboBlendCase(fmtName + "_src_over", "", format,
+ texNpotSizeA, gl.FUNC_ADD, gl.FUNC_ADD, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ONE));
+ }
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fFboColorbufferTests.run = function(context, range) {
+ gl = context;
+
+ const canvas = gl.canvas;
+ canvas.width = canvasWH;
+ canvas.height = canvasWH;
+
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fFboColorbufferTests.FboColorbufferTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fFboColorbufferTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboCompletenessTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboCompletenessTests.js
new file mode 100644
index 0000000000..1ae68fc8c7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboCompletenessTests.js
@@ -0,0 +1,567 @@
+
+// FboCompletenessTests
+'use strict';
+goog.provide('functional.gles3.es3fFboCompletenessTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('modules.shared.glsFboCompletenessTests');
+goog.require('modules.shared.glsFboUtil');
+
+goog.scope(function() {
+
+ var es3fFboCompletenessTests = functional.gles3.es3fFboCompletenessTests;
+ var glsFboUtil = modules.shared.glsFboUtil;
+ var glsFboCompletenessTests = modules.shared.glsFboCompletenessTests;
+ var tcuTestCase = framework.common.tcuTestCase;
+
+ es3fFboCompletenessTests.initGlDependents = function(gl) {
+ if (!(gl = gl || window.gl)) throw new Error('Invalid gl object');
+
+ /**
+ * @type {Array<number>}
+ */
+ es3fFboCompletenessTests.s_es3ColorRenderables = [
+ // GLES3, 4.4.4: "An internal format is color-renderable if it is one of
+ // the formats from table 3.12 noted as color-renderable..."
+ gl.R8, gl.RG8, gl.RGB8, gl.RGB565, gl.RGBA4, gl.RGB5_A1, gl.RGBA8,
+ gl.RGB10_A2, gl.RGB10_A2UI, gl.SRGB8_ALPHA8,
+ gl.R8I, gl.R8UI, gl.R16I, gl.R16UI, gl.R32I, gl.R32UI,
+ gl.RG8I, gl.RG8UI, gl.RG16I, gl.RG16UI, gl.RG32I, gl.RG32UI,
+ gl.RGBA81, gl.RGBA8UI, gl.RGB16I, gl.RGBA16UI, gl.RGBA32I, gl.RGBA32UI
+ ];
+
+ /**
+ * @type {Array<number>}
+ */
+ es3fFboCompletenessTests.s_es3UnsizedColorRenderables = [
+ // "...or if it is unsized format RGBA or RGB."
+ // See Table 3.3 in GLES3.
+ glsFboUtil.formatkey(gl.RGBA, gl.UNSIGNED_BYTE),
+ glsFboUtil.formatkey(gl.RGBA, gl.UNSIGNED_SHORT_4_4_4_4),
+ glsFboUtil.formatkey(gl.RGBA, gl.UNSIGNED_SHORT_5_5_5_1),
+ glsFboUtil.formatkey(gl.RGB, gl.UNSIGNED_BYTE),
+ glsFboUtil.formatkey(gl.RGB, gl.UNSIGNED_SHORT_5_6_5)
+ ];
+
+ /**
+ * @type {Array<number>}
+ */
+ es3fFboCompletenessTests.s_es3DepthRenderables = [
+ // GLES3, 4.4.4: "An internal format is depth-renderable if it is one of
+ // the formats from table 3.13."
+ gl.DEPTH_COMPONENT16, gl.DEPTH_COMPONENT24, gl.DEPTH_COMPONENT32F,
+ gl.DEPTH24_STENCIL8, gl.DEPTH32F_STENCIL8
+ ];
+
+ /**
+ * @type {Array<number>}
+ */
+ es3fFboCompletenessTests.s_es3StencilRboRenderables = [
+ // GLES3, 4.4.4: "An internal format is stencil-renderable if it is
+ // STENCIL_INDEX8..."
+ gl.STENCIL_INDEX8
+ ];
+
+ /**
+ * @type {Array<number>}
+ */
+ es3fFboCompletenessTests.s_es3StencilRenderables = [
+ // "...or one of the formats from table 3.13 whose base internal format is
+ // DEPTH_STENCIL."
+ gl.DEPTH24_STENCIL8, gl.DEPTH32F_STENCIL8
+ ];
+
+ /**
+ * @type {Array<number>}
+ */
+ es3fFboCompletenessTests.s_es3TextureFloatFormats = [
+ gl.RGBA32F, gl.RGBA16F, gl.R11F_G11F_B10F,
+ gl.RG32F, gl.RG16F, gl.R32F, gl.R16F,
+ gl.RGBA16F, gl.RGB16F, gl.RG16F, gl.R16F
+ ];
+
+ /**
+ * @type {Array<glsFboUtil.formatT>}
+ */
+ es3fFboCompletenessTests.s_es3Formats = [
+ [
+ (
+ glsFboUtil.FormatFlags.REQUIRED_RENDERABLE |
+ glsFboUtil.FormatFlags.COLOR_RENDERABLE |
+ glsFboUtil.FormatFlags.TEXTURE_VALID
+ ),
+ glsFboUtil.rangeArray(es3fFboCompletenessTests.s_es3UnsizedColorRenderables)
+ ],
+ [
+ (
+ glsFboUtil.FormatFlags.REQUIRED_RENDERABLE |
+ glsFboUtil.FormatFlags.COLOR_RENDERABLE |
+ glsFboUtil.FormatFlags.RENDERBUFFER_VALID |
+ glsFboUtil.FormatFlags.TEXTURE_VALID
+ ),
+ glsFboUtil.rangeArray(es3fFboCompletenessTests.s_es3ColorRenderables)
+ ], [
+ (
+ glsFboUtil.FormatFlags.REQUIRED_RENDERABLE |
+ glsFboUtil.FormatFlags.DEPTH_RENDERABLE |
+ glsFboUtil.FormatFlags.RENDERBUFFER_VALID |
+ glsFboUtil.FormatFlags.TEXTURE_VALID
+ ),
+ glsFboUtil.rangeArray(es3fFboCompletenessTests.s_es3DepthRenderables)
+ ], [
+ (
+ glsFboUtil.FormatFlags.REQUIRED_RENDERABLE |
+ glsFboUtil.FormatFlags.STENCIL_RENDERABLE |
+ glsFboUtil.FormatFlags.RENDERBUFFER_VALID
+ ),
+ glsFboUtil.rangeArray(es3fFboCompletenessTests.s_es3StencilRboRenderables)
+ ], [
+ (
+ glsFboUtil.FormatFlags.REQUIRED_RENDERABLE |
+ glsFboUtil.FormatFlags.STENCIL_RENDERABLE |
+ glsFboUtil.FormatFlags.RENDERBUFFER_VALID |
+ glsFboUtil.FormatFlags.TEXTURE_VALID
+ ),
+ glsFboUtil.rangeArray(es3fFboCompletenessTests.s_es3StencilRenderables)
+ ],
+
+ // These are not color-renderable in vanilla ES3, but we need to mark them
+ // as valid for textures, since EXT_color_buffer_(half_)float brings in
+ // color-renderability and only renderbuffer-validity.
+ [
+ glsFboUtil.FormatFlags.TEXTURE_VALID,
+ glsFboUtil.rangeArray(es3fFboCompletenessTests.s_es3TextureFloatFormats)
+ ]
+ ];
+
+ // gl.EXT_color_buffer_float
+ es3fFboCompletenessTests.s_extColorBufferFloatFormats = [
+ gl.RGBA32F, gl.RGBA16F, gl.R11F_G11F_B10F, gl.RG32F, gl.RG16F, gl.R32F, gl.R16F
+ ];
+
+ // gl.OES_texture_stencil8
+ es3fFboCompletenessTests.s_extOESTextureStencil8 = [
+ gl.STENCIL_INDEX8
+ ];
+
+ es3fFboCompletenessTests.s_es3ExtFormats = [{
+ extensions: 'gl.EXT_color_buffer_float',
+ flags: glsFboUtil.FormatFlags.REQUIRED_RENDERABLE |
+ glsFboUtil.FormatFlags.COLOR_RENDERABLE |
+ glsFboUtil.FormatFlags.RENDERBUFFER_VALID,
+ formats: new glsFboUtil.Range(es3fFboCompletenessTests.s_extColorBufferFloatFormats)
+ }, {
+ extensions: 'gl.OES_texture_stencil8',
+ flags: glsFboUtil.FormatFlags.REQUIRED_RENDERABLE |
+ glsFboUtil.FormatFlags.STENCIL_RENDERABLE |
+ glsFboUtil.FormatFlags.TEXTURE_VALID,
+ formats: new glsFboUtil.Range(es3fFboCompletenessTests.s_extOESTextureStencil8)
+ }
+ ];
+
+ glsFboCompletenessTests.initGlDependents(gl);
+ };
+
+ /**
+ * @constructor
+ * @extends {glsFboUtil.Checker}
+ */
+ es3fFboCompletenessTests.ES3Checker = function() {
+ glsFboUtil.Checker.call(this, gl);
+ /** @type {number} */ this.m_numSamples = -1; // GLsizei
+ /** @type {number} */ this.m_depthStencilImage = 0; // GLuint
+ /** @type {number} */ this.m_depthStencilType = gl.NONE;
+ };
+ es3fFboCompletenessTests.ES3Checker.prototype = Object.create(glsFboUtil.Checker.prototype);
+ es3fFboCompletenessTests.ES3Checker.prototype.constructor = es3fFboCompletenessTests.ES3Checker;
+
+ es3fFboCompletenessTests.ES3Checker.prototype.check = function(attPoint, att, image) {
+
+ var imgSamples = glsFboUtil.imageNumSamples(image);
+
+ if (this.m_numSamples == -1) {
+ this.m_numSamples = imgSamples;
+ } else {
+ // GLES3: "The value of RENDERBUFFER_SAMPLES is the same for all attached
+ // renderbuffers and, if the attached images are a mix of renderbuffers
+ // and textures, the value of RENDERBUFFER_SAMPLES is zero."
+ //
+ // On creating a renderbuffer: "If _samples_ is zero, then
+ // RENDERBUFFER_SAMPLES is set to zero. Otherwise [...] the resulting
+ // value for RENDERBUFFER_SAMPLES is guaranteed to be greater than or
+ // equal to _samples_ and no more than the next larger sample count
+ // supported by the implementation."
+
+ // Either all attachments are zero-sample renderbuffers and/or
+ // textures, or none of them are.
+ this.addFBOStatus(
+ (this.m_numSamples == 0) == (imgSamples == 0),
+ gl.FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
+ );
+
+ // If the attachments requested a different number of samples, the
+ // implementation is allowed to report this as incomplete. However, it
+ // is also possible that despite the different requests, the
+ // implementation allocated the same number of samples to both. Hence
+ // reporting the framebuffer as complete is also legal.
+ this.addPotentialFBOStatus(
+ this.m_numSamples == imgSamples,
+ gl.FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
+ );
+ }
+
+ // "Depth and stencil attachments, if present, are the same image."
+ if (attPoint == gl.DEPTH_ATTACHMENT || attPoint == gl.STENCIL_ATTACHMENT) {
+ if (this.m_depthStencilImage == 0) {
+ this.m_depthStencilImage = att.imageName;
+ this.m_depthStencilType = glsFboUtil.attachmentType(att);
+
+ } else {
+ this.addFBOStatus(
+ this.m_depthStencilImage == att.imageName && this.m_depthStencilType == glsFboUtil.attachmentType(att),
+ gl.FRAMEBUFFER_UNSUPPORTED
+ );
+ }
+ }
+
+ };
+
+ /**
+ * @typedef {{textureKind: number, numLayers: number, attachmentLayer: number}}
+ */
+ es3fFboCompletenessTests.numLayersParamsT;
+
+ /**
+ * @param {number} textureKind
+ * @param {number} numLayers
+ * @param {number} attachmentLayer
+ * @return {es3fFboCompletenessTests.numLayersParamsT}
+ */
+ es3fFboCompletenessTests.numLayersParams = function(textureKind, numLayers, attachmentLayer) {
+ if (typeof(attachmentLayer) == 'undefined') {
+ textureKind = 0;
+ numLayers = 0;
+ attachmentLayer = 0;
+ }
+ return {
+ textureKind: textureKind, //< gl.TEXTURE_3D or gl.TEXTURE_2D_ARRAY
+ numLayers: numLayers, //< Number of layers in texture
+ attachmentLayer: attachmentLayer //< Layer referenced by attachment
+ };
+ };
+
+ /**
+ * es3fFboCompletenessTests.numLayersParams.getName
+ * @param {es3fFboCompletenessTests.numLayersParamsT} params
+ * @return {string}
+ */
+ es3fFboCompletenessTests.numLayersParams.getName = function(params) {
+ return (
+ (params.textureKind == gl.TEXTURE_3D ? '3d' : '2darr') + '_' +
+ params.numLayers + '_' +
+ params.attachmentLayer
+ );
+ };
+ /**
+ * es3fFboCompletenessTests.numLayersParams.getDescription
+ * @param {es3fFboCompletenessTests.numLayersParamsT} params
+ * @return {string}
+ */
+ es3fFboCompletenessTests.numLayersParams.getDescription = function(params) {
+ return (
+ (params.textureKind == gl.TEXTURE_3D ? '3D Texture' : '2D Array Texture') + ', ' +
+ params.numLayers + ' layers, ' +
+ 'attached layer ' + params.attachmentLayer + '.'
+ );
+ };
+
+ // string, string, glsFboCompleteness::context, params.
+ /**
+ * @constructor
+ * @extends {glsFboCompletenessTests.TestBase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {glsFboCompletenessTests.Context} ctx
+ * @param {es3fFboCompletenessTests.numLayersParamsT} params
+ */
+ es3fFboCompletenessTests.NumLayersTest = function(name, desc, ctx, params) {
+ glsFboCompletenessTests.TestBase.call(this, name, desc, params);
+ this.m_ctx = ctx;
+ };
+
+ es3fFboCompletenessTests.NumLayersTest.prototype = Object.create(glsFboCompletenessTests.TestBase.prototype);
+ es3fFboCompletenessTests.NumLayersTest.prototype.constructor = es3fFboCompletenessTests.NumLayersTest;
+
+ es3fFboCompletenessTests.NumLayersTest.prototype.build = function(builder, gl) {
+
+ if (!(gl = gl || window.gl)) throw new Error('Invalid gl object');
+
+ var target = gl.COLOR_ATTACHMENT0;
+ var texCfg = builder.makeConfig(
+ function(kind) {
+ switch (kind) {
+ case gl.TEXTURE_3D: return glsFboUtil.Texture3D;
+ case gl.TEXTURE_2D_ARRAY: return glsFboUtil.Texture2DArray;
+ default: throw new Error('Impossible case');
+ }
+ }(this.m_params.textureKind)
+ );
+
+ texCfg.internalFormat = this.getDefaultFormat(target, gl.TEXTURE, gl);
+ texCfg.width = 64;
+ texCfg.height = 64;
+ texCfg.numLayers = this.m_params.numLayers;
+ var tex = builder.glCreateTexture(texCfg);
+
+ var att = builder.makeConfig(glsFboUtil.TextureLayerAttachment);
+ att.layer = this.m_params.attachmentLayer;
+ att.imageName = tex;
+
+ builder.glAttach(target, att);
+
+ // return tcuTestCase.IterateResult.STOP;
+ };
+//es3fFboCompletenessTests.NumLayersTest.prototype.isExecutable = function() {
+// return false;
+//};
+
+ /**
+ * @enum
+ */
+ es3fFboCompletenessTests.e_samples = {
+ NONE: -2,
+ TEXTURE: -1
+ };
+
+ /**
+ * @typedef {{numSamples: Array<number>}}
+ */
+ es3fFboCompletenessTests.numSamplesParamsT;
+
+ /**
+ * @param {number} colour
+ * @param {number} depth
+ * @param {number} stencil
+ * @return {es3fFboCompletenessTests.numSamplesParamsT}
+ */
+ es3fFboCompletenessTests.numSamplesParams = function(colour, depth, stencil) {
+ var ret = {
+ numSamples: new Array(3)
+ };
+ if (colour !== undefined) {
+ ret.numSamples[0] = colour;
+ if (depth !== undefined) {
+ ret.numSamples[1] = depth;
+ if (stencil !== undefined) {
+ ret.numSamples[2] = stencil;
+ }
+ }
+ }
+ return ret;
+ };
+
+ /**
+ * @param {es3fFboCompletenessTests.numSamplesParamsT} params
+ * @return {string}
+ */
+ es3fFboCompletenessTests.numSamplesParams.getName = function(params) {
+ var out = '';
+
+ var first = true;
+ for (var i = 0; i < 3; ++i) {
+ if (first)
+ first = false;
+ else
+ out += '_';
+
+ switch (params.numSamples[i]) {
+ case es3fFboCompletenessTests.e_samples.NONE: out += 'none'; break;
+ case es3fFboCompletenessTests.e_samples.TEXTURE: out += 'tex'; break;
+ default: out += 'rbo'; break;
+ }
+ }
+ return out;
+ };
+ /**
+ * @param {es3fFboCompletenessTests.numSamplesParamsT} params
+ * @return {string}
+ */
+ es3fFboCompletenessTests.numSamplesParams.getDescription = function(params) {
+ var out = '';
+ var names = ['color', 'depth', 'stencil'];
+ var first = true;
+
+ for (var i = 0; i < 3; ++i) {
+ if (first)
+ first = false;
+ else
+ out += ', ';
+
+ if (params.numSamples[i] == es3fFboCompletenessTests.e_samples.TEXTURE) {
+ out += 'texture ' + names[i] + ' attachment';
+ } else {
+ out += params.numSamples[i] + '-sample renderbuffer ' + names[i] + ' attachment';
+ }
+ }
+ return out;
+ };
+
+ /**
+ * @constructor
+ * @extends {glsFboCompletenessTests.TestBase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {glsFboCompletenessTests.Context} ctx
+ * @param {es3fFboCompletenessTests.numSamplesParamsT} params
+ */
+ es3fFboCompletenessTests.NumSamplesTest = function(name, desc, ctx, params) {
+ glsFboCompletenessTests.TestBase.call(this, name, desc, params);
+ this.m_ctx = ctx;
+ };
+ es3fFboCompletenessTests.NumSamplesTest.prototype = Object.create(glsFboCompletenessTests.TestBase.prototype);
+ es3fFboCompletenessTests.NumSamplesTest.prototype.constructor = es3fFboCompletenessTests.NumSamplesTest;
+
+ es3fFboCompletenessTests.NumSamplesTest.prototype.build = function(builder, gl) {
+ if (!(gl = gl || window.gl)) throw new Error('Invalid gl object');
+
+ var s_targets = [
+ gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.DEPTH_ATTACHMENT
+ ];
+ // Non-integer formats for each attachment type.
+ // \todo [2013-12-17 lauri] Add fixed/floating/integer metadata for formats so
+ // we can pick one smartly or maybe try several.
+ var s_formats = [
+ gl.RGBA8, gl.RGB565, gl.DEPTH_COMPONENT24
+ ];
+
+ var l = s_targets.length;
+ if (this.m_params.numSamples.length != l)
+ throw new Error('Wrong number of params.');
+
+ for (var i = 0; i < l; ++i) {
+ var target = s_targets[i];
+ var fmt = new glsFboUtil.ImageFormat(s_formats[i], gl.NONE);
+
+ var ns = this.m_params.numSamples[i];
+ if (ns == es3fFboCompletenessTests.e_samples.NONE)
+ continue;
+ if (ns == es3fFboCompletenessTests.e_samples.TEXTURE) {
+ this.attachTargetToNew(target, gl.TEXTURE, fmt, 64, 64, builder, gl);
+ } else {
+ var rboCfg = builder.makeConfig(glsFboUtil.Renderbuffer);
+ rboCfg.internalFormat = fmt;
+ rboCfg.width = rboCfg.height = 64;
+ rboCfg.numSamples = ns;
+
+ var rbo = builder.glCreateRbo(rboCfg);
+ // Implementations do not necessarily support sample sizes greater than 1.
+ if (builder.getError() == gl.INVALID_OPERATION) {
+ throw new Error('Unsupported number of samples.');
+ }
+ var att = builder.makeConfig(glsFboUtil.RenderbufferAttachment);
+ att.imageName = rbo;
+ builder.glAttach(target, att);
+ }
+ }
+
+ return true;
+ };
+
+ es3fFboCompletenessTests.init = function() {
+
+ //(testCtx, renderCtx, factory) {
+ var fboCtx = new glsFboCompletenessTests.Context(null, gl, function() {
+ return new es3fFboCompletenessTests.ES3Checker();
+ });
+
+ fboCtx.addFormats(glsFboUtil.rangeArray(es3fFboCompletenessTests.s_es3Formats));
+
+ /** @const @type {tcuTestCase.DeqpTest} */
+ var testGroup = tcuTestCase.runner.testCases;
+
+ testGroup.addChild(fboCtx.createRenderableTests(gl));
+ testGroup.addChild(fboCtx.createAttachmentTests(gl));
+ testGroup.addChild(fboCtx.createSizeTests(gl));
+
+ /** @type {tcuTestCase.DeqpTest} */
+ var layerTests = tcuTestCase.newTest('layer', 'Tests for layer attachments');
+
+ /** @static */
+ var s_layersParams = [
+ es3fFboCompletenessTests.numLayersParams(gl.TEXTURE_2D_ARRAY, 1, 0),
+ es3fFboCompletenessTests.numLayersParams(gl.TEXTURE_2D_ARRAY, 1, 3),
+ es3fFboCompletenessTests.numLayersParams(gl.TEXTURE_2D_ARRAY, 4, 3),
+ es3fFboCompletenessTests.numLayersParams(gl.TEXTURE_2D_ARRAY, 4, 15),
+ es3fFboCompletenessTests.numLayersParams(gl.TEXTURE_3D, 1, 0),
+ es3fFboCompletenessTests.numLayersParams(gl.TEXTURE_3D, 1, 15),
+ es3fFboCompletenessTests.numLayersParams(gl.TEXTURE_3D, 4, 15),
+ es3fFboCompletenessTests.numLayersParams(gl.TEXTURE_3D, 64, 15)
+ ];
+
+ for (var i = 0; i < s_layersParams.length; ++i) {
+ var name = 'name';
+ var desc = 'desc';
+ layerTests.addChild(new es3fFboCompletenessTests.NumLayersTest(
+ es3fFboCompletenessTests.numLayersParams.getName(s_layersParams[i]),
+ es3fFboCompletenessTests.numLayersParams.getDescription(s_layersParams[i]),
+ fboCtx, s_layersParams[i]
+ ));
+ }
+ testGroup.addChild(layerTests);
+
+ /** @type {tcuTestCase.DeqpTest} */
+ var sampleTests = tcuTestCase.newTest('sample', 'Tests for multisample attachments');
+ // some short hand
+ var samples = es3fFboCompletenessTests.e_samples;
+ // sample tests
+ /** @static */
+ var s_samplesParams = [
+ es3fFboCompletenessTests.numSamplesParams(0, samples.NONE, samples.NONE),
+ es3fFboCompletenessTests.numSamplesParams(1, samples.NONE, samples.NONE),
+ es3fFboCompletenessTests.numSamplesParams(2, samples.NONE, samples.NONE),
+ es3fFboCompletenessTests.numSamplesParams(0, samples.TEXTURE, samples.NONE),
+ es3fFboCompletenessTests.numSamplesParams(1, samples.TEXTURE, samples.NONE),
+ es3fFboCompletenessTests.numSamplesParams(2, samples.TEXTURE, samples.NONE),
+ es3fFboCompletenessTests.numSamplesParams(2, 1, samples.NONE),
+ es3fFboCompletenessTests.numSamplesParams(2, 2, samples.NONE),
+ es3fFboCompletenessTests.numSamplesParams(0, 0, samples.TEXTURE),
+ es3fFboCompletenessTests.numSamplesParams(1, 2, 0),
+ es3fFboCompletenessTests.numSamplesParams(2, 2, 0),
+ es3fFboCompletenessTests.numSamplesParams(1, 1, 1),
+ es3fFboCompletenessTests.numSamplesParams(1, 2, 4)
+ ];
+
+ for (var i = 0; i < s_samplesParams.length; ++i) {
+ var name = 'name';
+ var desc = 'desc';
+ sampleTests.addChild(new es3fFboCompletenessTests.NumSamplesTest(
+ es3fFboCompletenessTests.numSamplesParams.getName(s_samplesParams[i]),
+ es3fFboCompletenessTests.numSamplesParams.getDescription(s_samplesParams[i]),
+ fboCtx, s_samplesParams[i]
+ ));
+ }
+ testGroup.addChild(sampleTests);
+
+ };
+
+ es3fFboCompletenessTests.run = function() {
+ var testName = 'completeness';
+ var testDescription = 'Completeness tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.testCases = tcuTestCase.newTest(testName, testDescription, null);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+ try {
+ es3fFboCompletenessTests.init();
+ tcuTestCase.runner.runCallback(tcuTestCase.runTestCases);
+ } catch (err) {
+ bufferedLogToConsole(err);
+ tcuTestCase.runner.terminate();
+ }
+
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboDepthbufferTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboDepthbufferTests.js
new file mode 100644
index 0000000000..c662a3764e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboDepthbufferTests.js
@@ -0,0 +1,385 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fFboDepthbufferTests');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('functional.gles3.es3fFboTestCase');
+goog.require('functional.gles3.es3fFboTestUtil');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.referencerenderer.rrUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.opengl.gluShaderUtil');
+
+goog.scope(function() {
+var es3fFboDepthbufferTests = functional.gles3.es3fFboDepthbufferTests;
+var es3fFboTestCase = functional.gles3.es3fFboTestCase;
+var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
+var tcuTestCase = framework.common.tcuTestCase;
+var tcuSurface = framework.common.tcuSurface;
+var tcuTexture = framework.common.tcuTexture;
+var gluTextureUtil = framework.opengl.gluTextureUtil;
+var tcuRGBA = framework.common.tcuRGBA;
+var deRandom = framework.delibs.debase.deRandom;
+var tcuImageCompare = framework.common.tcuImageCompare;
+var tcuTextureUtil = framework.common.tcuTextureUtil;
+var rrUtil = framework.referencerenderer.rrUtil;
+var deMath = framework.delibs.debase.deMath;
+var gluShaderUtil = framework.opengl.gluShaderUtil;
+
+/** @type {WebGL2RenderingContext} */ var gl;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} width
+ * @param {number} height
+ */
+es3fFboDepthbufferTests.BasicFboDepthCase = function(name, desc, format, width, height) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_format = format;
+ this.m_width = width;
+ this.m_height = height;
+};
+
+setParentClass(es3fFboDepthbufferTests.BasicFboDepthCase, es3fFboTestCase.FboTestCase);
+
+es3fFboDepthbufferTests.BasicFboDepthCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_format);
+ return true; // No exception thrown
+ };
+
+es3fFboDepthbufferTests.BasicFboDepthCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var colorFormat = gl.RGBA8;
+ /** @type {es3fFboTestUtil.GradientShader} */
+ var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D], gluShaderUtil.DataType.FLOAT_VEC4);
+ var texShaderID = ctx.createProgram(texShader);
+ var gradShaderID = ctx.createProgram(gradShader);
+ var clearDepth = 1;
+
+ // Setup shaders
+ gradShader.setGradient(ctx, gradShaderID, [0, 0, 0, 0], [1, 1, 1, 1]);
+ texShader.setUniforms(ctx, texShaderID);
+
+ // Setup FBO
+
+ var fbo = ctx.createFramebuffer();
+ var colorRbo = ctx.createRenderbuffer();
+ var depthRbo = ctx.createRenderbuffer();
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.m_width, this.m_height);
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, depthRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_format, this.m_width, this.m_height);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRbo);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.viewport(0, 0, this.m_width, this.m_height);
+
+ // Clear depth to 1
+ ctx.clearBufferfv(gl.DEPTH, 0, [clearDepth]);
+
+ // Render gradient with depth = [-1..1]
+ ctx.enable(gl.DEPTH_TEST);
+ rrUtil.drawQuad(ctx, gradShaderID, [-1.0, -1.0, -1.0], [1.0, 1.0, 1.0]);
+
+ // Render grid pattern with depth = 0
+ var format = gl.RGBA;
+ var dataType = gl.UNSIGNED_BYTE;
+ var texW = 128;
+ var texH = 128;
+ var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), texW, texH, 1);
+
+ tcuTextureUtil.fillWithGrid(data.getAccess(), 8, [0.2, 0.7, 0.1, 1.0], [0.7, 0.1, 0.5, 0.8]);
+
+ var gridTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, gridTex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
+
+ rrUtil.drawQuad(ctx, texShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]);
+ this.checkError();
+
+ // Read results.
+ this.readPixelsUsingFormat(dst, 0, 0, this.m_width, this.m_height,
+ gluTextureUtil.mapGLInternalFormat(colorFormat),
+ [1, 1, 1, 1], [0, 0, 0, 0]);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} width
+ * @param {number} height
+ */
+es3fFboDepthbufferTests.DepthWriteClampCase = function(name, desc, format, width, height) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_format = format;
+ this.m_width = width;
+ this.m_height = height;
+};
+
+setParentClass(es3fFboDepthbufferTests.DepthWriteClampCase, es3fFboTestCase.FboTestCase);
+
+es3fFboDepthbufferTests.DepthWriteClampCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_format);
+ return true; // No exception thrown
+ };
+
+es3fFboDepthbufferTests.DepthWriteClampCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var colorFormat = gl.RGBA8;
+ var transferFmt = gluTextureUtil.getTransferFormat(gluTextureUtil.mapGLInternalFormat(this.m_format));
+ /** @type {es3fFboTestUtil.DepthGradientShader} */
+ var gradShader = new es3fFboTestUtil.DepthGradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
+
+ var gradShaderID = ctx.createProgram(gradShader);
+ var clearDepth = 1;
+ var red = [1, 0, 0, 1];
+ var green = [0, 1, 0, 1];
+
+ // Setup FBO
+
+ var fbo = ctx.createFramebuffer();
+ var colorRbo = ctx.createRenderbuffer();
+ var depthTexture = ctx.createTexture();
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.m_width, this.m_height);
+
+ ctx.bindTexture(gl.TEXTURE_2D, depthTexture);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_format, this.m_width, this.m_height, 0, transferFmt.format, transferFmt.dataType, null);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTexture, 0);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.viewport(0, 0, this.m_width, this.m_height);
+
+ // Clear depth to 1
+ ctx.clearBufferfv(gl.DEPTH, 0, [clearDepth]);
+
+ // Render gradient with depth = [-1..1]
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.depthFunc(gl.ALWAYS);
+ gradShader.setUniforms(ctx, gradShaderID, -1, 2, green);
+ rrUtil.drawQuad(ctx, gradShaderID, [-1.0, -1.0, -1.0], [1.0, 1.0, 1.0]);
+ ctx.depthMask(false);
+
+ // Test if any fragment has greater depth than 1; there should be none
+ ctx.depthFunc(gl.LESS); // (1 < depth) ?
+ gradShader.setUniforms(ctx, gradShaderID, 1, 1, red);
+ rrUtil.drawQuad(ctx, gradShaderID, [-1.0, -1.0, -1.0], [1.0, 1.0, 1.0]);
+
+ // Test if any fragment has smaller depth than 0; there should be none
+ ctx.depthFunc(gl.GREATER); // (0 > depth) ?
+ gradShader.setUniforms(ctx, gradShaderID, 0, 0, red);
+ rrUtil.drawQuad(ctx, gradShaderID, [-1.0, -1.0, -1.0], [1.0, 1.0, 1.0]);
+
+ // Read results.
+ this.readPixelsUsingFormat(dst, 0, 0, this.m_width, this.m_height,
+ gluTextureUtil.mapGLInternalFormat(colorFormat),
+ [1, 1, 1, 1], [0, 0, 0, 0]);
+
+ ctx.depthMask(true);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} width
+ * @param {number} height
+ */
+es3fFboDepthbufferTests.DepthTestClampCase = function(name, desc, format, width, height) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_format = format;
+ this.m_width = width;
+ this.m_height = height;
+};
+
+setParentClass(es3fFboDepthbufferTests.DepthTestClampCase, es3fFboTestCase.FboTestCase);
+
+es3fFboDepthbufferTests.DepthTestClampCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_format);
+ return true; // No exception thrown
+ };
+
+es3fFboDepthbufferTests.DepthTestClampCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var colorFormat = gl.RGBA8;
+ var transferFmt = gluTextureUtil.getTransferFormat(gluTextureUtil.mapGLInternalFormat(this.m_format));
+ /** @type {es3fFboTestUtil.DepthGradientShader} */
+ var gradShader = new es3fFboTestUtil.DepthGradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
+
+ var gradShaderID = ctx.createProgram(gradShader);
+ var clearDepth = 1;
+ var yellow = [1, 1, 0, 1];
+ var green = [0, 1, 0, 1];
+
+ // Setup FBO
+
+ var fbo = ctx.createFramebuffer();
+ var colorRbo = ctx.createRenderbuffer();
+ var depthTexture = ctx.createTexture();
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.m_width, this.m_height);
+
+ ctx.bindTexture(gl.TEXTURE_2D, depthTexture);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_format, this.m_width, this.m_height, 0, transferFmt.format, transferFmt.dataType, null);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTexture, 0);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.viewport(0, 0, this.m_width, this.m_height);
+
+ // Clear depth to 1
+ ctx.clearBufferfv(gl.DEPTH, 0, [clearDepth]);
+
+ // Test values used in depth test are clamped
+
+ // Render green quad, depth gradient = [-1..2]
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.depthFunc(gl.ALWAYS);
+
+ gradShader.setUniforms(ctx, gradShaderID, -1, 2, green);
+ rrUtil.drawQuad(ctx, gradShaderID, [-1.0, -1.0, -1.0], [1.0, 1.0, 1.0]);
+
+ // Render yellow quad, depth gradient = [-0.5..3]. Gradients have equal values only outside [0, 1] range due to clamping
+ ctx.depthFunc(gl.EQUAL);
+
+ gradShader.setUniforms(ctx, gradShaderID, -0.5, 3, yellow);
+ rrUtil.drawQuad(ctx, gradShaderID, [-1.0, -1.0, -1.0], [1.0, 1.0, 1.0]);
+
+ // Read results.
+ this.readPixelsUsingFormat(dst, 0, 0, this.m_width, this.m_height,
+ gluTextureUtil.mapGLInternalFormat(colorFormat),
+ [1, 1, 1, 1], [0, 0, 0, 0]);
+};
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+es3fFboDepthbufferTests.FboDepthbufferTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'depth', 'depth tests');
+};
+
+setParentClass(es3fFboDepthbufferTests.FboDepthbufferTests, tcuTestCase.DeqpTest);
+
+es3fFboDepthbufferTests.FboDepthbufferTests.prototype.init = function() {
+ var depthFormats = [
+ gl.DEPTH_COMPONENT32F,
+ gl.DEPTH_COMPONENT24,
+ gl.DEPTH_COMPONENT16,
+ gl.DEPTH32F_STENCIL8,
+ gl.DEPTH24_STENCIL8
+ ];
+
+ // .basic
+ var basicGroup = tcuTestCase.newTest('basic', 'Basic depth tests');
+ this.addChild(basicGroup);
+
+ for (var ndx = 0; ndx < depthFormats.length; ndx++)
+ basicGroup.addChild(new es3fFboDepthbufferTests.BasicFboDepthCase(es3fFboTestUtil.getFormatName(depthFormats[ndx]), '', depthFormats[ndx], 119, 127));
+
+ // .depth_write_clamp
+ var depthClampGroup = tcuTestCase.newTest('depth_write_clamp', 'Depth write clamping tests');
+ this.addChild(depthClampGroup);
+
+ for (var ndx = 0; ndx < depthFormats.length; ndx++)
+ depthClampGroup.addChild(new es3fFboDepthbufferTests.DepthWriteClampCase(es3fFboTestUtil.getFormatName(depthFormats[ndx]), '', depthFormats[ndx], 119, 127));
+
+ // .depth_test_clamp
+ var depthTestGroup = tcuTestCase.newTest('depth_test_clamp', 'Depth test value clamping tests');
+ this.addChild(depthTestGroup);
+
+ for (var ndx = 0; ndx < depthFormats.length; ndx++)
+ depthTestGroup.addChild(new es3fFboDepthbufferTests.DepthTestClampCase(es3fFboTestUtil.getFormatName(depthFormats[ndx]), '', depthFormats[ndx], 119, 127));
+
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fFboDepthbufferTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fFboDepthbufferTests.FboDepthbufferTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fFboDepthbufferTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboInvalidateTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboInvalidateTests.js
new file mode 100644
index 0000000000..3a90cceccd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboInvalidateTests.js
@@ -0,0 +1,1471 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fFboInvalidateTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('framework.referencerenderer.rrUtil');
+goog.require('functional.gles3.es3fFboTestCase');
+goog.require('functional.gles3.es3fFboTestUtil');
+
+goog.scope(function() {
+var es3fFboInvalidateTests = functional.gles3.es3fFboInvalidateTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var es3fFboTestCase = functional.gles3.es3fFboTestCase;
+var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
+var rrUtil = framework.referencerenderer.rrUtil;
+var gluShaderUtil = framework.opengl.gluShaderUtil;
+var gluTextureUtil = framework.opengl.gluTextureUtil;
+var tcuTexture = framework.common.tcuTexture;
+var tcuTextureUtil = framework.common.tcuTextureUtil;
+var deMath = framework.delibs.debase.deMath;
+var tcuRGBA = framework.common.tcuRGBA;
+var tcuImageCompare = framework.common.tcuImageCompare;
+
+/** @type {WebGL2RenderingContext} */ var gl;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+var getDefaultFBDiscardAttachments = function(discardBufferBits) {
+ var attachments = [];
+
+ if (discardBufferBits & gl.COLOR_BUFFER_BIT)
+ attachments.push(gl.COLOR);
+
+ if (discardBufferBits & gl.DEPTH_BUFFER_BIT)
+ attachments.push(gl.DEPTH);
+
+ if (discardBufferBits & gl.STENCIL_BUFFER_BIT)
+ attachments.push(gl.STENCIL);
+
+ return attachments;
+};
+
+var getFBODiscardAttachments = function(discardBufferBits) {
+ var attachments = [];
+
+ if (discardBufferBits & gl.COLOR_BUFFER_BIT)
+ attachments.push(gl.COLOR_ATTACHMENT0);
+
+ // \note DEPTH_STENCIL_ATTACHMENT is allowed when discarding FBO, but not with default FB
+ if ((discardBufferBits & (gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)) == (gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT))
+ attachments.push(gl.DEPTH_STENCIL_ATTACHMENT);
+ else if (discardBufferBits & gl.DEPTH_BUFFER_BIT)
+ attachments.push(gl.DEPTH_ATTACHMENT);
+ else if (discardBufferBits & gl.STENCIL_BUFFER_BIT)
+ attachments.push(gl.STENCIL_ATTACHMENT);
+
+ return attachments;
+};
+
+var getCompatibleColorFormat = function() {
+ var redBits = gl.getParameter(gl.RED_BITS);
+ var greenBits = gl.getParameter(gl.GREEN_BITS);
+ var blueBits = gl.getParameter(gl.BLUE_BITS);
+ var alphaBits = gl.getParameter(gl.ALPHA_BITS);
+ switch ('' + redBits + greenBits + blueBits + alphaBits) {
+ case '8888' : return gl.RGBA8;
+ case '8880' : return gl.RGB8;
+ default:
+ throw new Error('Unexpected bit depth');
+ }
+};
+
+var getCompatibleDepthStencilFormat = function() {
+ var depthBits = /** @type {number} */ (gl.getParameter(gl.DEPTH_BITS));
+ var stencilBits = /** @type {number} */ (gl.getParameter(gl.STENCIL_BITS));
+ var hasDepth = depthBits > 0;
+ var hasStencil = stencilBits > 0;
+
+ if (!hasDepth || !hasStencil || (stencilBits != 8))
+ return gl.NONE;
+
+ if (depthBits == 32)
+ return gl.DEPTH32F_STENCIL8;
+ else if (depthBits == 24)
+ return gl.DEPTH24_STENCIL8;
+ else
+ return gl.NONE;
+};
+
+var hasAttachment = function(attachments, attachment) {
+ return attachments.indexOf(attachment) >= 0;
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} buffers
+ * @param {number=} target
+ */
+es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase = function(name, desc, buffers, target) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_buffers = buffers;
+ this.m_fboTarget = target || gl.FRAMEBUFFER;
+};
+
+setParentClass(es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase, es3fFboTestCase.FboTestCase);
+
+es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var attachments = getDefaultFBDiscardAttachments(this.m_buffers);
+
+ var shader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var program = ctx.createProgram(shader);
+ shader.setColor(ctx, program, [1, 0, 0, 1]);
+ ctx.clearColor(0, 0, 0, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
+ ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
+
+ rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);
+ ctx.invalidateFramebuffer(this.m_fboTarget, attachments);
+
+ if ((this.m_buffers & gl.COLOR_BUFFER_BIT) != 0) {
+ // Color was not preserved - fill with green.
+ ctx.disable(gl.DEPTH_TEST);
+ ctx.disable(gl.STENCIL_TEST);
+
+ shader.setColor(ctx, program, [0, 1, 0, 1]);
+ rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ }
+
+ if ((this.m_buffers & gl.DEPTH_BUFFER_BIT) != 0) {
+ // Depth was not preserved.
+ ctx.depthFunc(gl.ALWAYS);
+ }
+
+ if ((this.m_buffers & gl.STENCIL_BUFFER_BIT) == 0) {
+ // Stencil was preserved.
+ ctx.stencilFunc(gl.EQUAL, 1, 0xff);
+ }
+
+ ctx.enable(gl.BLEND);
+ ctx.blendFunc(gl.ONE, gl.ONE);
+ ctx.blendEquation(gl.FUNC_ADD);
+
+ shader.setColor(ctx, program, [0, 0, 1, 1]);
+ rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
+ dst.readViewport(ctx);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} buffers
+ */
+es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase = function(name, desc, buffers) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_buffers = buffers;
+};
+
+setParentClass(es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase, es3fFboTestCase.FboTestCase);
+
+es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var attachments = getDefaultFBDiscardAttachments(this.m_buffers);
+
+ var shader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var program = ctx.createProgram(shader);
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D], gluShaderUtil.DataType.FLOAT_VEC4);
+
+ /** @type {es3fFboTestUtil.GradientShader} */
+ var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
+
+ var texShaderID = ctx.createProgram(texShader);
+ var gradShaderID = ctx.createProgram(gradShader);
+ ctx.clearColor(0, 0, 0, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ // Create fbo.
+ var fbo = ctx.createFramebuffer();
+ var tex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, tex);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, this.getWidth(), this.getHeight(), 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ ctx.bindTexture(gl.TEXTURE_2D, null);
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
+ ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
+
+ shader.setColor(ctx, program, [1, 0, 0, 1]);
+ rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);
+
+ ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);
+
+ // Switch to fbo and render gradient into it.
+ ctx.disable(gl.DEPTH_TEST);
+ ctx.disable(gl.STENCIL_TEST);
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ gradShader.setGradient(ctx, gradShaderID, [0, 0, 0, 0], [1, 1, 1, 1]);
+ rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, 0], [1, 1, 0]);
+ // Restore default fbo.
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ if ((this.m_buffers & gl.COLOR_BUFFER_BIT) != 0) {
+ // Color was not preserved - fill with green.
+ shader.setColor(ctx, program, [0, 1, 0, 1]);
+ rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
+ }
+
+ if ((this.m_buffers & gl.DEPTH_BUFFER_BIT) != 0) {
+ // Depth was not preserved.
+ ctx.depthFunc(gl.ALWAYS);
+ }
+
+ if ((this.m_buffers & gl.STENCIL_BUFFER_BIT) == 0) {
+ // Stencil was preserved.
+ ctx.stencilFunc(gl.EQUAL, 1, 0xff);
+ }
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.enable(gl.BLEND);
+ ctx.blendFunc(gl.ONE, gl.ONE);
+ ctx.blendEquation(gl.FUNC_ADD);
+ ctx.bindTexture(gl.TEXTURE_2D, tex);
+
+ texShader.setUniforms(ctx, texShaderID);
+ rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ dst.readViewport(ctx);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} buffers
+ * @param {number=} target
+ */
+es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase = function(name, desc, buffers, target) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_buffers = buffers;
+ this.m_fboTarget = target || gl.FRAMEBUFFER;
+};
+
+setParentClass(es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase, es3fFboTestCase.FboTestCase);
+
+es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var invalidateX = this.getWidth() / 4;
+ var invalidateY = this.getHeight() / 4;
+ var invalidateW = this.getWidth() / 2;
+ var invalidateH = this.getHeight() / 2;
+ var attachments = getDefaultFBDiscardAttachments(this.m_buffers);
+
+ var shader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var program = ctx.createProgram(shader);
+ shader.setColor(ctx, program, [1, 0, 0, 1]);
+ ctx.clearColor(0, 0, 0, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
+ ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
+
+ rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);
+ ctx.invalidateSubFramebuffer(this.m_fboTarget, attachments, invalidateX, invalidateY, invalidateW, invalidateH);
+
+ // Clear invalidated buffers.
+ ctx.clearColor(0, 1, 0, 1);
+ ctx.clearStencil(1);
+ ctx.scissor(invalidateX, invalidateY, invalidateW, invalidateH);
+ ctx.enable(gl.SCISSOR_TEST);
+ ctx.clear(this.m_buffers);
+ ctx.disable(gl.SCISSOR_TEST);
+
+ ctx.enable(gl.BLEND);
+ ctx.blendFunc(gl.ONE, gl.ONE);
+ ctx.blendEquation(gl.FUNC_ADD);
+
+ shader.setColor(ctx, program, [0, 0, 1, 1]);
+ rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
+ dst.readViewport(ctx);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} buffers
+ */
+es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase = function(name, desc, buffers) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_buffers = buffers;
+};
+
+setParentClass(es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase, es3fFboTestCase.FboTestCase);
+
+es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var attachments = getDefaultFBDiscardAttachments(this.m_buffers);
+ var invalidateX = this.getWidth() / 4;
+ var invalidateY = this.getHeight() / 4;
+ var invalidateW = this.getWidth() / 2;
+ var invalidateH = this.getHeight() / 2;
+
+ var shader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var program = ctx.createProgram(shader);
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D], gluShaderUtil.DataType.FLOAT_VEC4);
+
+ /** @type {es3fFboTestUtil.GradientShader} */
+ var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
+
+ var texShaderID = ctx.createProgram(texShader);
+ var gradShaderID = ctx.createProgram(gradShader);
+ ctx.clearColor(0, 0, 0, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ // Create fbo.
+ var fbo = ctx.createFramebuffer();
+ var tex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, tex);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, this.getWidth(), this.getHeight(), 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ ctx.bindTexture(gl.TEXTURE_2D, null);
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
+ ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
+
+ shader.setColor(ctx, program, [1, 0, 0, 1]);
+ rrUtil.drawQuad(ctx, program, [-1, -1, -1], [1, 1, 1]);
+
+ ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);
+
+ // Switch to fbo and render gradient into it.
+ ctx.disable(gl.DEPTH_TEST);
+ ctx.disable(gl.STENCIL_TEST);
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ gradShader.setGradient(ctx, gradShaderID, [0, 0, 0, 0], [1, 1, 1, 1]);
+ rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, 0], [1, 1, 0]);
+ // Restore default fbo.
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ if ((this.m_buffers & gl.COLOR_BUFFER_BIT) != 0) {
+ // Color was not preserved - fill with green.
+ shader.setColor(ctx, program, [0, 1, 0, 1]);
+ rrUtil.drawQuad(ctx, program, [-1, -1, 0], [1, 1, 0]);
+ }
+
+ // Clear invalidated buffers.
+ ctx.clearColor(0, 1, 0, 1);
+ ctx.clearStencil(1);
+ ctx.scissor(invalidateX, invalidateY, invalidateW, invalidateH);
+ ctx.enable(gl.SCISSOR_TEST);
+ ctx.clear(this.m_buffers);
+ ctx.disable(gl.SCISSOR_TEST);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.enable(gl.BLEND);
+ ctx.blendFunc(gl.ONE, gl.ONE);
+ ctx.blendEquation(gl.FUNC_ADD);
+ ctx.bindTexture(gl.TEXTURE_2D, tex);
+
+ texShader.setUniforms(ctx, texShaderID);
+ rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ dst.readViewport(ctx);
+ ctx.disable(gl.DEPTH_TEST);
+ ctx.disable(gl.STENCIL_TEST);
+ ctx.disable(gl.BLEND);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} colorFmt
+ * @param {number} depthStencilFmt
+ * @param {number} invalidateBuffers
+ */
+es3fFboInvalidateTests.InvalidateFboRenderCase = function(name, desc, colorFmt, depthStencilFmt, invalidateBuffers) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_colorFmt = colorFmt;
+ this.m_depthStencilFmt = depthStencilFmt;
+ this.m_invalidateBuffers = invalidateBuffers;
+};
+
+setParentClass(es3fFboInvalidateTests.InvalidateFboRenderCase, es3fFboTestCase.FboTestCase);
+
+es3fFboInvalidateTests.InvalidateFboRenderCase.prototype.preCheck = function() {
+ if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
+ if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
+ return true; // No exception thrown
+};
+
+es3fFboInvalidateTests.InvalidateFboRenderCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var colorFmt = gluTextureUtil.mapGLInternalFormat(this.m_colorFmt);
+ var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
+ var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
+ var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
+ var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
+ var cBias = colorFmtInfo.valueMin;
+ var cScale = deMath.subtract(colorFmtInfo.valueMax, colorFmtInfo.valueMin);
+ var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
+ var flatShaderID = ctx.createProgram(flatShader);
+
+ // Create fbo.
+ var colorRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_colorFmt, this.getWidth(), this.getHeight());
+
+ if (this.m_depthStencilFmt != gl.NONE) {
+ var depthStencilRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_depthStencilFmt, this.getWidth(), this.getHeight());
+ }
+
+ var fbo = ctx.createFramebuffer();
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
+
+ if (depth)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
+
+ if (stencil)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
+
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.clearColor(0, 0, 0, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
+ ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
+
+ flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([1, 0, 0, 1], cScale), cBias));
+ rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, -1], [1, 1, 1]);
+
+ ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);
+
+ if ((this.m_invalidateBuffers & gl.COLOR_BUFFER_BIT) != 0) {
+ // Color was not preserved - fill with green.
+ ctx.disable(gl.DEPTH_TEST);
+ ctx.disable(gl.STENCIL_TEST);
+
+ flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([0, 1, 0, 1], cScale), cBias));
+ rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ }
+
+ if ((this.m_invalidateBuffers & gl.DEPTH_BUFFER_BIT) != 0) {
+ // Depth was not preserved.
+ ctx.depthFunc(gl.ALWAYS);
+ }
+
+ if ((this.m_invalidateBuffers & gl.STENCIL_BUFFER_BIT) == 0) {
+ // Stencil was preserved.
+ ctx.stencilFunc(gl.EQUAL, 1, 0xff);
+ }
+
+ ctx.enable(gl.BLEND);
+ ctx.blendFunc(gl.ONE, gl.ONE);
+ ctx.blendEquation(gl.FUNC_ADD);
+
+ flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([0, 0, 1, 1], cScale), cBias));
+ rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ es3fFboTestUtil.readPixels(ctx, dst, 0, 0, this.getWidth(), this.getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} colorFmt
+ * @param {number} depthStencilFmt
+ * @param {number} invalidateBuffers
+ */
+es3fFboInvalidateTests.InvalidateFboUnbindReadCase = function(name, desc, colorFmt, depthStencilFmt, invalidateBuffers) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_colorFmt = colorFmt;
+ this.m_depthStencilFmt = depthStencilFmt;
+ this.m_invalidateBuffers = invalidateBuffers;
+};
+
+setParentClass(es3fFboInvalidateTests.InvalidateFboUnbindReadCase, es3fFboTestCase.FboTestCase);
+
+es3fFboInvalidateTests.InvalidateFboUnbindReadCase.prototype.preCheck = function() {
+ if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
+ if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
+ return true; // No exception thrown
+};
+
+es3fFboInvalidateTests.InvalidateFboUnbindReadCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var colorFmt = gluTextureUtil.mapGLInternalFormat(this.m_colorFmt);
+ var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
+ var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
+ var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
+ var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
+ var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
+ // Create fbo.
+ var transferFmt = gluTextureUtil.getTransferFormat(colorFmt);
+ var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var gradShaderID = ctx.createProgram(gradShader);
+
+ var colorTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, colorTex);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_colorFmt, this.getWidth(), this.getHeight(), 0, transferFmt.format, transferFmt.dataType, null);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+
+ if (this.m_depthStencilFmt != gl.NONE) {
+ transferFmt = gluTextureUtil.getTransferFormat(depthStencilFmt);
+
+ var depthStencilTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, depthStencilTex);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_depthStencilFmt, this.getWidth(), this.getHeight(), 0, transferFmt.format, transferFmt.dataType, null);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ }
+
+ var fbo = ctx.createFramebuffer();
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTex, 0);
+
+ if (depth)
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);
+
+ if (stencil)
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);
+
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.clearColor(0, 0, 0, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
+ ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
+
+ gradShader.setGradient(ctx, gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
+ rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, -1], [1, 1, 1]);
+
+ ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
+ ctx.disable(gl.DEPTH_TEST);
+ ctx.disable(gl.STENCIL_TEST);
+
+ if ((this.m_invalidateBuffers & gl.DEPTH_BUFFER_BIT) != 0) {
+ // Render color.
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluTextureUtil.getSampler2DType(colorFmt)], gluShaderUtil.DataType.FLOAT_VEC4);
+ var texShaderID = ctx.createProgram(texShader);
+
+ texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
+ texShader.setUniforms(ctx, texShaderID);
+
+ ctx.bindTexture(gl.TEXTURE_2D, colorTex);
+ rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
+ } else {
+ // Render depth.
+ texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluTextureUtil.getSampler2DType(depthStencilFmt)], gluShaderUtil.DataType.FLOAT_VEC4);
+ texShaderID = ctx.createProgram(texShader);
+
+ texShader.setUniforms(ctx, texShaderID);
+
+ ctx.bindTexture(gl.TEXTURE_2D, depthStencilTex);
+ rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
+ }
+
+ dst.readViewport(ctx);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} numSamples
+ * @param {number} invalidateBuffers
+ */
+es3fFboInvalidateTests.InvalidateFboUnbindBlitCase = function(name, desc, numSamples, invalidateBuffers) {
+// \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its
+// behing-the-scenes viewport position randomization, because with glBlitFramebuffer,
+// source and destination rectangles must match when multisampling.
+ es3fFboTestCase.FboTestCase.call(this, name, desc, numSamples > 0);
+ this.m_numSamples = numSamples;
+ this.m_colorFmt = getCompatibleColorFormat();
+ this.m_depthStencilFmt = getCompatibleDepthStencilFormat();
+ this.m_invalidateBuffers = invalidateBuffers;
+};
+
+setParentClass(es3fFboInvalidateTests.InvalidateFboUnbindBlitCase, es3fFboTestCase.FboTestCase);
+
+es3fFboInvalidateTests.InvalidateFboUnbindBlitCase.prototype.preCheck = function() {
+ if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
+ if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
+ return true; // No exception thrown
+};
+
+es3fFboInvalidateTests.InvalidateFboUnbindBlitCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var quadSizePixels = [this.m_numSamples == 0 ? this.getWidth() : Math.min(128, this.getWidth()),
+ this.m_numSamples == 0 ? this.getHeight() : Math.min(128, this.getHeight())];
+ var quadNDCLeftBottomXY = [-1, -1];
+ var quadNDCSize = [2 * quadSizePixels[0] / this.getWidth(), 2 * quadSizePixels[1] / this.getHeight()];
+ var quadNDCRightTopXY = deMath.add(quadNDCLeftBottomXY, quadNDCSize);
+ var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
+ var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
+ var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
+ var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
+ var flatShaderID = ctx.createProgram(flatShader);
+
+ ctx.clearColor(0, 0, 0, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ // Create fbo.
+ var colorRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
+ ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_colorFmt, quadSizePixels[0], quadSizePixels[1]);
+
+ if (this.m_depthStencilFmt != gl.NONE) {
+ var depthStencilRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
+ ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_depthStencilFmt, quadSizePixels[0], quadSizePixels[1]);
+ }
+
+ var fbo = ctx.createFramebuffer();
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
+
+ if (depth)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
+
+ if (stencil)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
+
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
+ ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
+
+ flatShader.setColor(ctx, flatShaderID, [1, 0, 0, 1]);
+ rrUtil.drawQuad(ctx, flatShaderID,
+ [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], -1],
+ [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 1]);
+
+ ctx.invalidateFramebuffer(gl.FRAMEBUFFER, attachments);
+
+ // Set default framebuffer as draw framebuffer and blit preserved buffers.
+ ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ ctx.blitFramebuffer(0, 0, quadSizePixels[0], quadSizePixels[1],
+ 0, 0, quadSizePixels[0], quadSizePixels[1],
+ (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT) & ~this.m_invalidateBuffers, gl.NEAREST);
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+
+ if ((this.m_invalidateBuffers & gl.COLOR_BUFFER_BIT) != 0) {
+ // Color was not preserved - fill with green.
+ ctx.disable(gl.DEPTH_TEST);
+ ctx.disable(gl.STENCIL_TEST);
+
+ flatShader.setColor(ctx, flatShaderID, [0, 1, 0, 1]);
+ rrUtil.drawQuad(ctx, flatShaderID,
+ [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], 0],
+ [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 0]);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ }
+
+ if ((this.m_invalidateBuffers & gl.DEPTH_BUFFER_BIT) != 0) {
+ // Depth was not preserved.
+ ctx.depthFunc(gl.ALWAYS);
+ }
+
+ if ((this.m_invalidateBuffers & gl.STENCIL_BUFFER_BIT) == 0) {
+ // Stencil was preserved.
+ ctx.stencilFunc(gl.EQUAL, 1, 0xff);
+ }
+
+ ctx.enable(gl.BLEND);
+ ctx.blendFunc(gl.ONE, gl.ONE);
+ ctx.blendEquation(gl.FUNC_ADD);
+
+ flatShader.setColor(ctx, flatShaderID, [0, 0, 1, 1]);
+ rrUtil.drawQuad(ctx, flatShaderID,
+ [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], 0],
+ [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 0]);
+
+ dst.readViewport(ctx, [0, 0, quadSizePixels[0], quadSizePixels[1]]);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} colorFmt
+ * @param {number} depthStencilFmt
+ * @param {number} invalidateBuffers
+ */
+es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase = function(name, desc, colorFmt, depthStencilFmt, invalidateBuffers) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_colorFmt = colorFmt;
+ this.m_depthStencilFmt = depthStencilFmt;
+ this.m_invalidateBuffers = invalidateBuffers;
+};
+
+setParentClass(es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase, es3fFboTestCase.FboTestCase);
+
+es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase.prototype.preCheck = function() {
+ if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
+ if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
+ return true; // No exception thrown
+};
+
+es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase.prototype.compare = function(reference, result) {
+ var threshold = tcuRGBA.max(es3fFboTestUtil.getFormatThreshold(this.m_colorFmt), new tcuRGBA.RGBA([12, 12, 12, 12]));
+ return tcuImageCompare.bilinearCompare('Result', 'Image comparison result', reference.getAccess(), result.getAccess(), threshold);
+};
+
+es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var colorFmt = gluTextureUtil.mapGLInternalFormat(this.m_colorFmt);
+ var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
+ var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
+ var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
+ var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
+ var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
+ // Create fbo.
+ var transferFmt = gluTextureUtil.getTransferFormat(colorFmt);
+ var gradShader = new es3fFboTestUtil.GradientShader(es3fFboTestUtil.getFragmentOutputType(colorFmt));
+ var gradShaderID = ctx.createProgram(gradShader);
+ var invalidateX = 0;
+ var invalidateY = 0;
+ var invalidateW = this.getWidth() / 2;
+ var invalidateH = this.getHeight();
+ var readX = invalidateW;
+ var readY = 0;
+ var readW = this.getWidth() / 2;
+ var readH = this.getHeight();
+
+ var colorTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, colorTex);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_colorFmt, this.getWidth(), this.getHeight(), 0, transferFmt.format, transferFmt.dataType, null);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+
+ if (this.m_depthStencilFmt != gl.NONE) {
+ transferFmt = gluTextureUtil.getTransferFormat(depthStencilFmt);
+
+ var depthStencilTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, depthStencilTex);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_depthStencilFmt, this.getWidth(), this.getHeight(), 0, transferFmt.format, transferFmt.dataType, null);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ }
+
+ var fbo = ctx.createFramebuffer();
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTex, 0);
+
+ if (depth)
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);
+
+ if (stencil)
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.TEXTURE_2D, depthStencilTex, 0);
+
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ this.clearColorBuffer(colorFmt, [0.0, 0.0, 0.0, 1.0]);
+ ctx.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
+ ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
+
+ gradShader.setGradient(ctx, gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
+ rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, -1], [1, 1, 1]);
+
+ ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
+ ctx.disable(gl.DEPTH_TEST);
+ ctx.disable(gl.STENCIL_TEST);
+
+ ctx.clearColor(0.25, 0.5, 0.75, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ // Limit read area using scissor.
+ ctx.scissor(readX, readY, readW, readH);
+ ctx.enable(gl.SCISSOR_TEST);
+
+ if ((this.m_invalidateBuffers & gl.COLOR_BUFFER_BIT) != 0) {
+ // Render color.
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluTextureUtil.getSampler2DType(colorFmt)], gluShaderUtil.DataType.FLOAT_VEC4);
+ var texShaderID = ctx.createProgram(texShader);
+
+ texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
+ texShader.setUniforms(ctx, texShaderID);
+
+ ctx.bindTexture(gl.TEXTURE_2D, colorTex);
+ rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
+ } else {
+ // Render depth.
+ texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluTextureUtil.getSampler2DType(depthStencilFmt)], gluShaderUtil.DataType.FLOAT_VEC4);
+ texShaderID = ctx.createProgram(texShader);
+
+ texShader.setUniforms(ctx, texShaderID);
+
+ ctx.bindTexture(gl.TEXTURE_2D, depthStencilTex);
+ rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
+ }
+
+ dst.readViewport(ctx);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} colorFmt
+ * @param {number} depthStencilFmt
+ * @param {number} invalidateBuffers
+ */
+es3fFboInvalidateTests.InvalidateSubFboRenderCase = function(name, desc, colorFmt, depthStencilFmt, invalidateBuffers) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_colorFmt = colorFmt;
+ this.m_depthStencilFmt = depthStencilFmt;
+ this.m_invalidateBuffers = invalidateBuffers;
+};
+
+setParentClass(es3fFboInvalidateTests.InvalidateSubFboRenderCase, es3fFboTestCase.FboTestCase);
+
+es3fFboInvalidateTests.InvalidateSubFboRenderCase.prototype.preCheck = function() {
+ if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
+ if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
+ return true; // No exception thrown
+};
+
+es3fFboInvalidateTests.InvalidateSubFboRenderCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var colorFmt = gluTextureUtil.mapGLInternalFormat(this.m_colorFmt);
+ var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
+ var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
+ var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
+ var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
+ var cBias = colorFmtInfo.valueMin;
+ var cScale = deMath.subtract(colorFmtInfo.valueMax, colorFmtInfo.valueMin);
+ var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
+ var flatShaderID = ctx.createProgram(flatShader);
+ var invalidateX = this.getWidth() / 4;
+ var invalidateY = this.getHeight() / 4;
+ var invalidateW = this.getWidth() / 2;
+ var invalidateH = this.getHeight() / 2;
+
+ // Create fbo.
+ var colorRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_colorFmt, this.getWidth(), this.getHeight());
+
+ if (this.m_depthStencilFmt != gl.NONE) {
+ var depthStencilRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_depthStencilFmt, this.getWidth(), this.getHeight());
+ }
+
+ var fbo = ctx.createFramebuffer();
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
+
+ if (depth)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
+
+ if (stencil)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
+
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.clearBufferfv(gl.COLOR, 0, deMath.add(deMath.multiply([0, 0, 0, 1], cScale), cBias));
+ ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1, 0);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
+ ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
+
+ flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([1, 0, 0, 1], cScale), cBias));
+ rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, -1], [1, 1, 1]);
+
+ ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);
+
+ // Clear invalidated buffers.
+ ctx.scissor(invalidateX, invalidateY, invalidateW, invalidateH);
+ ctx.enable(gl.SCISSOR_TEST);
+
+ if (this.m_invalidateBuffers & gl.COLOR_BUFFER_BIT)
+ ctx.clearBufferfv(gl.COLOR, 0, deMath.add(deMath.multiply([0, 1, 0, 1], cScale), cBias));
+
+ ctx.clear(this.m_invalidateBuffers & ~gl.COLOR_BUFFER_BIT);
+ ctx.disable(gl.SCISSOR_TEST);
+
+ ctx.enable(gl.BLEND);
+ ctx.blendFunc(gl.ONE, gl.ONE);
+ ctx.blendEquation(gl.FUNC_ADD);
+
+ flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([0, 0, 1, 1], cScale), cBias));
+ rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ es3fFboTestUtil.readPixels(ctx, dst, 0, 0, this.getWidth(), this.getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} numSamples
+ * @param {number} invalidateBuffers
+ */
+es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase = function(name, desc, numSamples, invalidateBuffers) {
+// \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its
+// behing-the-scenes viewport position randomization, because with glBlitFramebuffer,
+// source and destination rectangles must match when multisampling.
+ es3fFboTestCase.FboTestCase.call(this, name, desc, numSamples > 0);
+ this.m_numSamples = numSamples;
+ this.m_colorFmt = getCompatibleColorFormat();
+ this.m_depthStencilFmt = getCompatibleDepthStencilFormat();
+ this.m_invalidateBuffers = invalidateBuffers;
+};
+
+setParentClass(es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase, es3fFboTestCase.FboTestCase);
+
+es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase.prototype.preCheck = function() {
+ if (this.m_colorFmt != gl.NONE) this.checkFormatSupport(this.m_colorFmt);
+ if (this.m_depthStencilFmt != gl.NONE) this.checkFormatSupport(this.m_depthStencilFmt);
+ return true; // No exception thrown
+};
+
+es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var quadSizePixels = [this.m_numSamples == 0 ? this.getWidth() : Math.min(128, this.getWidth()),
+ this.m_numSamples == 0 ? this.getHeight() : Math.min(128, this.getHeight())];
+ var quadNDCLeftBottomXY = [-1, -1];
+ var quadNDCSize = [2 * quadSizePixels[0] / this.getWidth(), 2 * quadSizePixels[1] / this.getHeight()];
+ var quadNDCRightTopXY = deMath.add(quadNDCLeftBottomXY, quadNDCSize);
+ var depthStencilFmt = this.m_depthStencilFmt != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFmt) : new tcuTexture.TextureFormat(null, null);
+ var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
+ var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
+ var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var attachments = getFBODiscardAttachments(this.m_invalidateBuffers);
+ var flatShaderID = ctx.createProgram(flatShader);
+ var invalidateX = 0;
+ var invalidateY = 0;
+ var invalidateW = quadSizePixels[0] / 2;
+ var invalidateH = quadSizePixels[1];
+ var blitX0 = invalidateW;
+ var blitY0 = 0;
+ var blitX1 = blitX0 + quadSizePixels[0] / 2;
+ var blitY1 = blitY0 + quadSizePixels[1];
+
+ ctx.clearColor(0, 0, 0, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ // Create fbo.
+ var colorRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
+ ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_colorFmt, quadSizePixels[0], quadSizePixels[1]);
+
+ if (this.m_depthStencilFmt != gl.NONE) {
+ var depthStencilRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
+ ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_depthStencilFmt, quadSizePixels[0], quadSizePixels[1]);
+ }
+
+ var fbo = ctx.createFramebuffer();
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
+
+ if (depth)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
+
+ if (stencil)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
+
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
+ ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
+
+ flatShader.setColor(ctx, flatShaderID, [1, 0, 0, 1]);
+ rrUtil.drawQuad(ctx, flatShaderID,
+ [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], -1],
+ [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 1]);
+
+ ctx.invalidateSubFramebuffer(gl.FRAMEBUFFER, attachments, invalidateX, invalidateY, invalidateW, invalidateH);
+
+ // Set default framebuffer as draw framebuffer and blit preserved buffers.
+ ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ ctx.blitFramebuffer(blitX0, blitY0, blitX1, blitY1, blitX0, blitY0, blitX1, blitY1,
+ (gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT) & ~this.m_invalidateBuffers, gl.NEAREST);
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+
+ if ((this.m_invalidateBuffers & gl.COLOR_BUFFER_BIT) != 0) {
+ // Color was not preserved - fill with green.
+ ctx.disable(gl.DEPTH_TEST);
+ ctx.disable(gl.STENCIL_TEST);
+
+ flatShader.setColor(ctx, flatShaderID, [0, 1, 0, 1]);
+ rrUtil.drawQuad(ctx, flatShaderID,
+ [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], 0],
+ [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 0]);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ }
+
+ if ((this.m_invalidateBuffers & gl.DEPTH_BUFFER_BIT) != 0) {
+ // Depth was not preserved.
+ ctx.depthFunc(gl.ALWAYS);
+ }
+
+ if ((this.m_invalidateBuffers & gl.STENCIL_BUFFER_BIT) == 0) {
+ // Stencil was preserved.
+ ctx.stencilFunc(gl.EQUAL, 1, 0xff);
+ }
+
+ ctx.enable(gl.BLEND);
+ ctx.blendFunc(gl.ONE, gl.ONE);
+ ctx.blendEquation(gl.FUNC_ADD);
+
+ flatShader.setColor(ctx, flatShaderID, [0, 0, 1, 1]);
+ rrUtil.drawQuad(ctx, flatShaderID,
+ [quadNDCLeftBottomXY[0], quadNDCLeftBottomXY[1], 0],
+ [quadNDCRightTopXY[0], quadNDCRightTopXY[1], 0]);
+
+ dst.readViewport(ctx, [0, 0, quadSizePixels[0], quadSizePixels[1]]);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} boundTarget
+ * @param {number} invalidateTarget
+ * @param {Array<number>} invalidateAttachments
+ */
+es3fFboInvalidateTests.InvalidateFboTargetCase = function(name, desc, boundTarget, invalidateTarget, invalidateAttachments) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ this.m_boundTarget = boundTarget;
+ this.m_invalidateTarget = invalidateTarget;
+ this.m_invalidateAttachments = invalidateAttachments;
+};
+
+setParentClass(es3fFboInvalidateTests.InvalidateFboTargetCase, es3fFboTestCase.FboTestCase);
+
+es3fFboInvalidateTests.InvalidateFboTargetCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ var colorFormat = gl.RGBA8;
+ var depthStencilFormat = gl.DEPTH24_STENCIL8;
+ var colorFmt = gluTextureUtil.mapGLInternalFormat(colorFormat);
+ var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
+ var cBias = colorFmtInfo.valueMin;
+ var cScale = deMath.subtract(colorFmtInfo.valueMax, colorFmtInfo.valueMin);
+ var isDiscarded = (this.m_boundTarget == gl.FRAMEBUFFER) ||
+ (this.m_invalidateTarget == gl.FRAMEBUFFER && this.m_boundTarget == gl.DRAW_FRAMEBUFFER) ||
+ (this.m_invalidateTarget == this.m_boundTarget);
+ var isColorDiscarded = isDiscarded && hasAttachment(this.m_invalidateAttachments, gl.COLOR_ATTACHMENT0);
+ var isDepthDiscarded = isDiscarded && (hasAttachment(this.m_invalidateAttachments, gl.DEPTH_ATTACHMENT) || hasAttachment(this.m_invalidateAttachments, gl.DEPTH_STENCIL_ATTACHMENT));
+ var isStencilDiscarded = isDiscarded && (hasAttachment(this.m_invalidateAttachments, gl.STENCIL_ATTACHMENT) || hasAttachment(this.m_invalidateAttachments, gl.DEPTH_STENCIL_ATTACHMENT));
+
+ var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var flatShaderID = ctx.createProgram(flatShader);
+
+ // Create fbo.
+ var colorRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.getWidth(), this.getHeight());
+
+ var depthStencilRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, depthStencilFormat, this.getWidth(), this.getHeight());
+
+ var fbo = ctx.createFramebuffer();
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
+
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.clearColor(0, 0, 0, 1);
+ ctx.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
+ ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
+
+ flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([1, 0, 0, 1], cScale), cBias));
+ rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, -1], [1, 1, 1]);
+
+ // Bound FBO to test target and default to other
+ if (this.m_boundTarget != gl.FRAMEBUFFER) {
+ // Dummy fbo is used as complemeting target (read when discarding draw for example).
+ // \note Framework takes care of deleting objects at the end of test case.
+ var dummyTarget = this.m_boundTarget == gl.DRAW_FRAMEBUFFER ? gl.READ_FRAMEBUFFER : gl.DRAW_FRAMEBUFFER;
+
+ var dummyColorRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, dummyColorRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 64, 64);
+ var dummyFbo = ctx.createFramebuffer();
+ ctx.bindFramebuffer(dummyTarget, dummyFbo);
+ ctx.framebufferRenderbuffer(dummyTarget, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, dummyColorRbo);
+
+ ctx.bindFramebuffer(this.m_boundTarget, fbo);
+ }
+
+ ctx.invalidateFramebuffer(this.m_invalidateTarget, this.m_invalidateAttachments);
+
+ if (this.m_boundTarget != gl.FRAMEBUFFER)
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ if (isColorDiscarded) {
+ // Color was not preserved - fill with green.
+ ctx.disable(gl.DEPTH_TEST);
+ ctx.disable(gl.STENCIL_TEST);
+
+ flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([0, 1, 0, 1], cScale), cBias));
+ rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ }
+
+ if (isDepthDiscarded) {
+ // Depth was not preserved.
+ ctx.depthFunc(gl.ALWAYS);
+ }
+
+ if (!isStencilDiscarded) {
+ // Stencil was preserved.
+ ctx.stencilFunc(gl.EQUAL, 1, 0xff);
+ }
+
+ ctx.enable(gl.BLEND);
+ ctx.blendFunc(gl.ONE, gl.ONE);
+ ctx.blendEquation(gl.FUNC_ADD);
+
+ flatShader.setColor(ctx, flatShaderID, deMath.add(deMath.multiply([0, 0, 1, 1], cScale), cBias));
+ rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ es3fFboTestUtil.readPixels(ctx, dst, 0, 0, this.getWidth(), this.getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
+};
+
+/**
+* @constructor
+* @extends {tcuTestCase.DeqpTest}
+*/
+es3fFboInvalidateTests.FboInvalidateTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'invalidate', 'Framebuffer invalidate tests');
+};
+
+es3fFboInvalidateTests.FboInvalidateTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fFboInvalidateTests.FboInvalidateTests.prototype.constructor = es3fFboInvalidateTests.FboInvalidateTests;
+
+es3fFboInvalidateTests.FboInvalidateTests.prototype.init = function() {
+ var defaultFbGroup = new tcuTestCase.DeqpTest('default', 'Default framebuffer invalidate tests');
+ this.addChild(defaultFbGroup);
+
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_none', 'Invalidating no framebuffers (ref)', 0));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_color', 'Rendering after invalidating colorbuffer', gl.COLOR_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_depth', 'Rendering after invalidating depthbuffer', gl.DEPTH_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_stencil', 'Rendering after invalidating stencilbuffer', gl.STENCIL_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_depth_stencil', 'Rendering after invalidating depth- and stencilbuffers', gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('render_all', 'Rendering after invalidating all buffers', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase('bind_color', 'Binding fbo after invalidating colorbuffer', gl.COLOR_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase('bind_depth', 'Binding fbo after invalidating depthbuffer', gl.DEPTH_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase('bind_stencil', 'Binding fbo after invalidating stencilbuffer', gl.STENCIL_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase('bind_depth_stencil', 'Binding fbo after invalidating depth- and stencilbuffers', gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferBindCase('bind_all', 'Binding fbo after invalidating all buffers', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase('sub_render_color', 'Rendering after invalidating colorbuffer', gl.COLOR_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase('sub_render_depth', 'Rendering after invalidating depthbuffer', gl.DEPTH_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase('sub_render_stencil', 'Rendering after invalidating stencilbuffer', gl.STENCIL_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase('sub_render_depth_stencil', 'Rendering after invalidating depth- and stencilbuffers', gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferRenderCase('sub_render_all', 'Rendering after invalidating all buffers', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase('sub_bind_color', 'Binding fbo after invalidating colorbuffer', gl.COLOR_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase('sub_bind_depth', 'Binding fbo after invalidating depthbuffer', gl.DEPTH_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase('sub_bind_stencil', 'Binding fbo after invalidating stencilbuffer', gl.STENCIL_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase('sub_bind_depth_stencil', 'Binding fbo after invalidating depth- and stencilbuffers', gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultSubFramebufferBindCase('sub_bind_all', 'Binding fbo after invalidating all buffers', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('draw_framebuffer_color', 'Invalidating gl.COLOR in gl.DRAW_FRAMEBUFFER', gl.COLOR_BUFFER_BIT, gl.DRAW_FRAMEBUFFER));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('draw_framebuffer_all', 'Invalidating all in gl.DRAW_FRAMEBUFFER', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT, gl.DRAW_FRAMEBUFFER));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('read_framebuffer_color', 'Invalidating gl.COLOR in gl.READ_FRAMEBUFFER', gl.COLOR_BUFFER_BIT, gl.READ_FRAMEBUFFER));
+ defaultFbGroup.addChild(new es3fFboInvalidateTests.InvalidateDefaultFramebufferRenderCase('read_framebuffer_all', 'Invalidating all in gl.READ_FRAMEBUFFER', gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT, gl.READ_FRAMEBUFFER));
+
+ // invalidate.whole.
+ var wholeFboGroup = new tcuTestCase.DeqpTest('whole', 'Invalidating whole framebuffer object');
+ this.addChild(wholeFboGroup);
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_none', '', gl.RGBA8, gl.DEPTH24_STENCIL8, 0));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_color', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_depth', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.STENCIL_BUFFER_BIT));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_depth_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboRenderCase('render_all', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindReadCase('unbind_read_color', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindReadCase('unbind_read_depth', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindReadCase('unbind_read_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.STENCIL_BUFFER_BIT));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindReadCase('unbind_read_depth_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindReadCase('unbind_read_color_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+
+ if (getCompatibleDepthStencilFormat() !== gl.NONE) {
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_color', '', 0, gl.COLOR_BUFFER_BIT));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_depth', '', 0, gl.DEPTH_BUFFER_BIT));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_stencil', '', 0, gl.STENCIL_BUFFER_BIT));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_depth_stencil', '', 0, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_msaa_color', '', 4, gl.COLOR_BUFFER_BIT));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_msaa_depth', '', 4, gl.DEPTH_BUFFER_BIT));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_msaa_stencil', '', 4, gl.STENCIL_BUFFER_BIT));
+ wholeFboGroup.addChild(new es3fFboInvalidateTests.InvalidateFboUnbindBlitCase('unbind_blit_msaa_depth_stencil', '', 4, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ }
+
+ // invalidate.sub.
+ var subFboGroup = new tcuTestCase.DeqpTest('sub', 'Invalidating subsection of framebuffer object');
+ this.addChild(subFboGroup);
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_none', '', gl.RGBA8, gl.DEPTH24_STENCIL8, 0));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_color', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_depth', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.STENCIL_BUFFER_BIT));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_depth_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase('render_all', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase('unbind_read_color', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase('unbind_read_depth', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase('unbind_read_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.STENCIL_BUFFER_BIT));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase('unbind_read_depth_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase('unbind_read_color_stencil', '', gl.RGBA8, gl.DEPTH24_STENCIL8, gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+
+ if (getCompatibleDepthStencilFormat() !== gl.NONE) {
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_color', '', 0, gl.COLOR_BUFFER_BIT));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_depth', '', 0, gl.DEPTH_BUFFER_BIT));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_stencil', '', 0, gl.STENCIL_BUFFER_BIT));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_depth_stencil', '', 0, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_msaa_color', '', 4, gl.COLOR_BUFFER_BIT));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_msaa_depth', '', 4, gl.DEPTH_BUFFER_BIT));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_msaa_stencil', '', 4, gl.STENCIL_BUFFER_BIT));
+ subFboGroup.addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindBlitCase('unbind_blit_msaa_depth_stencil', '', 4, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+ }
+ // invalidate.format.
+ var numFormatSubGroups = 3;
+ var formatGroup = [];
+ for (var ii = 0; ii < numFormatSubGroups; ++ii) {
+ formatGroup[ii] = new tcuTestCase.DeqpTest('format', 'Invalidating framebuffers with selected formats');
+ this.addChild(formatGroup[ii]);
+ }
+ // Color buffer formats.
+ var colorFormats = [
+ // RGBA formats
+ gl.RGBA32I,
+ gl.RGBA32UI,
+ gl.RGBA16I,
+ gl.RGBA16UI,
+ gl.RGBA8,
+ gl.RGBA8I,
+ gl.RGBA8UI,
+ gl.SRGB8_ALPHA8,
+ gl.RGB10_A2,
+ gl.RGB10_A2UI,
+ gl.RGBA4,
+ gl.RGB5_A1,
+
+ // RGB formats
+ gl.RGB8,
+ gl.RGB565,
+
+ // RG formats
+ gl.RG32I,
+ gl.RG32UI,
+ gl.RG16I,
+ gl.RG16UI,
+ gl.RG8,
+ gl.RG8I,
+ gl.RG8UI,
+
+ // R formats
+ gl.R32I,
+ gl.R32UI,
+ gl.R16I,
+ gl.R16UI,
+ gl.R8,
+ gl.R8I,
+ gl.R8UI,
+
+ // gl.EXT_color_buffer_float
+ gl.RGBA32F,
+ gl.RGBA16F,
+ gl.R11F_G11F_B10F,
+ gl.RG32F,
+ gl.RG16F,
+ gl.R32F,
+ gl.R16F
+ ];
+
+ // Depth/stencilbuffer formats.
+ var depthStencilFormats = [
+ gl.DEPTH_COMPONENT32F,
+ gl.DEPTH_COMPONENT24,
+ gl.DEPTH_COMPONENT16,
+ gl.DEPTH32F_STENCIL8,
+ gl.DEPTH24_STENCIL8,
+ gl.STENCIL_INDEX8
+ ];
+
+ // Colorbuffer tests use invalidate, unbind, read test.
+ for (var ndx = 0; ndx < colorFormats.length; ndx++)
+ formatGroup[ndx % numFormatSubGroups].addChild(new es3fFboInvalidateTests.InvalidateSubFboUnbindReadCase(es3fFboTestUtil.getFormatName(colorFormats[ndx]), '', colorFormats[ndx], gl.NONE, gl.COLOR_BUFFER_BIT));
+
+ // Depth/stencilbuffer tests use invalidate, render test.
+ for (var ndx = 0; ndx < depthStencilFormats.length; ndx++)
+ formatGroup[ndx % numFormatSubGroups].addChild(new es3fFboInvalidateTests.InvalidateSubFboRenderCase(es3fFboTestUtil.getFormatName(depthStencilFormats[ndx]), '', gl.RGBA8, depthStencilFormats[ndx], gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT));
+
+ // invalidate.target
+ var targetGroup = new tcuTestCase.DeqpTest('target', 'Invalidate target');
+ this.addChild(targetGroup);
+
+ var s_targetCases = [
+ ['framebuffer_framebuffer', gl.FRAMEBUFFER, gl.FRAMEBUFFER],
+ ['framebuffer_read_framebuffer', gl.FRAMEBUFFER, gl.READ_FRAMEBUFFER],
+ ['framebuffer_draw_framebuffer', gl.FRAMEBUFFER, gl.DRAW_FRAMEBUFFER],
+ ['read_framebuffer_framebuffer', gl.READ_FRAMEBUFFER, gl.FRAMEBUFFER],
+ ['read_framebuffer_read_framebuffer', gl.READ_FRAMEBUFFER, gl.READ_FRAMEBUFFER],
+ ['read_framebuffer_draw_framebuffer', gl.READ_FRAMEBUFFER, gl.DRAW_FRAMEBUFFER],
+ ['draw_framebuffer_framebuffer', gl.DRAW_FRAMEBUFFER, gl.FRAMEBUFFER],
+ ['draw_framebuffer_read_framebuffer', gl.DRAW_FRAMEBUFFER, gl.READ_FRAMEBUFFER],
+ ['draw_framebuffer_draw_framebuffer', gl.DRAW_FRAMEBUFFER, gl.DRAW_FRAMEBUFFER]
+ ];
+
+ var colorAttachment = [gl.COLOR_ATTACHMENT0];
+ var depthStencilAttachment = [gl.DEPTH_STENCIL_ATTACHMENT];
+ var allAttachments = [gl.COLOR_ATTACHMENT0, gl.DEPTH_ATTACHMENT, gl.STENCIL_ATTACHMENT];
+
+ for (var caseNdx = 0; caseNdx < s_targetCases.length; caseNdx++) {
+ var baseName = s_targetCases[caseNdx][0];
+ var invalidateT = s_targetCases[caseNdx][1];
+ var boundT = s_targetCases[caseNdx][1];
+
+ targetGroup.addChild(new es3fFboInvalidateTests.InvalidateFboTargetCase(baseName + '_color', '', boundT, invalidateT, colorAttachment));
+ targetGroup.addChild(new es3fFboInvalidateTests.InvalidateFboTargetCase(baseName + '_depth_stencil', '', boundT, invalidateT, depthStencilAttachment));
+ targetGroup.addChild(new es3fFboInvalidateTests.InvalidateFboTargetCase(baseName + '_all', '', boundT, invalidateT, allAttachments));
+ }
+
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fFboInvalidateTests.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fFboInvalidateTests.FboInvalidateTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fFboInvalidateTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboMultisampleTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboMultisampleTests.js
new file mode 100644
index 0000000000..261da00734
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboMultisampleTests.js
@@ -0,0 +1,377 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fFboMultisampleTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('framework.referencerenderer.rrUtil');
+goog.require('functional.gles3.es3fFboTestCase');
+goog.require('functional.gles3.es3fFboTestUtil');
+
+goog.scope(function() {
+
+var es3fFboMultisampleTests = functional.gles3.es3fFboMultisampleTests;
+var es3fFboTestCase = functional.gles3.es3fFboTestCase;
+var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
+var tcuTestCase = framework.common.tcuTestCase;
+var tcuSurface = framework.common.tcuSurface;
+var tcuRGBA = framework.common.tcuRGBA;
+var tcuImageCompare = framework.common.tcuImageCompare;
+var tcuTexture = framework.common.tcuTexture;
+var tcuTextureUtil = framework.common.tcuTextureUtil;
+var deRandom = framework.delibs.debase.deRandom;
+var deMath = framework.delibs.debase.deMath;
+var gluTextureUtil = framework.opengl.gluTextureUtil;
+var rrUtil = framework.referencerenderer.rrUtil;
+
+/** @type {WebGL2RenderingContext} */ var gl;
+
+var DE_ASSERT = function(x) {
+ if (!x)
+ throw new Error('Assert failed');
+};
+
+ /**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} colorFormat
+ * @param {number} depthStencilFormat
+ * @param {Array<number>} size
+ * @param {number} numSamples
+ */
+ es3fFboMultisampleTests.BasicFboMultisampleCase = function(name, desc, colorFormat, depthStencilFormat, size, numSamples) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ /** @type {number} */ this.m_colorFormat = colorFormat;
+ /** @type {number} */ this.m_depthStencilFormat = depthStencilFormat;
+ /** @type {Array<number>} */ this.m_size = size;
+ /** @type {number} */ this.m_numSamples = numSamples;
+ };
+
+ es3fFboMultisampleTests.BasicFboMultisampleCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
+ es3fFboMultisampleTests.BasicFboMultisampleCase.prototype.constructor = es3fFboMultisampleTests.BasicFboMultisampleCase;
+
+ es3fFboMultisampleTests.BasicFboMultisampleCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_colorFormat);
+ if (!this.checkSampleCount(this.m_colorFormat, this.m_numSamples))
+ return false;
+
+ if (this.m_depthStencilFormat != gl.NONE) {
+ this.checkFormatSupport(this.m_depthStencilFormat);
+ if (!this.checkSampleCount(this.m_depthStencilFormat, this.m_numSamples))
+ return false;
+ }
+ return true; // No exception thrown
+ };
+
+ /**
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFboMultisampleTests.BasicFboMultisampleCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ /** @type {tcuTexture.TextureFormat} */ var colorFmt = gluTextureUtil.mapGLInternalFormat(this.m_colorFormat);
+ /** @type {tcuTexture.TextureFormat} */ var depthStencilFmt = this.m_depthStencilFormat != gl.NONE ? gluTextureUtil.mapGLInternalFormat(this.m_depthStencilFormat) : new tcuTexture.TextureFormat(null, null);
+ /** @type {tcuTextureUtil.TextureFormatInfo} */ var colorFmtInfo = tcuTextureUtil.getTextureFormatInfo(colorFmt);
+ /** @type {boolean} */ var depth = depthStencilFmt.order == tcuTexture.ChannelOrder.D || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
+ /** @type {boolean} */ var stencil = depthStencilFmt.order == tcuTexture.ChannelOrder.S || depthStencilFmt.order == tcuTexture.ChannelOrder.DS;
+ /** @type {es3fFboTestUtil.GradientShader} */ var gradShader = new es3fFboTestUtil.GradientShader(es3fFboTestUtil.getFragmentOutputType(colorFmt));
+ /** @type {es3fFboTestUtil.FlatColorShader} */ var flatShader = new es3fFboTestUtil.FlatColorShader(es3fFboTestUtil.getFragmentOutputType(colorFmt));
+ var gradShaderID = this.getCurrentContext().createProgram(gradShader);
+ var flatShaderID = this.getCurrentContext().createProgram(flatShader);
+ var msaaFbo = null;
+ var resolveFbo = null;
+ var msaaColorRbo = null;
+ var resolveColorRbo = null;
+ var msaaDepthStencilRbo = null;
+ var resolveDepthStencilRbo = null;
+
+ // Create framebuffers.
+ msaaColorRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, msaaColorRbo);
+ ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_colorFormat, this.m_size[0], this.m_size[1]);
+
+ if (depth || stencil) {
+ msaaDepthStencilRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, msaaDepthStencilRbo);
+ ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, this.m_depthStencilFormat, this.m_size[0], this.m_size[1]);
+ }
+
+ msaaFbo = ctx.createFramebuffer();
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, msaaFbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msaaColorRbo);
+ if (depth)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, msaaDepthStencilRbo);
+ if (stencil)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, msaaDepthStencilRbo);
+
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ resolveColorRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, resolveColorRbo);
+ ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, 0, this.m_colorFormat, this.m_size[0], this.m_size[1]);
+
+ if (depth || stencil) {
+ resolveDepthStencilRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, resolveDepthStencilRbo);
+ ctx.renderbufferStorageMultisample(gl.RENDERBUFFER, 0, this.m_depthStencilFormat, this.m_size[0], this.m_size[1]);
+ }
+
+ resolveFbo = ctx.createFramebuffer();
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, resolveFbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, resolveColorRbo);
+ if (depth)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, resolveDepthStencilRbo);
+ if (stencil)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, resolveDepthStencilRbo);
+
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, msaaFbo);
+ ctx.viewport(0, 0, this.m_size[0], this.m_size[1]);
+
+ // Clear depth and stencil buffers.
+ ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0);
+
+ // Fill MSAA fbo with gradient, depth = [-1..1]
+ ctx.enable(gl.DEPTH_TEST);
+ gradShader.setGradient(this.getCurrentContext(), gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax);
+
+ rrUtil.drawQuad(this.getCurrentContext(), gradShaderID, [-1.0, -1.0, -1.0], [1.0, 1.0, 1.0]);
+
+ // Render random-colored quads.
+ /** @const {number} */ var numQuads = 8;
+
+ // The choice of random seed affects the correctness of the tests,
+ // because there are some boundary conditions which aren't handled
+ // correctly even in the C++ dEQP tests.
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(7);
+
+ ctx.depthFunc(gl.ALWAYS);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilFunc(gl.ALWAYS, 0, 0xff);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);
+
+ for (var ndx = 0; ndx < numQuads; ndx++) {
+ /** @type {number} */ var r = rnd.getFloat();
+ /** @type {number} */ var g = rnd.getFloat();
+ /** @type {number} */ var b = rnd.getFloat();
+ /** @type {number} */ var a = rnd.getFloat();
+ /** @type {number} */ var x0 = rnd.getFloat(-1.0, 1.0);
+ /** @type {number} */ var y0 = rnd.getFloat(-1.0, 1.0);
+ /** @type {number} */ var z0 = rnd.getFloat(-1.0, 1.0);
+ /** @type {number} */ var x1 = rnd.getFloat(-1.0, 1.0);
+ /** @type {number} */ var y1 = rnd.getFloat(-1.0, 1.0);
+ /** @type {number} */ var z1 = rnd.getFloat(-1.0, 1.0);
+
+ flatShader.setColor(this.getCurrentContext(), flatShaderID, deMath.add(deMath.multiply([r, g, b, a], deMath.subtract(colorFmtInfo.valueMax, colorFmtInfo.valueMin)), colorFmtInfo.valueMin));
+ rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [x0, y0, z0], [x1, y1, z1]);
+ }
+
+ ctx.disable(gl.DEPTH_TEST);
+ ctx.disable(gl.STENCIL_TEST);
+ this.checkError();
+
+ // Resolve using glBlitFramebuffer().
+ ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, resolveFbo);
+ ctx.blitFramebuffer(0, 0, this.m_size[0], this.m_size[1], 0, 0, this.m_size[0], this.m_size[1], gl.COLOR_BUFFER_BIT | (depth ? gl.DEPTH_BUFFER_BIT : 0) | (stencil ? gl.STENCIL_BUFFER_BIT : 0), gl.NEAREST);
+
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, resolveFbo);
+
+ /** @type {number} */ var numSteps;
+ /** @type {number} */ var step;
+ /** @type {number} */ var d;
+ /** @type {number} */ var c;
+ /** @type {number} */ var s;
+ if (depth) {
+ // Visualize depth.
+ numSteps = 8;
+ step = 2.0 / numSteps;
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.depthFunc(gl.LESS);
+ ctx.depthMask(false);
+ ctx.colorMask(false, false, true, false);
+
+ for (var ndx = 0; ndx < numSteps; ndx++) {
+ d = -1.0 + step * ndx;
+ c = ndx / (numSteps - 1);
+
+ flatShader.setColor(this.getCurrentContext(), flatShaderID, deMath.add(deMath.multiply([0.0, 0.0, c, 1.0], deMath.subtract(colorFmtInfo.valueMax, colorFmtInfo.valueMin)), colorFmtInfo.valueMin));
+ rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-1.0, -1.0, d], [1.0, 1.0, d]);
+ }
+
+ ctx.disable(gl.DEPTH_TEST);
+ }
+
+ if (stencil) {
+ // Visualize stencil.
+ numSteps = 4;
+ step = 1;
+
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
+ ctx.colorMask(false, true, false, false);
+
+ for (var ndx = 0; ndx < numSteps; ndx++) {
+ s = step * ndx;
+ c = ndx / (numSteps - 1);
+
+ ctx.stencilFunc(gl.EQUAL, s, 0xff);
+
+ flatShader.setColor(this.getCurrentContext(), flatShaderID, deMath.add(deMath.multiply([0.0, c, 0.0, 1.0], deMath.subtract(colorFmtInfo.valueMax, colorFmtInfo.valueMin)), colorFmtInfo.valueMin));
+ rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]);
+ }
+
+ ctx.disable(gl.STENCIL_TEST);
+ }
+
+ this.readPixelsUsingFormat(dst, 0, 0, this.m_size[0], this.m_size[1], colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias);
+ };
+
+ /**
+ * @param {tcuSurface.Surface} reference
+ * @param {tcuSurface.Surface} result
+ * @return {boolean}
+ */
+ es3fFboMultisampleTests.BasicFboMultisampleCase.prototype.colorCompare = function(reference, result) {
+ /** @const {tcuRGBA.RGBA} */ var threshold = tcuRGBA.max(es3fFboTestUtil.getFormatThreshold(this.m_colorFormat), tcuRGBA.newRGBAComponents(12, 12, 12, 12));
+ return tcuImageCompare.bilinearCompare('Result', 'Image comparison result', reference.getAccess(), result.getAccess(), threshold, tcuImageCompare.CompareLogMode.RESULT);
+ };
+
+ /**
+ * @param {tcuSurface.Surface} reference
+ * @param {tcuSurface.Surface} result
+ * @return {boolean}
+ */
+ es3fFboMultisampleTests.BasicFboMultisampleCase.prototype.compare = function(reference, result) {
+ if (this.m_depthStencilFormat != gl.NONE)
+ return es3fFboTestCase.FboTestCase.prototype.compare(reference, result); // FboTestCase.compare
+ else
+ return this.colorCompare(reference, result);
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fFboMultisampleTests.FboMultisampleTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'msaa', 'Multisample FBO tests');
+ };
+
+ es3fFboMultisampleTests.FboMultisampleTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fFboMultisampleTests.FboMultisampleTests.prototype.constructor = es3fFboMultisampleTests.FboMultisampleTests;
+
+ es3fFboMultisampleTests.FboMultisampleTests.prototype.init = function() {
+ /** @const {Array<number>} */ var colorFormats = [
+ // RGBA formats
+ gl.RGBA8,
+ gl.SRGB8_ALPHA8,
+ gl.RGB10_A2,
+ gl.RGBA4,
+ gl.RGB5_A1,
+
+ // RGB formats
+ gl.RGB8,
+ gl.RGB565,
+
+ // RG formats
+ gl.RG8,
+
+ // R formats
+ gl.R8,
+
+ // gl.EXT_color_buffer_float
+ // Multi-sample floating-point color buffers can be optional supported, see https://www.khronos.org/registry/webgl/extensions/EXT_color_buffer_float/
+ gl.RGBA32F,
+ gl.RGBA16F,
+ gl.R11F_G11F_B10F,
+ gl.RG32F,
+ gl.RG16F,
+ gl.R32F,
+ gl.R16F
+ ];
+
+ /** @const {Array<number>} */ var depthStencilFormats = [
+ gl.DEPTH_COMPONENT32F,
+ gl.DEPTH_COMPONENT24,
+ gl.DEPTH_COMPONENT16,
+ gl.DEPTH32F_STENCIL8,
+ gl.DEPTH24_STENCIL8,
+ gl.STENCIL_INDEX8
+ ];
+
+ /** @const {Array<number>} */ var sampleCounts = [2, 4, 8];
+
+ for (var sampleCntNdx in sampleCounts) {
+ /** @type {number} */ var samples = sampleCounts[sampleCntNdx];
+ /** @type {tcuTestCase.DeqpTest} */
+ var sampleCountGroup = tcuTestCase.newTest(samples + '_samples', '');
+ this.addChild(sampleCountGroup);
+
+ // Color formats.
+ for (var fmtNdx in colorFormats)
+ sampleCountGroup.addChild(new es3fFboMultisampleTests.BasicFboMultisampleCase(es3fFboTestUtil.getFormatName(colorFormats[fmtNdx]), '', colorFormats[fmtNdx], gl.NONE, [119, 131], samples));
+
+ // Depth/stencil formats.
+ for (var fmtNdx in depthStencilFormats)
+ sampleCountGroup.addChild(new es3fFboMultisampleTests.BasicFboMultisampleCase(es3fFboTestUtil.getFormatName(depthStencilFormats[fmtNdx]), '', gl.RGBA8, depthStencilFormats[fmtNdx], [119, 131], samples));
+ }
+ };
+
+ es3fFboMultisampleTests.run = function(context, range) {
+ gl = context;
+ //Set up root Test
+ var state = tcuTestCase.runner;
+
+ var test = new es3fFboMultisampleTests.FboMultisampleTests();
+ var testName = test.fullName();
+ var testDescription = test.getDescription();
+
+ state.testName = testName;
+ state.setRoot(test);
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ test.init();
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fFboMultisampleTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboRenderTest.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboRenderTest.js
new file mode 100644
index 0000000000..78229de447
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboRenderTest.js
@@ -0,0 +1,2389 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fFboRenderTest');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuLogImage');
+goog.require('framework.common.tcuPixelFormat');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.delibs.debase.deUtil');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('framework.opengl.simplereference.sglrGLContext');
+goog.require('framework.opengl.simplereference.sglrReferenceContext');
+goog.require('framework.referencerenderer.rrUtil');
+goog.require('functional.gles3.es3fFboTestUtil');
+
+goog.scope(function() {
+
+ var es3fFboRenderTest = functional.gles3.es3fFboRenderTest;
+ var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluTextureUtil = framework.opengl.gluTextureUtil;
+ var tcuImageCompare = framework.common.tcuImageCompare;
+ var tcuLogImage = framework.common.tcuLogImage;
+ var tcuPixelFormat = framework.common.tcuPixelFormat;
+ var tcuRGBA = framework.common.tcuRGBA;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuTexture = framework.common.tcuTexture;
+ var tcuTextureUtil = framework.common.tcuTextureUtil;
+ var deMath = framework.delibs.debase.deMath;
+ var deRandom = framework.delibs.debase.deRandom;
+ var deString = framework.delibs.debase.deString;
+ var deUtil = framework.delibs.debase.deUtil;
+ var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
+ var sglrReferenceContext =
+ framework.opengl.simplereference.sglrReferenceContext;
+ var rrUtil = framework.referencerenderer.rrUtil;
+
+ /** @type {WebGL2RenderingContext} */ var gl;
+
+ /**
+ * @constructor
+ * @param {number=} buffers_
+ * @param {number=} colorType_
+ * @param {number=} colorFormat_
+ * @param {number=} depthStencilType_
+ * @param {number=} depthStencilFormat_
+ * @param {number=} width_
+ * @param {number=} height_
+ * @param {number=} samples_
+ */
+ es3fFboRenderTest.FboConfig = function(
+ buffers_, colorType_, colorFormat_, depthStencilType_,
+ depthStencilFormat_, width_, height_, samples_
+ ) {
+ // Buffer bit mask (gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT|...)
+ this.buffers = buffers_ ? buffers_ : 0;
+ // gl.TEXTURE_2D, gl.TEXTURE_CUBE_MAP, gl.RENDERBUFFER
+ this.colorType = colorType_ ? colorType_ : gl.NONE;
+ // Internal format for color buffer texture or renderbuffer
+ this.colorFormat = colorFormat_ ? colorFormat_ : gl.NONE;
+ this.depthStencilType = depthStencilType_?
+ depthStencilType_ : gl.NONE;
+ this.depthStencilFormat = depthStencilFormat_ ?
+ depthStencilFormat_ : gl.NONE;
+ this.width = width_ ? width_ : 0;
+ this.height = height_ ? height_ : 0;
+ this.samples = samples_? samples_ : 0;
+ };
+
+ /**
+ * @param {number} type
+ * @return {string}
+ */
+ es3fFboRenderTest.getTypeName = function(type) {
+ switch (type) {
+ case gl.TEXTURE_2D: return 'tex2d';
+ case gl.RENDERBUFFER: return 'rbo';
+ default:
+ testFailed('Unknown type');
+ }
+ return 'Should not get to this point';
+ };
+
+ /**
+ * @return {string}
+ */
+ es3fFboRenderTest.FboConfig.prototype.getName = function() {
+ var name = '';
+
+ assertMsgOptions((this.buffers & gl.COLOR_BUFFER_BIT) != 0,
+ 'Color buffer is not specified', false, true);
+
+ name += es3fFboRenderTest.getTypeName(this.colorType) + '_' +
+ es3fFboTestUtil.getFormatName(this.colorFormat);
+
+ if (this.buffers & gl.DEPTH_BUFFER_BIT)
+ name += '_depth';
+ if (this.buffers & gl.STENCIL_BUFFER_BIT)
+ name += '_stencil';
+
+ if (this.buffers & (gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT))
+ name += '_' + es3fFboRenderTest.getTypeName(this.depthStencilType) +
+ '_' + es3fFboTestUtil.getFormatName(this.depthStencilFormat);
+
+ return name;
+ };
+
+ /**
+ * @param {number} format
+ * @return {Array<string>}
+ */
+ es3fFboRenderTest.getEnablingExtensions = function(format) {
+ /** @type {Array<string>} */ var out = [];
+
+ switch (format) {
+ case gl.RGB16F:
+ assertMsgOptions(false, "Not part of the tested formats", false, true);
+ break;
+
+ case gl.RGBA16F:
+ case gl.RG16F:
+ case gl.R16F:
+ case gl.RGBA32F:
+ case gl.RGB32F:
+ case gl.R11F_G11F_B10F:
+ case gl.RG32F:
+ case gl.R32F:
+ out.push('EXT_color_buffer_float');
+
+ default:
+ break;
+ }
+
+ return out;
+ };
+
+ /**
+ * @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
+ * context
+ * @param {string} name
+ * @return {*}
+ */
+ es3fFboRenderTest.isExtensionSupported = function(context, name) {
+ return context.getExtension(name);
+ };
+
+ /**
+ * @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
+ * context
+ * @param {Array<string>} requiredExts
+ * @return {boolean}
+ */
+ es3fFboRenderTest.isAnyExtensionSupported = function(
+ context, requiredExts) {
+
+ if (!requiredExts || requiredExts.length == 0)
+ return true;
+
+ for (var extNdx = 0; extNdx < requiredExts.length; extNdx++) {
+ var extension = requiredExts[extNdx];
+
+ if (es3fFboRenderTest.isExtensionSupported(context, extension))
+ return true;
+ }
+
+ return false;
+ };
+
+ /**
+ * @param {Array} list
+ * @param {string} sep
+ * @return {string}
+ */
+ es3fFboRenderTest.join = function(list, sep) {
+ var out = '';
+
+ for (var elemNdx = 0; elemNdx < list.length; elemNdx++) {
+ if (elemNdx != 0)
+ out += sep;
+ out += list[elemNdx];
+ }
+
+ return out;
+ };
+
+ /**
+ * @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
+ * context
+ * @param {number} sizedFormat
+ */
+ es3fFboRenderTest.checkColorFormatSupport = function(context, sizedFormat) {
+ /** @type {Array<string>} */ var requiredExts =
+ es3fFboRenderTest.getEnablingExtensions(sizedFormat);
+
+ if (!es3fFboRenderTest.isAnyExtensionSupported(context, requiredExts)) {
+ var errMsg = 'Format not supported, requires ' + (
+ (requiredExts.length == 1) ? requiredExts[0] :
+ ' one of the following: ' +
+ requiredExts.join(', ')
+ );
+ checkMessage(false, errMsg);
+
+ throw new TestFailedException(errMsg);
+ }
+ };
+
+ /**
+ * @constructor
+ * @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
+ * context
+ * @param {es3fFboRenderTest.FboConfig} config
+ * @param {number} width
+ * @param {number} height
+ * @param {sglrReferenceContext.AnyFramebuffer=} fbo
+ * @param {sglrReferenceContext.AnyRenderbuffer=} colorBufferName
+ * @param {sglrReferenceContext.AnyRenderbuffer=} depthStencilBufferName
+ */
+ es3fFboRenderTest.Framebuffer = function(
+ context, config, width, height, fbo,
+ colorBufferName, depthStencilBufferName) {
+
+ this.m_config = config;
+ this.m_context = context;
+ this.m_framebuffer = fbo ? fbo : null;
+ this.m_colorBuffer = colorBufferName ? colorBufferName : null;
+ this.m_depthStencilBuffer = depthStencilBufferName ?
+ depthStencilBufferName : null;
+
+ // Verify that color format is supported
+ es3fFboRenderTest.checkColorFormatSupport(context, config.colorFormat);
+
+ if (!this.m_framebuffer)
+ this.m_framebuffer = context.createFramebuffer();
+ context.bindFramebuffer(gl.FRAMEBUFFER, this.m_framebuffer);
+
+ if (this.m_config.buffers & (gl.COLOR_BUFFER_BIT)) {
+ switch (this.m_config.colorType) {
+ case gl.TEXTURE_2D:
+ this.m_colorBuffer = this.createTex2D(
+ /** @type {WebGLTexture} */ (colorBufferName),
+ this.m_config.colorFormat, width, height
+ );
+
+ context.framebufferTexture2D(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
+ gl.TEXTURE_2D, this.m_colorBuffer, 0
+ );
+
+ break;
+
+ case gl.RENDERBUFFER:
+ this.m_colorBuffer = this.createRbo(
+ /** @type {WebGLRenderbuffer} */ (colorBufferName),
+ this.m_config.colorFormat, width, height
+ );
+
+ context.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
+ gl.RENDERBUFFER, this.m_colorBuffer
+ );
+
+ break;
+
+ default:
+ testFailed('Unsupported type');
+ }
+ }
+
+ if (this.m_config.buffers &
+ (gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)) {
+
+ switch (this.m_config.depthStencilType) {
+ case gl.TEXTURE_2D:
+ this.m_depthStencilBuffer = this.createTex2D(
+ /** @type {WebGLTexture} */
+ (depthStencilBufferName),
+ this.m_config.depthStencilFormat, width, height
+ );
+ break;
+ case gl.RENDERBUFFER:
+ this.m_depthStencilBuffer = this.createRbo(
+ /** @type {WebGLRenderbuffer} */
+ (depthStencilBufferName),
+ this.m_config.depthStencilFormat, width, height
+ );
+ break;
+
+ default:
+ testFailed('Unsupported type');
+ }
+ }
+
+ for (var ndx = 0; ndx < 2; ndx++) {
+ var bit = ndx ? gl.STENCIL_BUFFER_BIT : gl.DEPTH_BUFFER_BIT;
+ var point = ndx ? gl.STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT;
+
+ if ((this.m_config.buffers & bit) == 0)
+ continue; /* Not used. */
+
+ switch (this.m_config.depthStencilType) {
+ case gl.TEXTURE_2D:
+ context.framebufferTexture2D(
+ gl.FRAMEBUFFER, point, gl.TEXTURE_2D,
+ this.m_depthStencilBuffer, 0
+ );
+ break;
+ case gl.RENDERBUFFER:
+ context.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, point,
+ gl.RENDERBUFFER, this.m_depthStencilBuffer
+ );
+ break;
+ default:
+ throw new Error('Invalid depth stencil type');
+ }
+ }
+
+ context.bindFramebuffer(gl.FRAMEBUFFER, null);
+ };
+
+ /**
+ * @return {es3fFboRenderTest.FboConfig}
+ */
+ es3fFboRenderTest.Framebuffer.prototype.getConfig = function() {
+ return this.m_config;
+ };
+
+ /**
+ * @return {?sglrReferenceContext.AnyFramebuffer}
+ */
+ es3fFboRenderTest.Framebuffer.prototype.getFramebuffer = function() {
+ return this.m_framebuffer;
+ };
+
+ /**
+ * @return {?sglrReferenceContext.AnyRenderbuffer}
+ */
+ es3fFboRenderTest.Framebuffer.prototype.getColorBuffer = function() {
+ return this.m_colorBuffer;
+ };
+
+ /**
+ * @return {?sglrReferenceContext.AnyRenderbuffer}
+ */
+ es3fFboRenderTest.Framebuffer.prototype.getDepthStencilBuffer = function() {
+ return this.m_depthStencilBuffer;
+ };
+
+ /**
+ * deinit
+ */
+ es3fFboRenderTest.Framebuffer.prototype.deinit = function() {
+ this.m_context.deleteFramebuffer(
+ /** @type {WebGLFramebuffer} */ (this.m_framebuffer)
+ );
+ this.destroyBuffer(this.m_colorBuffer, this.m_config.colorType);
+ this.destroyBuffer(
+ this.m_depthStencilBuffer, this.m_config.depthStencilType
+ );
+ };
+
+ /**
+ * checkCompleteness
+ */
+ es3fFboRenderTest.Framebuffer.prototype.checkCompleteness = function() {
+ this.m_context.bindFramebuffer(gl.FRAMEBUFFER, this.m_framebuffer);
+ var status = this.m_context.checkFramebufferStatus(gl.FRAMEBUFFER);
+ this.m_context.bindFramebuffer(gl.FRAMEBUFFER, null);
+ if (status != gl.FRAMEBUFFER_COMPLETE)
+ throw new es3fFboTestUtil.FboIncompleteException(status);
+ };
+
+ /**
+ * @param {?WebGLTexture|sglrReferenceContext.TextureContainer} name
+ * @param {number} format
+ * @param {number} width
+ * @param {number} height
+ * @return {?WebGLTexture|sglrReferenceContext.TextureContainer}
+ */
+ es3fFboRenderTest.Framebuffer.prototype.createTex2D = function(
+ name, format, width, height) {
+
+ if (!name)
+ name = this.m_context.createTexture();
+
+ this.m_context.bindTexture(gl.TEXTURE_2D, name);
+ this.m_context.texImage2DDelegate(
+ gl.TEXTURE_2D, 0, format, width, height
+ );
+
+ if (!deMath.deIsPowerOfTwo32(width) ||
+ !deMath.deIsPowerOfTwo32(height)) {
+
+ // Set wrap mode to clamp for NPOT FBOs
+ this.m_context.texParameteri(
+ gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE
+ );
+ }
+
+ this.m_context.texParameteri(
+ gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST
+ );
+
+ return name;
+ };
+
+ /**
+ * @param {?WebGLRenderbuffer|sglrReferenceContext.Renderbuffer} name
+ * @param {number} format
+ * @param {number} width
+ * @param {number} height
+ * @return {?WebGLRenderbuffer|sglrReferenceContext.Renderbuffer}
+ */
+ es3fFboRenderTest.Framebuffer.prototype.createRbo = function(
+ name, format, width, height) {
+
+ if (!name)
+ name = this.m_context.createRenderbuffer();
+
+ this.m_context.bindRenderbuffer(gl.RENDERBUFFER, name);
+ this.m_context.renderbufferStorage(
+ gl.RENDERBUFFER, format, width, height
+ );
+
+ return name;
+ };
+
+ /**
+ * @param {?sglrReferenceContext.AnyRenderbuffer} name
+ * @param {number} type
+ */
+ es3fFboRenderTest.Framebuffer.prototype.destroyBuffer = function(
+ name, type) {
+
+ if (type == gl.TEXTURE_2D || type == gl.TEXTURE_CUBE_MAP)
+ this.m_context.deleteTexture(/** @type {?WebGLTexture} */ (name));
+ else if (type == gl.RENDERBUFFER)
+ this.m_context.deleteRenderbuffer(
+ /** @type {?WebGLRenderbuffer} */ (name)
+ );
+ else
+ assertMsgOptions(
+ type == gl.NONE, 'Invalid buffer type', false, true
+ );
+ };
+
+ /**
+ * @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
+ * context
+ * @param {WebGLTexture|sglrReferenceContext.TextureContainer} name
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} width
+ * @param {number} height
+ */
+ es3fFboRenderTest.createMetaballsTex2D = function(
+ context, name, format, dataType, width, height) {
+
+ /** @type {tcuTexture.TextureFormat} */ var texFormat =
+ gluTextureUtil.mapGLTransferFormat(format, dataType);
+ /** @type {tcuTexture.TextureLevel} */ var level =
+ new tcuTexture.TextureLevel(texFormat, width, height);
+
+ tcuTextureUtil.fillWithMetaballs(
+ level.getAccess(), 5, /*name ^*/ width ^ height
+ );
+
+ context.bindTexture(gl.TEXTURE_2D, name);
+ context.texImage2D(
+ gl.TEXTURE_2D, 0, format, width, height, 0, format,
+ dataType, level.getAccess().getDataPtr()
+ );
+ context.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ };
+
+ /**
+ * @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
+ * context
+ * @param {WebGLTexture|sglrReferenceContext.TextureContainer} name
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} width
+ * @param {number} height
+ */
+ es3fFboRenderTest.createQuadsTex2D = function(
+ context, name, format, dataType, width, height) {
+
+ /** @type {tcuTexture.TextureFormat} */
+ var texFormat = gluTextureUtil.mapGLTransferFormat(format, dataType);
+ /** @type {tcuTexture.TextureLevel} */
+ var level = new tcuTexture.TextureLevel(texFormat, width, height);
+
+ tcuTextureUtil.fillWithRGBAQuads(level.getAccess());
+
+ context.bindTexture(gl.TEXTURE_2D, name);
+ context.texImage2D(
+ gl.TEXTURE_2D, 0, format, width, height, 0,
+ format, dataType, level.getAccess().getDataPtr()
+ );
+ context.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ * @param {es3fFboRenderTest.FboConfig} config
+ */
+ es3fFboRenderTest.FboRenderCase = function(name, description, config) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ this.m_config = config;
+ };
+
+ es3fFboRenderTest.FboRenderCase.prototype =
+ Object.create(tcuTestCase.DeqpTest.prototype);
+
+ es3fFboRenderTest.FboRenderCase.prototype.constructor =
+ es3fFboRenderTest.FboRenderCase;
+
+ /**
+ * Must be overridden
+ * @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
+ * fboContext
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFboRenderTest.FboRenderCase.prototype.render = function(
+ fboContext, dst) {
+ throw new Error('Must override');
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fFboRenderTest.FboRenderCase.prototype.iterate = function() {
+ var clearColor = [0.125, 0.25, 0.5, 1.0];
+ /** @type {?string} */ var failReason = "";
+
+ // Position & size for context
+ var rnd = new deRandom.deRandom();
+ deRandom.deRandom_init(rnd, deString.deStringHash(this.fullName()));
+
+ var width = Math.min(gl.canvas.width, 128);
+ var height = Math.min(gl.canvas.height, 128);
+ var xMax = gl.canvas.width - width + 1;
+ var yMax = gl.canvas.height - height + 1;
+ var x = Math.abs(deRandom.deRandom_getInt(rnd)) % xMax;
+ var y = Math.abs(deRandom.deRandom_getInt(rnd)) % yMax;
+
+ /** @type {tcuSurface.Surface} */
+ var gles3Frame = new tcuSurface.Surface(width, height);
+ /** @type {tcuSurface.Surface} */
+ var refFrame = new tcuSurface.Surface(width, height);
+
+ /** @type {number} */ var gles3Error = 0;
+ /** @type {number} */ var refError = 0;
+
+ // Render using GLES3
+ /**
+ * @type {sglrGLContext.GLContext|
+ * sglrReferenceContext.ReferenceContext}
+ */
+ var context;
+
+ try {
+ context = new sglrGLContext.GLContext(gl, [x, y, width, height]);
+
+ context.clearColor(
+ clearColor[0], clearColor[1], clearColor[2], clearColor[3]
+ );
+
+ context.clear(
+ gl.COLOR_BUFFER_BIT |
+ gl.DEPTH_BUFFER_BIT |
+ gl.STENCIL_BUFFER_BIT
+ );
+
+ this.render(context, gles3Frame); // Call actual render func
+ gles3Error = context.getError();
+ }
+ catch (e) {
+ if (e instanceof es3fFboTestUtil.FboIncompleteException) {
+ e.message = WebGLTestUtils.glEnumToString(gl, e.getReason());
+ if(e.getReason() == gl.FRAMEBUFFER_UNSUPPORTED) {
+ // Mark test case as unsupported
+ bufferedLogToConsole(e + ': ' + e.message);
+ testFailed('Not supported');
+ return tcuTestCase.IterateResult.STOP;
+ }
+ }
+
+ // Propagate error
+ throw e;
+ }
+
+ // Render reference image
+
+ /** @type {sglrReferenceContext.ReferenceContextBuffers} */
+ var buffers = new sglrReferenceContext.ReferenceContextBuffers(
+ new tcuPixelFormat.PixelFormat(
+ 8, 8, 8,
+ gl.getParameter(gl.ALPHA_BITS) ? 8 : 0
+ ),
+ /** @type {number} */ (gl.getParameter(gl.DEPTH_BITS)),
+ /** @type {number} */ (gl.getParameter(gl.STENCIL_BITS)),
+ width,
+ height
+ );
+ context = new sglrReferenceContext.ReferenceContext(
+ new sglrReferenceContext.ReferenceContextLimits(gl),
+ buffers.getColorbuffer(),
+ buffers.getDepthbuffer(),
+ buffers.getStencilbuffer()
+ );
+
+ context.clearColor(
+ clearColor[0], clearColor[1], clearColor[2], clearColor[3]
+ );
+
+ context.clear(
+ gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT
+ );
+
+ this.render(context, refFrame);
+ refError = context.getError();
+
+ // Compare error codes
+ var errorCodesOk = (gles3Error == refError);
+
+ if (!errorCodesOk) {
+ bufferedLogToConsole (
+ 'Error code mismatch: got ' +
+ WebGLTestUtils.glEnumToString(gl, gles3Error) + ', expected ' +
+ WebGLTestUtils.glEnumToString(gl, refError)
+ );
+ failReason = 'Got unexpected error';
+ }
+
+ // Compare images
+ var imagesOk = this.compare(refFrame, gles3Frame);
+
+ if (!imagesOk && !failReason)
+ failReason = 'Image comparison failed';
+
+ // Store test result
+ var isOk = errorCodesOk && imagesOk;
+ assertMsgOptions(isOk, failReason, true, true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @param {tcuSurface.Surface} reference
+ * @param {tcuSurface.Surface} result
+ * @return {boolean}
+ */
+ es3fFboRenderTest.FboRenderCase.prototype.compare = function(
+ reference, result) {
+
+ var threshold = new tcuRGBA.RGBA(
+ /* TODO: tcu::max(getFormatThreshold(this.m_config.colorFormat),*/
+ [12, 12, 12, 12]
+ );
+
+ return tcuImageCompare.bilinearCompare(
+ 'ComparisonResult', 'Image comparison result',
+ reference.getAccess(), result.getAccess(),
+ threshold, tcuImageCompare.CompareLogMode.RESULT
+ );
+ };
+
+ /**
+ * deinit
+ */
+ es3fFboRenderTest.FboRenderCase.prototype.deinit = function() {
+ gl.clearColor(0.0, 0.0, 0.0, 0.0);
+ gl.clearDepth(1.0);
+ gl.clearStencil(0);
+
+ gl.disable(gl.STENCIL_TEST);
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ };
+
+ // FboCases
+
+ /**
+ * @constructor
+ * @extends {es3fFboRenderTest.FboRenderCase}
+ * @param {es3fFboRenderTest.FboConfig} config
+ */
+ es3fFboRenderTest.StencilClearsTest = function(config) {
+ es3fFboRenderTest.FboRenderCase.call(
+ this, config.getName(), 'Stencil clears', config
+ );
+ };
+
+ es3fFboRenderTest.StencilClearsTest.prototype =
+ Object.create(es3fFboRenderTest.FboRenderCase.prototype);
+
+ es3fFboRenderTest.StencilClearsTest.prototype.constructor =
+ es3fFboRenderTest.StencilClearsTest;
+
+ /**
+ * @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
+ * context
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFboRenderTest.StencilClearsTest.prototype.render = function(
+ context, dst) {
+
+ /** @type {tcuTexture.TextureFormat} */
+ var colorFormat = gluTextureUtil.mapGLInternalFormat(
+ this.m_config.colorFormat
+ );
+
+ /** @type {gluShaderUtil.DataType} */
+ var fboSamplerType = /** @type {gluShaderUtil.DataType} */ (
+ gluTextureUtil.getSampler2DType(colorFormat)
+ );
+
+ /** @type {gluShaderUtil.DataType} */
+ var fboOutputType = es3fFboTestUtil.getFragmentOutputType(colorFormat);
+
+ /** @type {tcuTextureUtil.TextureFormatInfo} */
+ var fboRangeInfo = tcuTextureUtil.getTextureFormatInfo(colorFormat);
+
+ var fboOutScale = deMath.subtract(
+ fboRangeInfo.valueMax, fboRangeInfo.valueMin
+ );
+
+ var fboOutBias = fboRangeInfo.valueMin;
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texToFboShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D], fboOutputType
+ );
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texFromFboShader = new es3fFboTestUtil.Texture2DShader(
+ [fboSamplerType], gluShaderUtil.DataType.FLOAT_VEC4);
+
+ /** @type {number} */ var texToFboShaderID =
+ context.createProgram(texToFboShader);
+
+ /** @type {number} */ var texFromFboShaderID =
+ context.createProgram(texFromFboShader);
+
+ /** @type {?WebGLTexture|sglrReferenceContext.TextureContainer} */
+ var metaballsTex = context.createTexture();
+
+ /** @type {?WebGLTexture|sglrReferenceContext.TextureContainer} */
+ var quadsTex = context.createTexture();
+
+ /** @type {number} */ var width = 128;
+ /** @type {number} */ var height = 128;
+
+ texToFboShader.setOutScaleBias(fboOutScale, fboOutBias);
+ texFromFboShader.setTexScaleBias(
+ 0, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias
+ );
+
+ es3fFboRenderTest.createQuadsTex2D(
+ context, quadsTex, gl.RGBA, gl.UNSIGNED_BYTE, width, height
+ );
+
+ es3fFboRenderTest.createMetaballsTex2D(
+ context, metaballsTex, gl.RGBA, gl.UNSIGNED_BYTE, width, height
+ );
+
+ /** @type {es3fFboRenderTest.Framebuffer} */
+ var fbo = new es3fFboRenderTest.Framebuffer(
+ context, this.m_config, width, height
+ );
+ fbo.checkCompleteness();
+
+ // Bind framebuffer and clear
+ context.bindFramebuffer(gl.FRAMEBUFFER, fbo.getFramebuffer());
+ context.viewport(0, 0, width, height);
+ context.clearColor(0.0, 0.0, 0.0, 1.0);
+ context.clear(
+ gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT
+ );
+
+ // Do stencil clears
+ context.enable(gl.SCISSOR_TEST);
+ context.scissor(10, 16, 32, 120);
+ context.clearStencil(1);
+ context.clear(gl.STENCIL_BUFFER_BIT);
+ context.scissor(16, 32, 100, 64);
+ context.clearStencil(2);
+ context.clear(gl.STENCIL_BUFFER_BIT);
+ context.disable(gl.SCISSOR_TEST);
+
+ // Draw 2 textures with stecil tests
+ context.enable(gl.STENCIL_TEST);
+
+ context.bindTexture(gl.TEXTURE_2D, quadsTex);
+ context.stencilFunc(gl.EQUAL, 1, 0xff);
+
+ texToFboShader.setUniforms(context, texToFboShaderID);
+ rrUtil.drawQuad(
+ context, texToFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+
+ context.bindTexture(gl.TEXTURE_2D, metaballsTex);
+ context.stencilFunc(gl.EQUAL, 2, 0xff);
+
+ texToFboShader.setUniforms(context, texToFboShaderID);
+ rrUtil.drawQuad(
+ context, texToFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+
+ context.disable(gl.STENCIL_TEST);
+
+ if (fbo.getConfig().colorType == gl.TEXTURE_2D) {
+ context.bindFramebuffer(gl.FRAMEBUFFER, null);
+ context.bindTexture(gl.TEXTURE_2D, fbo.getColorBuffer());
+ context.viewport(0, 0, context.getWidth(), context.getHeight());
+
+ texFromFboShader.setUniforms(context, texFromFboShaderID);
+ rrUtil.drawQuad(
+ context, texFromFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+
+ dst.readViewport(
+ context, [0, 0, context.getWidth(), context.getHeight()]
+ );
+ } else
+ es3fFboTestUtil.readPixels(
+ context, dst, 0, 0, width, height, colorFormat,
+ fboRangeInfo.lookupScale, fboRangeInfo.lookupBias
+ );
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fFboRenderTest.FboRenderCase}
+ * @param {es3fFboRenderTest.FboConfig} config
+ */
+ es3fFboRenderTest.SharedColorbufferTest = function(config) {
+ es3fFboRenderTest.FboRenderCase.call(
+ this, config.getName(), 'Shared colorbuffer', config
+ );
+ };
+
+ es3fFboRenderTest.SharedColorbufferTest.prototype =
+ Object.create(es3fFboRenderTest.FboRenderCase.prototype);
+
+ es3fFboRenderTest.SharedColorbufferTest.prototype.constructor =
+ es3fFboRenderTest.SharedColorbufferTest;
+
+ /**
+ * @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
+ * context
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFboRenderTest.SharedColorbufferTest.prototype.render = function(
+ context, dst) {
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D],
+ gluShaderUtil.DataType.FLOAT_VEC4
+ );
+
+ /** @type {es3fFboTestUtil.FlatColorShader} */
+ var flatShader = new es3fFboTestUtil.FlatColorShader(
+ gluShaderUtil.DataType.FLOAT_VEC4
+ );
+
+ /** @type {number} */
+ var texShaderID = context.createProgram(texShader);
+ /** @type {number} */
+ var flatShaderID = context.createProgram(flatShader);
+
+ /** @type {number} */ var width = 128;
+ /** @type {number} */ var height = 128;
+
+ /** @type {?WebGLTexture|sglrReferenceContext.TextureContainer} */
+ var quadsTex = context.createTexture();
+
+ /** @type {?WebGLTexture|sglrReferenceContext.TextureContainer} */
+ var metaballsTex = context.createTexture();
+
+ /** @type {boolean} */ var stencil =
+ (this.m_config.buffers & gl.STENCIL_BUFFER_BIT) != 0;
+
+ context.disable(gl.DITHER);
+
+ // Textures
+ es3fFboRenderTest.createQuadsTex2D(
+ context, quadsTex, gl.RGB, gl.UNSIGNED_BYTE, 64, 64
+ );
+ es3fFboRenderTest.createMetaballsTex2D(
+ context, metaballsTex, gl.RGBA, gl.UNSIGNED_BYTE, 64, 64
+ );
+
+ context.viewport(0, 0, width, height);
+
+ // Fbo A
+ /** @type {es3fFboRenderTest.Framebuffer} */
+ var fboA = new es3fFboRenderTest.Framebuffer(
+ context, this.m_config, width, height
+ );
+ fboA.checkCompleteness();
+
+ // Fbo B - don't create colorbuffer
+
+ /** @type {es3fFboRenderTest.FboConfig} */
+ var cfg = /** @type {es3fFboRenderTest.FboConfig} */
+ (deUtil.clone(this.m_config));
+
+ cfg.buffers = deMath.binaryOp(
+ cfg.buffers,
+ deMath.binaryNot(gl.COLOR_BUFFER_BIT),
+ deMath.BinaryOp.AND
+ );
+ cfg.colorType = gl.NONE;
+ cfg.colorFormat = gl.NONE;
+
+ /** @type {es3fFboRenderTest.Framebuffer} */
+ var fboB = new es3fFboRenderTest.Framebuffer(
+ context, cfg, width, height
+ );
+
+ // Attach color buffer from fbo A
+ context.bindFramebuffer(gl.FRAMEBUFFER, fboB.getFramebuffer());
+ switch (this.m_config.colorType) {
+ case gl.TEXTURE_2D:
+ context.framebufferTexture2D(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
+ gl.TEXTURE_2D, fboA.getColorBuffer(), 0
+ );
+ break;
+
+ case gl.RENDERBUFFER:
+ context.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
+ gl.RENDERBUFFER, fboA.getColorBuffer()
+ );
+ break;
+
+ default:
+ throw new Error('Invalid color type');
+ }
+
+ // Clear depth and stencil in fbo B
+ context.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ // Render quads to fbo 1, with depth 0.0
+ context.bindFramebuffer(gl.FRAMEBUFFER, fboA.getFramebuffer());
+ context.bindTexture(gl.TEXTURE_2D, quadsTex);
+ context.clearColor(0.0, 0.0, 0.0, 1.0);
+ context.clear(
+ gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT
+ );
+
+ if (stencil) {
+ // Stencil to 1 in fbo A
+ context.clearStencil(1);
+ context.clear(gl.STENCIL_BUFFER_BIT);
+ }
+
+ texShader.setUniforms(context, texShaderID);
+
+ context.enable(gl.DEPTH_TEST);
+ rrUtil.drawQuad(
+ context, texShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+ context.disable(gl.DEPTH_TEST);
+
+ // Blend metaballs to fbo 2
+ context.bindFramebuffer(gl.FRAMEBUFFER, fboB.getFramebuffer());
+ context.bindTexture(gl.TEXTURE_2D, metaballsTex);
+ context.enable(gl.BLEND);
+ context.blendFuncSeparate(
+ gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ONE
+ );
+ rrUtil.drawQuad(
+ context, texShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+
+ // Render small quad that is only visible if depth buffer
+ // is not shared with fbo A - or there is no depth bits
+ context.bindTexture(gl.TEXTURE_2D, quadsTex);
+ context.enable(gl.DEPTH_TEST);
+ rrUtil.drawQuad(context, texShaderID, [0.5, 0.5, 0.5], [1.0, 1.0, 0.5]);
+ context.disable(gl.DEPTH_TEST);
+
+ if (stencil) {
+ flatShader.setColor(context, flatShaderID, [0.0, 1.0, 0.0, 1.0]);
+
+ // Clear subset of stencil buffer to 1
+ context.enable(gl.SCISSOR_TEST);
+ context.scissor(10, 10, 12, 25);
+ context.clearStencil(1);
+ context.clear(gl.STENCIL_BUFFER_BIT);
+ context.disable(gl.SCISSOR_TEST);
+
+ // Render quad with stencil mask == 1
+ context.enable(gl.STENCIL_TEST);
+ context.stencilFunc(gl.EQUAL, 1, 0xff);
+ rrUtil.drawQuad(
+ context, flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+ context.disable(gl.STENCIL_TEST);
+ }
+
+ // Get results
+ if (fboA.getConfig().colorType == gl.TEXTURE_2D) {
+ texShader.setUniforms(context, texShaderID);
+
+ context.bindFramebuffer(gl.FRAMEBUFFER, null);
+ context.bindTexture(gl.TEXTURE_2D, fboA.getColorBuffer());
+ context.viewport(0, 0, context.getWidth(), context.getHeight());
+ rrUtil.drawQuad(
+ context, texShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+ dst.readViewport(
+ context, [0, 0, context.getWidth(), context.getHeight()]
+ );
+ } else
+ es3fFboTestUtil.readPixels(
+ context, dst, 0, 0, width, height,
+ gluTextureUtil.mapGLInternalFormat(
+ fboA.getConfig().colorFormat
+ ), [1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]
+ );
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fFboRenderTest.FboRenderCase}
+ * @param {es3fFboRenderTest.FboConfig} config
+ */
+ es3fFboRenderTest.SharedColorbufferClearsTest = function(config) {
+ es3fFboRenderTest.FboRenderCase.call(
+ this, config.getName(), 'Shared colorbuffer clears', config
+ );
+ };
+
+ es3fFboRenderTest.SharedColorbufferClearsTest.prototype =
+ Object.create(es3fFboRenderTest.FboRenderCase.prototype);
+
+ es3fFboRenderTest.SharedColorbufferClearsTest.prototype.constructor =
+ es3fFboRenderTest.SharedColorbufferClearsTest;
+
+ /**
+ * @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
+ * context
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFboRenderTest.SharedColorbufferClearsTest.prototype.render = function(
+ context, dst) {
+
+ /** @type {tcuTexture.TextureFormat} */
+ var colorFormat = gluTextureUtil.mapGLInternalFormat(
+ this.m_config.colorFormat
+ );
+
+ /** @type {gluShaderUtil.DataType} */
+ var fboSamplerType = gluTextureUtil.getSampler2DType(colorFormat);
+
+ var width = 128;
+ var height = 128;
+ var colorbuffer = this.m_config.colorType == gl.TEXTURE_2D?
+ context.createTexture() :
+ context.createRenderbuffer();
+
+ // Check for format support.
+ es3fFboRenderTest.checkColorFormatSupport(
+ context, this.m_config.colorFormat
+ );
+
+ // Single colorbuffer
+ if (this.m_config.colorType == gl.TEXTURE_2D) {
+ context.bindTexture(gl.TEXTURE_2D, colorbuffer);
+ context.texImage2DDelegate(
+ gl.TEXTURE_2D, 0, this.m_config.colorFormat, width, height
+ );
+ context.texParameteri(
+ gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST
+ );
+ context.texParameteri(
+ gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST
+ );
+ } else {
+ assertMsgOptions(
+ this.m_config.colorType == gl.RENDERBUFFER,
+ 'Not a render buffer type', false, true
+ );
+ context.bindRenderbuffer(gl.RENDERBUFFER, colorbuffer);
+ context.renderbufferStorage(
+ gl.RENDERBUFFER, this.m_config.colorFormat, width, height
+ );
+ }
+
+ // Multiple framebuffers sharing the colorbuffer
+ var fbo = [
+ context.createFramebuffer(),
+ context.createFramebuffer(),
+ context.createFramebuffer()
+ ];
+
+ for (var fboi = 0; fboi < fbo.length; fboi++) {
+ context.bindFramebuffer(gl.FRAMEBUFFER, fbo[fboi]);
+
+ if (this.m_config.colorType == gl.TEXTURE_2D)
+ context.framebufferTexture2D(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
+ gl.TEXTURE_2D, colorbuffer, 0
+ );
+ else
+ context.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
+ gl.RENDERBUFFER, colorbuffer
+ );
+ }
+
+ context.bindFramebuffer(gl.FRAMEBUFFER, fbo[0]);
+
+ // Check completeness
+
+ var status = context.checkFramebufferStatus(gl.FRAMEBUFFER);
+ if (status != gl.FRAMEBUFFER_COMPLETE)
+ throw new es3fFboTestUtil.FboIncompleteException(status);
+
+ // Render to them
+ context.viewport(0, 0, width, height);
+ context.clearColor(0.0, 0.0, 1.0, 1.0);
+ context.clear(gl.COLOR_BUFFER_BIT);
+
+ context.enable(gl.SCISSOR_TEST);
+
+ context.bindFramebuffer(gl.FRAMEBUFFER, fbo[1]);
+ context.clearColor(0.6, 0.0, 0.0, 1.0);
+ context.scissor(10, 10, 64, 64);
+ context.clear(gl.COLOR_BUFFER_BIT);
+ context.clearColor(0.0, 0.6, 0.0, 1.0);
+ context.scissor(60, 60, 40, 20);
+ context.clear(gl.COLOR_BUFFER_BIT);
+
+ context.bindFramebuffer(gl.FRAMEBUFFER, fbo[2]);
+ context.clearColor(0.0, 0.0, 0.6, 1.0);
+ context.scissor(20, 20, 100, 10);
+ context.clear(gl.COLOR_BUFFER_BIT);
+
+ context.bindFramebuffer(gl.FRAMEBUFFER, fbo[0]);
+ context.clearColor(0.6, 0.0, 0.6, 1.0);
+ context.scissor(20, 20, 5, 100);
+ context.clear(gl.COLOR_BUFFER_BIT);
+
+ context.disable(gl.SCISSOR_TEST);
+
+ if (this.m_config.colorType == gl.TEXTURE_2D) {
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var shader = new es3fFboTestUtil.Texture2DShader(
+ [fboSamplerType], gluShaderUtil.DataType.FLOAT_VEC4
+ );
+ var shaderID = context.createProgram(shader);
+
+ shader.setUniforms(context, shaderID);
+
+ context.bindFramebuffer(gl.FRAMEBUFFER, null);
+ context.viewport(0, 0, context.getWidth(), context.getHeight());
+ rrUtil.drawQuad(
+ context, shaderID, [-0.9, -0.9, 0.0], [0.9, 0.9, 0.0]
+ );
+ dst.readViewport(
+ context, [0, 0, context.getWidth(), context.getHeight()]
+ );
+ } else
+ es3fFboTestUtil.readPixels(
+ context, dst, 0, 0, width, height, colorFormat,
+ [1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]
+ );
+
+ //delete FBOs
+ for (fboi = 0; fboi < fbo.length; fboi++)
+ context.deleteFramebuffer(fbo[fboi]);
+
+ //delete Texture/Renderbuffer
+ if (this.m_config.colorType == gl.TEXTURE_2D)
+ context.deleteTexture(colorbuffer);
+ else
+ context.deleteRenderbuffer(colorbuffer);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fFboRenderTest.FboRenderCase}
+ * @param {es3fFboRenderTest.FboConfig} config
+ */
+ es3fFboRenderTest.SharedDepthStencilTest = function(config) {
+ es3fFboRenderTest.FboRenderCase.call(
+ this, config.getName(), 'Shared depth/stencilbuffer', config
+ );
+ };
+
+ es3fFboRenderTest.SharedDepthStencilTest.prototype =
+ Object.create(es3fFboRenderTest.FboRenderCase.prototype);
+
+ es3fFboRenderTest.SharedDepthStencilTest.prototype.constructor =
+ es3fFboRenderTest.SharedDepthStencilTest;
+
+ /**
+ * @param {es3fFboRenderTest.FboConfig} config
+ * @return {boolean}
+ */
+ es3fFboRenderTest.SharedDepthStencilTest.prototype.isConfigSupported =
+ function(config) {
+ return deMath.binaryOp(
+ config.buffers,
+ deMath.binaryOp(
+ gl.DEPTH_BUFFER_BIT, gl.STENCIL_BUFFER_BIT, deMath.BinaryOp.OR
+ ), deMath.BinaryOp.AND
+ ) != 0;
+ };
+
+ /**
+ * @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
+ * context
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFboRenderTest.SharedDepthStencilTest.prototype.render = function(
+ context, dst) {
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D],
+ gluShaderUtil.DataType.FLOAT_VEC4
+ );
+
+ /** @type {es3fFboTestUtil.FlatColorShader} */
+ var flatShader = new es3fFboTestUtil.FlatColorShader(
+ gluShaderUtil.DataType.FLOAT_VEC4
+ );
+
+ var texShaderID = context.createProgram(texShader);
+ var flatShaderID = context.createProgram(flatShader);
+ var width = 128;
+ var height = 128;
+ // bool depth = (this.m_config.buffers & gl.DEPTH_BUFFER_BIT) != 0;
+ /**@type {boolean} */ var stencil =
+ (this.m_config.buffers & gl.STENCIL_BUFFER_BIT) != 0;
+
+ // Textures
+ var metaballsTex = context.createTexture();
+ var quadsTex = context.createTexture();
+ es3fFboRenderTest.createMetaballsTex2D(
+ context, metaballsTex, gl.RGB, gl.UNSIGNED_BYTE, 64, 64
+ );
+ es3fFboRenderTest.createQuadsTex2D(
+ context, quadsTex, gl.RGB, gl.UNSIGNED_BYTE, 64, 64
+ );
+
+ context.viewport(0, 0, width, height);
+
+ // Fbo A
+ /** @type {es3fFboRenderTest.Framebuffer} */
+ var fboA = new es3fFboRenderTest.Framebuffer(
+ context, this.m_config, width, height
+ );
+
+ fboA.checkCompleteness();
+
+ // Fbo B
+ /** @type {es3fFboRenderTest.FboConfig} */
+ var cfg = /** @type {es3fFboRenderTest.FboConfig} */
+ (deUtil.clone(this.m_config));
+
+ cfg.buffers = deMath.binaryOp(
+ cfg.buffers,
+ deMath.binaryNot(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT),
+ deMath.BinaryOp.AND
+ );
+ cfg.depthStencilType = gl.NONE;
+ cfg.depthStencilFormat = gl.NONE;
+
+ /** @type {es3fFboRenderTest.Framebuffer} */
+ var fboB = new es3fFboRenderTest.Framebuffer(
+ context, cfg, width, height
+ );
+
+ // Bind depth/stencil buffers from fbo A to fbo B
+ context.bindFramebuffer(gl.FRAMEBUFFER, fboB.getFramebuffer());
+ for (var ndx = 0; ndx < 2; ndx++) {
+ var bit = ndx ? gl.STENCIL_BUFFER_BIT : gl.DEPTH_BUFFER_BIT;
+ var point = ndx ? gl.STENCIL_ATTACHMENT : gl.DEPTH_ATTACHMENT;
+
+ if (
+ deMath.binaryOp(
+ this.m_config.buffers, bit, deMath.BinaryOp.AND
+ ) == 0
+ )
+ continue;
+
+ switch (this.m_config.depthStencilType) {
+ case gl.TEXTURE_2D:
+ context.framebufferTexture2D(
+ gl.FRAMEBUFFER, point, gl.TEXTURE_2D,
+ fboA.getDepthStencilBuffer(), 0
+ );
+ break;
+ case gl.RENDERBUFFER:
+ context.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, point, gl.RENDERBUFFER,
+ fboA.getDepthStencilBuffer()
+ );
+ break;
+ default:
+ testFailed('Not implemented');
+ }
+ }
+
+ // Setup uniforms
+ texShader.setUniforms(context, texShaderID);
+
+ // Clear color to red and stencil to 1 in fbo B.
+ context.clearColor(1.0, 0.0, 0.0, 1.0);
+ context.clearStencil(1);
+ context.clear(
+ gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT
+ );
+
+ context.enable(gl.DEPTH_TEST);
+
+ // Render quad to fbo A
+ context.bindFramebuffer(gl.FRAMEBUFFER, fboA.getFramebuffer());
+ context.bindTexture(gl.TEXTURE_2D, quadsTex);
+ rrUtil.drawQuad(
+ context, texShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+
+ if (stencil) {
+ // Clear subset of stencil buffer to 0 in fbo A
+ context.enable(gl.SCISSOR_TEST);
+ context.scissor(10, 10, 12, 25);
+ context.clearStencil(0);
+ context.clear(gl.STENCIL_BUFFER_BIT);
+ context.disable(gl.SCISSOR_TEST);
+ }
+
+ // Render metaballs to fbo B
+ context.bindFramebuffer(gl.FRAMEBUFFER, fboB.getFramebuffer());
+ context.bindTexture(gl.TEXTURE_2D, metaballsTex);
+ rrUtil.drawQuad(
+ context, texShaderID, [-1.0, -1.0, -1.0], [1.0, 1.0, 1.0]
+ );
+
+ context.disable(gl.DEPTH_TEST);
+
+ if (stencil) {
+ // Render quad with stencil mask == 0
+ context.enable(gl.STENCIL_TEST);
+ context.stencilFunc(gl.EQUAL, 0, 0xff);
+ context.useProgram(flatShaderID);
+ flatShader.setColor(context, flatShaderID, [0.0, 1.0, 0.0, 1.0]);
+ rrUtil.drawQuad(
+ context, flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+ context.disable(gl.STENCIL_TEST);
+ }
+
+ if (this.m_config.colorType == gl.TEXTURE_2D) {
+ // Render both to screen
+ context.bindFramebuffer(gl.FRAMEBUFFER, null);
+ context.viewport(0, 0, context.getWidth(), context.getHeight());
+ context.bindTexture(gl.TEXTURE_2D, fboA.getColorBuffer());
+ rrUtil.drawQuad(
+ context, texShaderID, [-1.0, -1.0, 0.0], [0.0, 1.0, 0.0]
+ );
+ context.bindTexture(gl.TEXTURE_2D, fboB.getColorBuffer());
+ rrUtil.drawQuad(
+ context, texShaderID, [0.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+
+ dst.readViewport(
+ context, [0, 0, context.getWidth(), context.getHeight()]
+ );
+ } else {
+ // Read results from fbo B
+ es3fFboTestUtil.readPixels(
+ context, dst, 0, 0, width, height,
+ gluTextureUtil.mapGLInternalFormat(this.m_config.colorFormat),
+ [1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]
+ );
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fFboRenderTest.FboRenderCase}
+ * @param {es3fFboRenderTest.FboConfig} config
+ */
+ es3fFboRenderTest.ResizeTest = function(config) {
+ es3fFboRenderTest.FboRenderCase.call(
+ this, config.getName(), 'Resize framebuffer', config
+ );
+ };
+
+ es3fFboRenderTest.ResizeTest.prototype =
+ Object.create(es3fFboRenderTest.FboRenderCase.prototype);
+
+ es3fFboRenderTest.ResizeTest.prototype.constructor =
+ es3fFboRenderTest.ResizeTest;
+
+ /**
+ * @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
+ * context
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFboRenderTest.ResizeTest.prototype.render = function(context, dst) {
+ /** @type {tcuTexture.TextureFormat} */
+ var colorFormat = gluTextureUtil.mapGLInternalFormat(
+ this.m_config.colorFormat
+ );
+ /** @type {gluShaderUtil.DataType} */
+ var fboSamplerType = gluTextureUtil.getSampler2DType(colorFormat);
+ /** @type {gluShaderUtil.DataType} */
+ var fboOutputType = es3fFboTestUtil.getFragmentOutputType(colorFormat);
+ /** @type {tcuTextureUtil.TextureFormatInfo} */
+ var fboRangeInfo = tcuTextureUtil.getTextureFormatInfo(colorFormat);
+ var fboOutScale = deMath.subtract(
+ fboRangeInfo.valueMax, fboRangeInfo.valueMin
+ );
+ var fboOutBias = fboRangeInfo.valueMin;
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texToFboShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D], fboOutputType
+ );
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texFromFboShader = new es3fFboTestUtil.Texture2DShader(
+ [fboSamplerType], gluShaderUtil.DataType.FLOAT_VEC4
+ );
+
+ /** @type {es3fFboTestUtil.FlatColorShader} */
+ var flatShader = new es3fFboTestUtil.FlatColorShader(fboOutputType);
+ /** @type {WebGLProgram} */
+ var texToFboShaderID = context.createProgram(texToFboShader);
+ /** @type {WebGLProgram} */
+ var texFromFboShaderID = context.createProgram(texFromFboShader);
+ /** @type {WebGLProgram} */
+ var flatShaderID = context.createProgram(flatShader);
+
+ var quadsTex = context.createTexture();
+ var metaballsTex = context.createTexture();
+
+ var depth = deMath.binaryOp(
+ this.m_config.buffers, gl.DEPTH_BUFFER_BIT, deMath.BinaryOp.AND
+ ) != 0;
+ var stencil = deMath.binaryOp(
+ this.m_config.buffers, gl.STENCIL_BUFFER_BIT, deMath.BinaryOp.AND
+ ) != 0;
+
+ var initialWidth = 128;
+ var initialHeight = 128;
+ var newWidth = 64;
+ var newHeight = 32;
+
+ texToFboShader.setOutScaleBias(fboOutScale, fboOutBias);
+ texFromFboShader.setTexScaleBias(
+ 0, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias
+ );
+
+ es3fFboRenderTest.createQuadsTex2D(
+ context, quadsTex, gl.RGB, gl.UNSIGNED_BYTE, 64, 64
+ );
+ es3fFboRenderTest.createMetaballsTex2D(
+ context, metaballsTex, gl.RGB, gl.UNSIGNED_BYTE, 32, 32
+ );
+
+ /** @type {es3fFboRenderTest.Framebuffer} */
+ var fbo = new es3fFboRenderTest.Framebuffer(
+ context, this.m_config, initialWidth, initialHeight
+ );
+ fbo.checkCompleteness();
+
+ // Setup shaders
+ texToFboShader.setUniforms(context, texToFboShaderID);
+ texFromFboShader.setUniforms(context, texFromFboShaderID);
+ flatShader.setColor(
+ context, flatShaderID, deMath.add(
+ deMath.multiply([0.0, 1.0, 0.0, 1.0], fboOutScale), fboOutBias
+ )
+ );
+
+ // Render quads
+ context.bindFramebuffer(gl.FRAMEBUFFER, fbo.getFramebuffer());
+ context.viewport(0, 0, initialWidth, initialHeight);
+ es3fFboTestUtil.clearColorBuffer(
+ context, colorFormat, [0.0, 0.0, 0.0, 1.0]
+ );
+ context.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ context.bindTexture(gl.TEXTURE_2D, quadsTex);
+ rrUtil.drawQuad(
+ context, texToFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+
+ if (fbo.getConfig().colorType == gl.TEXTURE_2D) {
+ // Render fbo to screen
+ context.bindFramebuffer(gl.FRAMEBUFFER, null);
+ context.viewport(0, 0, context.getWidth(), context.getHeight());
+ context.bindTexture(gl.TEXTURE_2D, fbo.getColorBuffer());
+ rrUtil.drawQuad(
+ context, texFromFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+ // Restore binding
+ context.bindFramebuffer(gl.FRAMEBUFFER, fbo.getFramebuffer());
+ }
+
+ // Resize buffers
+ switch (fbo.getConfig().colorType) {
+ case gl.TEXTURE_2D:
+ context.bindTexture(gl.TEXTURE_2D, fbo.getColorBuffer());
+ context.texImage2DDelegate(
+ gl.TEXTURE_2D, 0, fbo.getConfig().colorFormat,
+ newWidth, newHeight
+ );
+ break;
+
+ case gl.RENDERBUFFER:
+ context.bindRenderbuffer(gl.RENDERBUFFER, fbo.getColorBuffer());
+ context.renderbufferStorage(
+ gl.RENDERBUFFER, fbo.getConfig().colorFormat,
+ newWidth, newHeight
+ );
+ break;
+
+ default:
+ throw new Error('Color type unsupported');
+ }
+
+ if (depth || stencil) {
+ switch (fbo.getConfig().depthStencilType) {
+ case gl.TEXTURE_2D:
+ context.bindTexture(
+ gl.TEXTURE_2D, fbo.getDepthStencilBuffer()
+ );
+ context.texImage2DDelegate(
+ gl.TEXTURE_2D, 0, fbo.getConfig().depthStencilFormat,
+ newWidth, newHeight
+ );
+ break;
+
+ case gl.RENDERBUFFER:
+ context.bindRenderbuffer(
+ gl.RENDERBUFFER, fbo.getDepthStencilBuffer()
+ );
+ context.renderbufferStorage(
+ gl.RENDERBUFFER, fbo.getConfig().depthStencilFormat,
+ newWidth, newHeight
+ );
+ break;
+
+ default:
+ throw new Error('Depth / stencil type unsupported');
+ }
+ }
+
+ // Render to resized fbo
+ context.viewport(0, 0, newWidth, newHeight);
+ es3fFboTestUtil.clearColorBuffer(
+ context, colorFormat, [1.0, 0.0, 0.0, 1.0]
+ );
+ context.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ context.enable(gl.DEPTH_TEST);
+
+ context.bindTexture(gl.TEXTURE_2D, metaballsTex);
+ rrUtil.drawQuad(
+ context, texToFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+
+ context.bindTexture(gl.TEXTURE_2D, quadsTex);
+ rrUtil.drawQuad(
+ context, texToFboShaderID, [0.0, 0.0, -1.0], [1.0, 1.0, 1.0]
+ );
+
+ context.disable(gl.DEPTH_TEST);
+
+ if (stencil) {
+ context.enable(gl.SCISSOR_TEST);
+ context.clearStencil(1);
+ context.scissor(10, 10, 5, 15);
+ context.clear(gl.STENCIL_BUFFER_BIT);
+ context.disable(gl.SCISSOR_TEST);
+
+ context.enable(gl.STENCIL_TEST);
+ context.stencilFunc(gl.EQUAL, 1, 0xff);
+ rrUtil.drawQuad(
+ context, flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+ context.disable(gl.STENCIL_TEST);
+ }
+
+ if (this.m_config.colorType == gl.TEXTURE_2D) {
+ context.bindFramebuffer(gl.FRAMEBUFFER, null);
+ context.viewport(0, 0, context.getWidth(), context.getHeight());
+ context.bindTexture(gl.TEXTURE_2D, fbo.getColorBuffer());
+ rrUtil.drawQuad(
+ context, texFromFboShaderID, [-0.5, -0.5, 0.0], [0.5, 0.5, 0.0]
+ );
+ dst.readViewport(
+ context, [0, 0, context.getWidth(), context.getHeight()]
+ );
+ } else
+ es3fFboTestUtil.readPixels(
+ context, dst, 0, 0, newWidth, newHeight, colorFormat,
+ fboRangeInfo.lookupScale, fboRangeInfo.lookupBias
+ );
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fFboRenderTest.FboRenderCase}
+ * @param {es3fFboRenderTest.FboConfig} config
+ * @param {number} buffers
+ * @param {boolean} rebind
+ */
+ es3fFboRenderTest.RecreateBuffersTest = function(config, buffers, rebind) {
+ es3fFboRenderTest.FboRenderCase.call(
+ this, config.getName() +
+ (rebind ? '' : '_no_rebind'),
+ 'Recreate buffers', config
+ );
+ this.m_buffers = buffers;
+ this.m_rebind = rebind;
+ };
+
+ es3fFboRenderTest.RecreateBuffersTest.prototype =
+ Object.create(es3fFboRenderTest.FboRenderCase.prototype);
+
+ es3fFboRenderTest.RecreateBuffersTest.prototype.construtor =
+ es3fFboRenderTest.RecreateBuffersTest;
+
+ /**
+ * @param {?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext}
+ * ctx
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFboRenderTest.RecreateBuffersTest.prototype.render = function(
+ ctx, dst) {
+
+ /** @type {tcuTexture.TextureFormat} */
+ var colorFormat = gluTextureUtil.mapGLInternalFormat(
+ this.m_config.colorFormat
+ );
+ /** @type {gluShaderUtil.DataType} */
+ var fboSamplerType = gluTextureUtil.getSampler2DType(colorFormat);
+ /** @type {gluShaderUtil.DataType} */
+ var fboOutputType = es3fFboTestUtil.getFragmentOutputType(colorFormat);
+ /** @type {tcuTextureUtil.TextureFormatInfo} */
+ var fboRangeInfo = tcuTextureUtil.getTextureFormatInfo(colorFormat);
+ var fboOutScale = deMath.subtract(
+ fboRangeInfo.valueMax, fboRangeInfo.valueMin
+ );
+ var fboOutBias = fboRangeInfo.valueMin;
+
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texToFboShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D], fboOutputType
+ );
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texFromFboShader = new es3fFboTestUtil.Texture2DShader(
+ [fboSamplerType], gluShaderUtil.DataType.FLOAT_VEC4
+ );
+
+ /** @type {es3fFboTestUtil.FlatColorShader} */
+ var flatShader = new es3fFboTestUtil.FlatColorShader(fboOutputType);
+ /** @type {number} */
+ var texToFboShaderID = ctx.createProgram(texToFboShader);
+ /** @type {number} */
+ var texFromFboShaderID = ctx.createProgram(texFromFboShader);
+ /** @type {number} */
+ var flatShaderID = ctx.createProgram(flatShader);
+
+ var width = 128;
+ var height = 128;
+ var metaballsTex = ctx.createTexture();
+ var quadsTex = ctx.createTexture();
+ var stencil = deMath.binaryOp(
+ this.m_config.buffers, gl.STENCIL_BUFFER_BIT, deMath.BinaryOp.AND
+ ) != 0;
+
+ es3fFboRenderTest.createQuadsTex2D(
+ ctx, quadsTex, gl.RGB, gl.UNSIGNED_BYTE, 64, 64
+ );
+ es3fFboRenderTest.createMetaballsTex2D(
+ ctx, metaballsTex, gl.RGB, gl.UNSIGNED_BYTE, 64, 64
+ );
+
+ /** @type {es3fFboRenderTest.Framebuffer} */
+ var fbo = new es3fFboRenderTest.Framebuffer(
+ ctx, this.m_config, width, height
+ );
+ fbo.checkCompleteness();
+
+ // Setup shaders
+ texToFboShader.setOutScaleBias(fboOutScale, fboOutBias);
+ texFromFboShader.setTexScaleBias(
+ 0, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias
+ );
+ texToFboShader.setUniforms(ctx, texToFboShaderID);
+ texFromFboShader.setUniforms(ctx, texFromFboShaderID);
+ flatShader.setColor(
+ ctx, flatShaderID, deMath.add(
+ deMath.multiply([0.0, 0.0, 1.0, 1.0], fboOutScale
+ ), fboOutBias)
+ );
+
+ // Draw scene
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo.getFramebuffer());
+ ctx.viewport(0, 0, width, height);
+ es3fFboTestUtil.clearColorBuffer(
+ ctx, colorFormat, [1.0, 0.0, 0.0, 1.0]
+ );
+ ctx.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ ctx.enable(gl.DEPTH_TEST);
+
+ ctx.bindTexture(gl.TEXTURE_2D, quadsTex);
+ rrUtil.drawQuad(
+ ctx, texToFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+
+ ctx.disable(gl.DEPTH_TEST);
+
+ if (stencil) {
+ ctx.enable(gl.SCISSOR_TEST);
+ ctx.scissor(
+ Math.floor(width / 4), Math.floor(height / 4),
+ Math.floor(width / 2), Math.floor(height / 2)
+ );
+ ctx.clearStencil(1);
+ ctx.clear(gl.STENCIL_BUFFER_BIT);
+ ctx.disable(gl.SCISSOR_TEST);
+ }
+
+ // Recreate buffers
+ if (!this.m_rebind)
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ assertMsgOptions(
+ deMath.binaryOp(
+ this.m_buffers, deMath.binaryOp(
+ gl.DEPTH_BUFFER_BIT,
+ gl.STENCIL_BUFFER_BIT,
+ deMath.BinaryOp.OR
+ ), deMath.BinaryOp.AND
+ ) == 0 || deMath.binaryOp(
+ this.m_buffers, deMath.binaryOp(
+ gl.DEPTH_BUFFER_BIT,
+ gl.STENCIL_BUFFER_BIT,
+ deMath.BinaryOp.OR
+ ), deMath.BinaryOp.AND
+ ) == deMath.binaryOp(
+ this.m_config.buffers, deMath.binaryOp(
+ gl.DEPTH_BUFFER_BIT,
+ gl.STENCIL_BUFFER_BIT,
+ deMath.BinaryOp.OR
+ ), deMath.BinaryOp.AND
+ ), 'Depth/stencil buffers are not disabled or not ' +
+ 'equal to the config\'s depth/stencil buffer state',
+ false, true
+ );
+
+ // Recreate.
+ for (var ndx = 0; ndx < 2; ndx++) {
+ var bit = ndx == 0 ? gl.COLOR_BUFFER_BIT :
+ (gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ var type = ndx == 0 ? fbo.getConfig().colorType :
+ fbo.getConfig().depthStencilType;
+ var format = ndx == 0 ? fbo.getConfig().colorFormat :
+ fbo.getConfig().depthStencilFormat;
+ var buf = ndx == 0 ? fbo.getColorBuffer() :
+ fbo.getDepthStencilBuffer();
+
+ if (deMath.binaryOp(this.m_buffers, bit, deMath.BinaryOp.AND) == 0)
+ continue;
+
+ switch (type) {
+ case gl.TEXTURE_2D:
+ ctx.deleteTexture(/** @type {WebGLTexture} */ (buf));
+ buf = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, buf);
+ ctx.texImage2DDelegate(
+ gl.TEXTURE_2D, 0, format, width, height
+ );
+ ctx.texParameteri(
+ gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST
+ );
+ ctx.texParameteri(
+ gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST
+ );
+ break;
+
+ case gl.RENDERBUFFER:
+ ctx.deleteRenderbuffer(
+ /** @type {WebGLRenderbuffer} */ (buf)
+ );
+ buf = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, buf);
+ ctx.renderbufferStorage(
+ gl.RENDERBUFFER, format, width, height
+ );
+ break;
+
+ default:
+ throw new Error('Unsupported buffer type');
+ }
+
+ if (ndx == 0) {
+ fbo.m_colorBuffer = buf;
+ } else {
+ fbo.m_depthStencilBuffer = buf;
+ }
+ }
+
+ // Rebind.
+ if (this.m_rebind) {
+ for (var ndx = 0; ndx < 3; ndx++) {
+ var bit = ndx == 0 ? gl.COLOR_BUFFER_BIT :
+ ndx == 1 ? gl.DEPTH_BUFFER_BIT :
+ ndx == 2 ? gl.STENCIL_BUFFER_BIT : 0;
+ var point = ndx == 0 ? gl.COLOR_ATTACHMENT0 :
+ ndx == 1 ? gl.DEPTH_ATTACHMENT :
+ ndx == 2 ? gl.STENCIL_ATTACHMENT : 0;
+ var type = ndx == 0 ? fbo.getConfig().colorType :
+ fbo.getConfig().depthStencilType;
+ var buf = ndx == 0 ? fbo.getColorBuffer() :
+ fbo.getDepthStencilBuffer();
+
+ if (deMath.binaryOp(
+ this.m_buffers, bit, deMath.BinaryOp.AND) == 0)
+ continue;
+
+ switch (type) {
+ case gl.TEXTURE_2D:
+ ctx.framebufferTexture2D(
+ gl.FRAMEBUFFER, point, gl.TEXTURE_2D, buf, 0
+ );
+ break;
+
+ case gl.RENDERBUFFER:
+ ctx.framebufferRenderbuffer(
+ gl.FRAMEBUFFER, point, gl.RENDERBUFFER, buf
+ );
+ break;
+
+ default:
+ throw new Error('Invalid buffer type');
+ }
+ }
+ }
+
+ if (!this.m_rebind)
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo.getFramebuffer());
+
+ ctx.clearStencil(0);
+
+ // \note Clear only buffers that were re-created
+ ctx.clear(
+ deMath.binaryOp(
+ this.m_buffers,
+ deMath.binaryOp(
+ gl.DEPTH_BUFFER_BIT,
+ gl.STENCIL_BUFFER_BIT,
+ deMath.BinaryOp.OR
+ ), deMath.BinaryOp.AND
+ )
+ );
+
+ if (deMath.binaryOp(
+ this.m_buffers, gl.COLOR_BUFFER_BIT, deMath.BinaryOp.AND)) {
+ // Clearing of integer buffers is undefined
+ // so do clearing by rendering flat color.
+ rrUtil.drawQuad(
+ ctx, flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+ }
+
+ ctx.enable(gl.DEPTH_TEST);
+
+ if (stencil) {
+ // \note Stencil test enabled only if we have stencil buffer
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilFunc(gl.EQUAL, 0, 0xff);
+ }
+ ctx.bindTexture(gl.TEXTURE_2D, metaballsTex);
+ rrUtil.drawQuad(
+ ctx, texToFboShaderID, [-1.0, -1.0, 1.0], [1.0, 1.0, -1.0]
+ );
+ if (stencil)
+ ctx.disable(gl.STENCIL_TEST);
+
+ ctx.disable(gl.DEPTH_TEST);
+
+ if (fbo.getConfig().colorType == gl.TEXTURE_2D) {
+ // Unbind fbo
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ // Draw to screen
+ ctx.bindTexture(gl.TEXTURE_2D, fbo.getColorBuffer());
+ ctx.viewport(0, 0, ctx.getWidth(), ctx.getHeight());
+ rrUtil.drawQuad(
+ ctx, texFromFboShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+
+ // Read from screen
+ dst.readViewport(ctx, [0, 0, ctx.getWidth(), ctx.getHeight()]);
+ } else {
+ // Read from fbo
+ es3fFboTestUtil.readPixels(
+ ctx, dst, 0, 0, width, height, colorFormat,
+ fboRangeInfo.lookupScale, fboRangeInfo.lookupBias
+ );
+ }
+ };
+
+ // FboGroups
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fFboRenderTest.FboRenderTestGroup = function() {
+ tcuTestCase.DeqpTest.call(this, 'render', 'Rendering Tests');
+ };
+
+ es3fFboRenderTest.FboRenderTestGroup.prototype =
+ Object.create(tcuTestCase.DeqpTest.prototype);
+
+ es3fFboRenderTest.FboRenderTestGroup.prototype.constructor =
+ es3fFboRenderTest.FboRenderTestGroup;
+
+ /**
+ * @enum {number}
+ */
+ var FormatType = {
+ FLOAT: 0,
+ INT: 1,
+ UINT: 2
+ };
+
+ // Required by specification.
+ /**
+ * @typedef {{format: number, type: FormatType}}
+ */
+ var ColorFormatStruct;
+
+ /**
+ * @typedef {{format: number, depth: boolean, stencil: boolean}}
+ */
+ var DepthStencilFormatStruct;
+
+ /**
+ * init
+ */
+ es3fFboRenderTest.FboRenderTestGroup.prototype.init = function() {
+ var objectTypes = [
+ gl.TEXTURE_2D,
+ gl.RENDERBUFFER
+ ];
+
+ /** @type {Array<ColorFormatStruct>} */ var colorFormats = [{
+ format: gl.RGBA32F, type: FormatType.FLOAT
+ },{
+ format: gl.RGBA32I, type: FormatType.INT
+ },{
+ format: gl.RGBA32UI, type: FormatType.UINT
+ },{
+ format: gl.RGBA16F, type: FormatType.FLOAT
+ },{
+ format: gl.RGBA16I, type: FormatType.INT
+ },{
+ format: gl.RGBA16UI, type: FormatType.UINT
+ },/*{
+ // RGB16F isn't made color-renderable through WebGL's EXT_color_buffer_float
+ format: gl.RGB16F, type: FormatType.FLOAT
+ },*/{
+ format: gl.RGBA8I, type: FormatType.INT
+ },{
+ format: gl.RGBA8UI, type: FormatType.UINT
+ },{
+ format: gl.RGB10_A2UI, type: FormatType.UINT
+ },{
+ format: gl.R11F_G11F_B10F, type: FormatType.FLOAT
+ },{
+ format: gl.RG32F, type: FormatType.FLOAT
+ },{
+ format: gl.RG32I, type: FormatType.INT
+ },{
+ format: gl.RG32UI, type: FormatType.UINT
+ },{
+ format: gl.RG16F, type: FormatType.FLOAT
+ },{
+ format: gl.RG16I, type: FormatType.INT
+ },{
+ format: gl.RG16UI, type: FormatType.UINT
+ },{
+ format: gl.RG8, type: FormatType.FLOAT
+ },{
+ format: gl.RG8I, type: FormatType.INT
+ },{
+ format: gl.RG8UI, type: FormatType.UINT
+ },{
+ format: gl.R32F, type: FormatType.FLOAT
+ },{
+ format: gl.R32I, type: FormatType.INT
+ },{
+ format: gl.R32UI, type: FormatType.UINT
+ },{
+ format: gl.R16F, type: FormatType.FLOAT
+ },{
+ format: gl.R16I, type: FormatType.INT
+ },{
+ format: gl.R16UI, type: FormatType.UINT
+ },{
+ format: gl.R8, type: FormatType.FLOAT
+ },{
+ format: gl.R8I, type: FormatType.INT
+ },{
+ format: gl.R8UI, type: FormatType.UINT
+ }];
+
+ /** @type {Array<DepthStencilFormatStruct>} */
+ var depthStencilFormats = [{
+ format: gl.DEPTH_COMPONENT32F, depth: true, stencil: false
+ },{
+ format: gl.DEPTH_COMPONENT24, depth: true, stencil: false
+ },{
+ format: gl.DEPTH_COMPONENT16, depth: true, stencil: false
+ },{
+ format: gl.DEPTH32F_STENCIL8, depth: true, stencil: true
+ },{
+ format: gl.DEPTH24_STENCIL8, depth: true, stencil: true
+ },{
+ format: gl.STENCIL_INDEX8, depth: false, stencil: true
+ }];
+
+ /** @type {es3fFboRenderTest.FboConfig} */ var config;
+ var colorType;
+ var stencilType;
+ var colorFmt;
+ var depth;
+ var stencil;
+ var depthStencilType;
+ var depthStencilFormat;
+
+ // .stencil_clear
+ /** @type {tcuTestCase.DeqpTest} */
+ var stencilClearGroup = new tcuTestCase.DeqpTest(
+ 'stencil_clear', 'Stencil buffer clears'
+ );
+
+ this.addChild(stencilClearGroup);
+
+ for (var fmtNdx = 0; fmtNdx < depthStencilFormats.length; fmtNdx++) {
+ colorType = gl.TEXTURE_2D;
+ stencilType = gl.RENDERBUFFER;
+ colorFmt = gl.RGBA8;
+
+ if (!depthStencilFormats[fmtNdx].stencil)
+ continue;
+
+ config = new es3fFboRenderTest.FboConfig(
+ gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT,
+ colorType, colorFmt, stencilType,
+ depthStencilFormats[fmtNdx].format
+ );
+ stencilClearGroup.addChild(
+ new es3fFboRenderTest.StencilClearsTest(config)
+ );
+ }
+
+ // .shared_colorbuffer_clear
+ /** @type {tcuTestCase.DeqpTest} */
+ var sharedColorbufferClearGroup = new tcuTestCase.DeqpTest(
+ 'shared_colorbuffer_clear', 'Shader colorbuffer clears'
+ );
+
+ this.addChild(sharedColorbufferClearGroup);
+
+ for (var colorFmtNdx = 0;
+ colorFmtNdx < colorFormats.length;
+ colorFmtNdx++) {
+
+ // Clearing of integer buffers is undefined.
+ if (colorFormats[colorFmtNdx].type == FormatType.INT ||
+ colorFormats[colorFmtNdx].type == FormatType.UINT)
+ continue;
+
+ for (var typeNdx = 0; typeNdx < objectTypes.length; typeNdx++) {
+ config = new es3fFboRenderTest.FboConfig(
+ gl.COLOR_BUFFER_BIT, objectTypes[typeNdx],
+ colorFormats[colorFmtNdx].format, gl.NONE, gl.NONE
+ );
+ sharedColorbufferClearGroup.addChild(
+ new es3fFboRenderTest.SharedColorbufferClearsTest(config)
+ );
+ }
+ }
+
+ // .shared_colorbuffer
+ /** @type {Array<tcuTestCase.DeqpTest>} */ var sharedColorbufferGroup = [];
+ var numSharedColorbufferGroups = 3;
+ for (var ii = 0; ii < numSharedColorbufferGroups; ++ii) {
+ sharedColorbufferGroup[ii] = new tcuTestCase.DeqpTest(
+ 'shared_colorbuffer', 'Shared colorbuffer tests'
+ );
+ this.addChild(sharedColorbufferGroup[ii]);
+ }
+
+ for (var colorFmtNdx = 0; colorFmtNdx < colorFormats.length; colorFmtNdx++) {
+
+ depthStencilType = gl.RENDERBUFFER;
+ depthStencilFormat = gl.DEPTH24_STENCIL8;
+
+ // Blending with integer buffers and fp32 targets is not supported.
+ if (colorFormats[colorFmtNdx].type == FormatType.INT ||
+ colorFormats[colorFmtNdx].type == FormatType.UINT ||
+ colorFormats[colorFmtNdx].format == gl.RGBA32F ||
+ colorFormats[colorFmtNdx].format == gl.RGB32F ||
+ colorFormats[colorFmtNdx].format == gl.RG32F ||
+ colorFormats[colorFmtNdx].format == gl.R32F)
+ continue;
+
+ for (var typeNdx = 0; typeNdx < objectTypes.length; typeNdx++) {
+ /** @type {es3fFboRenderTest.FboConfig} */
+ var colorOnlyConfig = new es3fFboRenderTest.FboConfig(
+ gl.COLOR_BUFFER_BIT, objectTypes[typeNdx],
+ colorFormats[colorFmtNdx].format, gl.NONE, gl.NONE
+ );
+ /** @type {es3fFboRenderTest.FboConfig} */
+ var colorDepthConfig = new es3fFboRenderTest.FboConfig(
+ gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT,
+ objectTypes[typeNdx], colorFormats[colorFmtNdx].format,
+ depthStencilType, depthStencilFormat
+ );
+ /** @type {es3fFboRenderTest.FboConfig} */
+ var colorDepthStencilConfig =
+ new es3fFboRenderTest.FboConfig(
+ gl.COLOR_BUFFER_BIT |
+ gl.DEPTH_BUFFER_BIT |
+ gl.STENCIL_BUFFER_BIT,
+ objectTypes[typeNdx], colorFormats[colorFmtNdx].format,
+ depthStencilType, depthStencilFormat
+ );
+
+ sharedColorbufferGroup[0].addChild(
+ new es3fFboRenderTest.SharedColorbufferTest(colorOnlyConfig)
+ );
+
+ sharedColorbufferGroup[1].addChild(
+ new es3fFboRenderTest.SharedColorbufferTest(
+ colorDepthConfig
+ )
+ );
+
+ sharedColorbufferGroup[2].addChild(
+ new es3fFboRenderTest.SharedColorbufferTest(
+ colorDepthStencilConfig
+ )
+ );
+ }
+ }
+
+ // .shared_depth_stencil
+ /** @type {tcuTestCase.DeqpTest} */
+ var sharedDepthStencilGroup = new tcuTestCase.DeqpTest(
+ 'shared_depth_stencil', 'Shared depth and stencil buffers'
+ );
+
+ this.addChild(sharedDepthStencilGroup);
+
+ for (var fmtNdx = 0; fmtNdx < depthStencilFormats.length; fmtNdx++) {
+ colorType = gl.TEXTURE_2D;
+ colorFmt = gl.RGBA8;
+ depth = depthStencilFormats[fmtNdx].depth;
+ stencil = depthStencilFormats[fmtNdx].stencil;
+
+ if (!depth)
+ continue; // Not verified.
+
+ // Depth and stencil: both rbo and textures
+ for (var typeNdx = 0; typeNdx < objectTypes.length; typeNdx++) {
+ config = new es3fFboRenderTest.FboConfig(
+ gl.COLOR_BUFFER_BIT |
+ (depth ? gl.DEPTH_BUFFER_BIT : 0) |
+ (stencil ? gl.STENCIL_BUFFER_BIT : 0),
+ colorType, colorFmt, objectTypes[typeNdx],
+ depthStencilFormats[fmtNdx].format
+ );
+
+ sharedDepthStencilGroup.addChild(
+ new es3fFboRenderTest.SharedDepthStencilTest(config)
+ );
+ }
+ }
+
+ // .resize
+ /** @type {Array<tcuTestCase.DeqpTest>} */ var resizeGroup = [];
+ var numResizeGroups = 4;
+ for (var ii = 0; ii < numResizeGroups; ++ii) {
+ resizeGroup[ii] = new tcuTestCase.DeqpTest('resize', 'FBO resize tests');
+ this.addChild(resizeGroup[ii]);
+ }
+
+ for (var colorFmtNdx = 0; colorFmtNdx < colorFormats.length; colorFmtNdx++) {
+
+ var colorFormat = colorFormats[colorFmtNdx].format;
+
+ // Color-only.
+ for (var typeNdx = 0; typeNdx < objectTypes.length; typeNdx++) {
+ config = new es3fFboRenderTest.FboConfig(
+ gl.COLOR_BUFFER_BIT, objectTypes[typeNdx],
+ colorFormat, gl.NONE, gl.NONE
+ );
+ resizeGroup[colorFmtNdx % numResizeGroups].addChild(new es3fFboRenderTest.ResizeTest(config));
+ }
+
+ // For selected color formats tests depth & stencil variants.
+ if (colorFormat == gl.RGBA8 || colorFormat == gl.RGBA16F) {
+ for (var depthStencilFmtNdx = 0; depthStencilFmtNdx < depthStencilFormats.length; depthStencilFmtNdx++) {
+
+ colorType = gl.TEXTURE_2D;
+ depth = depthStencilFormats[depthStencilFmtNdx].depth;
+ stencil = depthStencilFormats[depthStencilFmtNdx].stencil;
+
+ // Depth and stencil: both rbo and textures
+ for (var typeNdx = 0; typeNdx < objectTypes.length; typeNdx++) {
+
+ if (!depth && objectTypes[typeNdx] != gl.RENDERBUFFER)
+ continue; // Not supported.
+
+ config = new es3fFboRenderTest.FboConfig(
+ gl.COLOR_BUFFER_BIT |
+ (depth ? gl.DEPTH_BUFFER_BIT : 0) |
+ (stencil ? gl.STENCIL_BUFFER_BIT : 0),
+ colorType, colorFormat, objectTypes[typeNdx],
+ depthStencilFormats[depthStencilFmtNdx].format
+ );
+
+ resizeGroup[colorFmtNdx % numResizeGroups].addChild(
+ new es3fFboRenderTest.ResizeTest(config)
+ );
+ }
+ }
+ }
+ }
+
+ // .recreate_color
+ /** @type {Array<tcuTestCase.DeqpTest>} */ var recreateColorGroup = [];
+ var numRecreateColorGroups = 7;
+ for (var ii = 0; ii < numRecreateColorGroups; ++ii) {
+ recreateColorGroup[ii] = new tcuTestCase.DeqpTest('recreate_color', 'Recreate colorbuffer tests');
+ this.addChild(recreateColorGroup[ii]);
+ }
+
+ for (var colorFmtNdx = 0; colorFmtNdx < colorFormats.length; colorFmtNdx++) {
+
+ colorFormat = colorFormats[colorFmtNdx].format;
+ depthStencilFormat = gl.DEPTH24_STENCIL8;
+ depthStencilType = gl.RENDERBUFFER;
+
+ // Color-only.
+ for (var typeNdx = 0; typeNdx < objectTypes.length; typeNdx++) {
+ config = new es3fFboRenderTest.FboConfig(
+ gl.COLOR_BUFFER_BIT |
+ gl.DEPTH_BUFFER_BIT |
+ gl.STENCIL_BUFFER_BIT,
+ objectTypes[typeNdx], colorFormat,
+ depthStencilType, depthStencilFormat
+ );
+
+ recreateColorGroup[colorFmtNdx % numRecreateColorGroups].addChild(
+ new es3fFboRenderTest.RecreateBuffersTest(
+ config, gl.COLOR_BUFFER_BIT, true /* rebind */
+ )
+ );
+ }
+ }
+
+ // .recreate_depth_stencil
+ /** @type {tcuTestCase.DeqpTest} */
+ var recreateDepthStencilGroup = new tcuTestCase.DeqpTest(
+ 'recreate_depth_stencil', 'Recreate depth and stencil buffers'
+ );
+
+ this.addChild(recreateDepthStencilGroup);
+
+ for (var fmtNdx = 0; fmtNdx < depthStencilFormats.length; fmtNdx++) {
+ colorType = gl.TEXTURE_2D;
+ colorFmt = gl.RGBA8;
+ depth = depthStencilFormats[fmtNdx].depth;
+ stencil = depthStencilFormats[fmtNdx].stencil;
+
+ // Depth and stencil: both rbo and textures
+ for (var typeNdx = 0; typeNdx < objectTypes.length; typeNdx++) {
+ if (!depth && objectTypes[typeNdx] != gl.RENDERBUFFER)
+ continue;
+
+ config = new es3fFboRenderTest.FboConfig(
+ gl.COLOR_BUFFER_BIT |
+ (depth ? gl.DEPTH_BUFFER_BIT : 0) |
+ (stencil ? gl.STENCIL_BUFFER_BIT : 0),
+ colorType, colorFmt, objectTypes[typeNdx],
+ depthStencilFormats[fmtNdx].format
+ );
+
+ recreateDepthStencilGroup.addChild(
+ new es3fFboRenderTest.RecreateBuffersTest(
+ config,
+ (depth ? gl.DEPTH_BUFFER_BIT : 0) |
+ (stencil ? gl.STENCIL_BUFFER_BIT : 0),
+ true /* rebind */
+ )
+ );
+ }
+ }
+ };
+
+ /**
+ * Create and execute the test cases
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fFboRenderTest.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+
+ state.setRoot(new es3fFboRenderTest.FboRenderTestGroup());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboStateQueryTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboStateQueryTests.js
new file mode 100644
index 0000000000..4795790ef4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboStateQueryTests.js
@@ -0,0 +1,796 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fFboStateQueryTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('functional.gles3.es3fApiCase');
+goog.require('modules.shared.glsStateQuery');
+
+goog.scope(function() {
+var es3fFboStateQueryTests = functional.gles3.es3fFboStateQueryTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var glsStateQuery = modules.shared.glsStateQuery;
+var es3fApiCase = functional.gles3.es3fApiCase;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+// WebGL bit depths
+es3fFboStateQueryTests.colorBits = [8, 8, 8, 8];
+es3fFboStateQueryTests.depthBits = 0;
+es3fFboStateQueryTests.stencilBits = 0;
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} framebufferTarget
+ */
+es3fFboStateQueryTests.DefaultFramebufferCase = function(name, description, framebufferTarget) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ this.m_framebufferTarget = framebufferTarget;
+};
+
+setParentClass(es3fFboStateQueryTests.DefaultFramebufferCase, es3fApiCase.ApiCase);
+
+es3fFboStateQueryTests.DefaultFramebufferCase.prototype.test = function() {
+ var hasColorBuffer = es3fFboStateQueryTests.colorBits[0] > 0 ||
+ es3fFboStateQueryTests.colorBits[1] > 0 ||
+ es3fFboStateQueryTests.colorBits[2] > 0 ||
+ es3fFboStateQueryTests.colorBits[3] > 0;
+ var attachments = [
+ gl.BACK,
+ gl.DEPTH,
+ gl.STENCIL
+ ];
+ var attachmentExists = [
+ hasColorBuffer,
+ es3fFboStateQueryTests.depthBits > 0,
+ es3fFboStateQueryTests.stencilBits > 0
+ ];
+
+ for (var ndx = 0; ndx < attachments.length; ++ndx) {
+ var objType = gl.getFramebufferAttachmentParameter(this.m_framebufferTarget, attachments[ndx], gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
+ if (attachmentExists[ndx]) {
+ this.check(objType === gl.FRAMEBUFFER_DEFAULT);
+ } else {
+ // \note [jarkko] FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE "identifes the type of object which contains the attached image". However, it
+ // is unclear if an object of type FRAMEBUFFER_DEFAULT can contain a null image (or a 0-bits-per-pixel image). Accept both
+ // FRAMEBUFFER_DEFAULT and NONE as valid results in these cases.
+ this.check(objType === gl.FRAMEBUFFER_DEFAULT || objType === gl.NONE);
+ }
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fFboStateQueryTests.AttachmentObjectCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fFboStateQueryTests.AttachmentObjectCase, es3fApiCase.ApiCase);
+
+es3fFboStateQueryTests.AttachmentObjectCase.prototype.test = function() {
+ var framebufferID = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebufferID);
+
+ // initial
+ this.check(glsStateQuery.verifyAttachment(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, gl.NONE));
+ this.check(glsStateQuery.verifyAttachment(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, null));
+
+ // texture
+ var textureID = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, textureID);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 128, 128, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureID, 0);
+
+ this.check(glsStateQuery.verifyColorAttachment(gl.FRAMEBUFFER, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, gl.TEXTURE));
+ this.check(glsStateQuery.verifyColorAttachment(gl.FRAMEBUFFER, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, textureID));
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
+
+ // rb
+ var renderbufferID = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbufferID);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB8, 128, 128);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbufferID);
+
+ this.check(glsStateQuery.verifyColorAttachment(gl.FRAMEBUFFER, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, gl.RENDERBUFFER));
+ this.check(glsStateQuery.verifyColorAttachment(gl.FRAMEBUFFER, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, renderbufferID));
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
+ gl.deleteRenderbuffer(renderbufferID);
+
+ gl.deleteFramebuffer(framebufferID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fFboStateQueryTests.AttachmentTextureLevelCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fFboStateQueryTests.AttachmentTextureLevelCase, es3fApiCase.ApiCase);
+
+es3fFboStateQueryTests.AttachmentTextureLevelCase.prototype.test = function() {
+ var framebufferID = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebufferID);
+ for (var mipmapLevel = 0; mipmapLevel < 7; ++mipmapLevel) {
+ var textureID = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, textureID);
+ gl.texStorage2D(gl.TEXTURE_2D, 7, gl.RGB8, 128, 128);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureID, mipmapLevel);
+
+ this.check(glsStateQuery.verifyColorAttachment(gl.FRAMEBUFFER, gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, mipmapLevel));
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
+ gl.deleteTexture(textureID);
+ }
+ gl.deleteFramebuffer(framebufferID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fFboStateQueryTests.AttachmentTextureCubeMapFaceCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fFboStateQueryTests.AttachmentTextureCubeMapFaceCase, es3fApiCase.ApiCase);
+
+es3fFboStateQueryTests.AttachmentTextureCubeMapFaceCase.prototype.test = function() {
+ var framebufferID = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebufferID);
+ var textureID = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, textureID);
+
+ gl.texStorage2D(gl.TEXTURE_CUBE_MAP, 1, gl.RGB8, 128, 128);
+
+ var faces = [
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X, gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
+ ];
+
+ for (var ndx = 0; ndx < faces.length; ++ndx) {
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, faces[ndx], textureID, 0);
+ this.check(glsStateQuery.verifyColorAttachment(gl.FRAMEBUFFER, gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, faces[ndx]));
+ }
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
+ gl.deleteTexture(textureID);
+ gl.deleteFramebuffer(framebufferID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fFboStateQueryTests.AttachmentTextureLayerCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fFboStateQueryTests.AttachmentTextureLayerCase, es3fApiCase.ApiCase);
+
+es3fFboStateQueryTests.AttachmentTextureLayerCase.prototype.test = function() {
+ var framebufferID = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebufferID);
+ // tex3d
+ var textureID = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, textureID);
+ gl.texStorage3D(gl.TEXTURE_3D, 1, gl.RGBA8, 16, 16, 16);
+
+ for (var layer = 0; layer < 16; ++layer) {
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, textureID, 0, layer);
+ this.check(glsStateQuery.verifyColorAttachment(gl.FRAMEBUFFER, gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, layer));
+ }
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
+ gl.deleteTexture(textureID);
+ // tex2d array
+ textureID = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, textureID);
+ gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, 16, 16, 16);
+
+ for (var layer = 0; layer < 16; ++layer) {
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, textureID, 0, layer);
+ this.check(glsStateQuery.verifyColorAttachment(gl.FRAMEBUFFER, gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, layer));
+ }
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
+ gl.deleteTexture(textureID);
+ gl.deleteFramebuffer(framebufferID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fFboStateQueryTests.AttachmentTextureColorCodingCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fFboStateQueryTests.AttachmentTextureColorCodingCase, es3fApiCase.ApiCase);
+
+es3fFboStateQueryTests.AttachmentTextureColorCodingCase.prototype.test = function() {
+ var framebufferID = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebufferID);
+ // rgb8 color
+ var renderbufferID = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbufferID);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB8, 128, 128);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbufferID);
+
+ this.check(glsStateQuery.verifyColorAttachment(gl.FRAMEBUFFER, gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, gl.LINEAR));
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
+ gl.deleteRenderbuffer(renderbufferID);
+
+ // srgb8_alpha8 color
+ renderbufferID = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbufferID);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.SRGB8_ALPHA8, 128, 128);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbufferID);
+
+ this.check(glsStateQuery.verifyColorAttachment(gl.FRAMEBUFFER, gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, gl.SRGB));
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
+ gl.deleteRenderbuffer(renderbufferID);
+
+ // depth
+ renderbufferID = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbufferID);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 128, 128);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbufferID);
+
+ this.check(glsStateQuery.verifyAttachment(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, gl.LINEAR));
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
+ gl.deleteRenderbuffer(renderbufferID);
+ gl.deleteFramebuffer(framebufferID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fFboStateQueryTests.AttachmentTextureComponentTypeCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fFboStateQueryTests.AttachmentTextureComponentTypeCase, es3fApiCase.ApiCase);
+
+es3fFboStateQueryTests.AttachmentTextureComponentTypeCase.prototype.test = function() {
+ var framebufferID = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebufferID);
+ // color-renderable required texture formats
+ var requiredColorformats = [
+ [gl.R8, gl.UNSIGNED_NORMALIZED],
+ [gl.RG8, gl.UNSIGNED_NORMALIZED],
+ [gl.RGB8, gl.UNSIGNED_NORMALIZED],
+ [gl.RGB565, gl.UNSIGNED_NORMALIZED],
+ [gl.RGBA4, gl.UNSIGNED_NORMALIZED],
+ [gl.RGB5_A1, gl.UNSIGNED_NORMALIZED],
+ [gl.RGBA8, gl.UNSIGNED_NORMALIZED],
+ [gl.RGB10_A2, gl.UNSIGNED_NORMALIZED],
+ [gl.RGB10_A2UI, gl.UNSIGNED_INT],
+ [gl.SRGB8_ALPHA8, gl.UNSIGNED_NORMALIZED],
+ [gl.R8I, gl.INT],
+ [gl.R8UI, gl.UNSIGNED_INT],
+ [gl.R16I, gl.INT],
+ [gl.R16UI, gl.UNSIGNED_INT],
+ [gl.R32I, gl.INT],
+ [gl.R32UI, gl.UNSIGNED_INT],
+ [gl.RG8I, gl.INT],
+ [gl.RG8UI, gl.UNSIGNED_INT],
+ [gl.RG16I, gl.INT],
+ [gl.RG16UI, gl.UNSIGNED_INT],
+ [gl.RG32I, gl.INT],
+ [gl.RG32UI, gl.UNSIGNED_INT],
+ [gl.RGBA8I, gl.INT],
+ [gl.RGBA8UI, gl.UNSIGNED_INT],
+ [gl.RGBA16I, gl.INT],
+ [gl.RGBA16UI, gl.UNSIGNED_INT],
+ [gl.RGBA32I, gl.INT],
+ [gl.RGBA32UI, gl.UNSIGNED_INT]
+ ];
+
+ for (var ndx = 0; ndx < requiredColorformats.length; ++ndx) {
+ var colorFormat = requiredColorformats[ndx][0];
+ var componentType = requiredColorformats[ndx][1];
+
+ var textureID = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, textureID);
+ gl.texStorage2D(gl.TEXTURE_2D, 1, colorFormat, 128, 128);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureID, 0);
+
+ this.check(glsStateQuery.verifyColorAttachment(gl.FRAMEBUFFER, gl.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, componentType));
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
+ gl.deleteTexture(textureID);
+ }
+ gl.deleteFramebuffer(framebufferID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fFboStateQueryTests.AttachmentSizeInitialCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fFboStateQueryTests.AttachmentSizeInitialCase, es3fApiCase.ApiCase);
+
+es3fFboStateQueryTests.AttachmentSizeInitialCase.prototype.attachmentExists = function(attachment) {
+ var objType = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, attachment, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE);
+ return objType !== gl.NONE;
+};
+
+/**
+ * @this {es3fApiCase.ApiCase}
+ */
+var checkAttachmentComponentSizeAtLeast = function(target, attachment, r, g, b, a, d, s) {
+ var referenceSizes = [r, g, b, a, d, s];
+ var paramNames = [
+ gl.FRAMEBUFFER_ATTACHMENT_RED_SIZE, gl.FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
+ gl.FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, gl.FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
+ gl.FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, gl.FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE
+ ];
+
+ for (var ndx = 0; ndx < referenceSizes.length; ++ndx) {
+ if (referenceSizes[ndx] == -1)
+ continue;
+
+ var value = /** @type {number} */ (gl.getFramebufferAttachmentParameter(target, attachment, paramNames[ndx]));
+
+ this.check(value >= referenceSizes[ndx], 'Expected greater or equal to ' + referenceSizes[ndx] + ' got ' + value);
+ }
+};
+
+/**
+ * @this {es3fApiCase.ApiCase}
+ */
+var checkAttachmentComponentSizeExactly = function(target, attachment, r, g, b, a, d, s) {
+ var referenceSizes = [r, g, b, a, d, s];
+ var paramNames = [
+ gl.FRAMEBUFFER_ATTACHMENT_RED_SIZE, gl.FRAMEBUFFER_ATTACHMENT_GREEN_SIZE,
+ gl.FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, gl.FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
+ gl.FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, gl.FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE
+ ];
+
+ for (var ndx = 0; ndx < referenceSizes.length; ++ndx) {
+ if (referenceSizes[ndx] == -1)
+ continue;
+
+ var value = gl.getFramebufferAttachmentParameter(target, attachment, paramNames[ndx]);
+
+ this.check(value == referenceSizes[ndx], 'Expected equal to ' + referenceSizes[ndx] + ' got ' + value);
+ }
+};
+
+es3fFboStateQueryTests.AttachmentSizeInitialCase.prototype.test = function() {
+ // check default
+ if (this.attachmentExists(gl.BACK)) {
+ checkAttachmentComponentSizeAtLeast.bind(this,
+ gl.FRAMEBUFFER,
+ gl.BACK,
+ es3fFboStateQueryTests.colorBits[0],
+ es3fFboStateQueryTests.colorBits[1],
+ es3fFboStateQueryTests.colorBits[2],
+ es3fFboStateQueryTests.colorBits[3],
+ -1,
+ -1);
+ }
+
+ if (this.attachmentExists(gl.DEPTH)) {
+ checkAttachmentComponentSizeAtLeast.bind(this,
+ gl.FRAMEBUFFER,
+ gl.DEPTH,
+ -1,
+ -1,
+ -1,
+ -1,
+ es3fFboStateQueryTests.depthBits,
+ -1);
+ }
+
+ if (this.attachmentExists(gl.STENCIL)) {
+ checkAttachmentComponentSizeAtLeast.bind(this,
+ gl.FRAMEBUFFER,
+ gl.STENCIL,
+ -1,
+ -1,
+ -1,
+ -1,
+ -1,
+ es3fFboStateQueryTests.stencilBits);
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fFboStateQueryTests.AttachmentSizeCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fFboStateQueryTests.AttachmentSizeCase, es3fApiCase.ApiCase);
+
+es3fFboStateQueryTests.AttachmentSizeCase.prototype.test = function() {
+ var framebufferID = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebufferID);
+ // check some color targets
+
+ var colorAttachments = [
+ //format, red, green, blue, alpha
+ [gl.RGBA8, 8, 8, 8, 8],
+ [gl.RGB565, 5, 6, 5, 0],
+ [gl.RGBA4, 4, 4, 4, 4],
+ [gl.RGB5_A1, 5, 5, 5, 1],
+ [gl.RGBA8I, 8, 8, 8, 8],
+ [gl.RG32UI, 32, 32, 0, 0]
+ ];
+ for (var ndx = 0; ndx < colorAttachments.length; ++ndx)
+ this.testColorAttachment(colorAttachments[ndx][0], gl.COLOR_ATTACHMENT0, colorAttachments[ndx][1], colorAttachments[ndx][2], colorAttachments[ndx][3], colorAttachments[ndx][4]);
+
+ // check some depth targets
+
+ var depthAttachments = [
+ // format, attachment, depth, stencil
+ [gl.DEPTH_COMPONENT16, gl.DEPTH_ATTACHMENT, 16, 0],
+ [gl.DEPTH_COMPONENT24, gl.DEPTH_ATTACHMENT, 24, 0],
+ [gl.DEPTH_COMPONENT32F, gl.DEPTH_ATTACHMENT, 32, 0],
+ [gl.DEPTH24_STENCIL8, gl.DEPTH_STENCIL_ATTACHMENT, 24, 8],
+ [gl.DEPTH32F_STENCIL8, gl.DEPTH_STENCIL_ATTACHMENT, 32, 8]
+ ];
+ for (var ndx = 0; ndx < depthAttachments.length; ++ndx)
+ this.testDepthAttachment(depthAttachments[ndx][0], depthAttachments[ndx][1], depthAttachments[ndx][2], depthAttachments[ndx][3]);
+ gl.deleteFramebuffer(framebufferID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboStateQueryTests.AttachmentSizeCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fFboStateQueryTests.AttachmentSizeRboCase = function(name, description) {
+ es3fFboStateQueryTests.AttachmentSizeCase.call(this, name, description);
+};
+
+setParentClass(es3fFboStateQueryTests.AttachmentSizeRboCase, es3fFboStateQueryTests.AttachmentSizeCase);
+
+es3fFboStateQueryTests.AttachmentSizeRboCase.prototype.testColorAttachment = function(internalFormat, attachment, r, g, b, a) {
+ var renderbufferID = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbufferID);
+ gl.renderbufferStorage(gl.RENDERBUFFER, internalFormat, 128, 128);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, renderbufferID);
+
+ checkAttachmentComponentSizeAtLeast.bind(this, gl.FRAMEBUFFER, attachment, r, g, b, a, -1, -1);
+ checkAttachmentComponentSizeExactly.bind(this, gl.FRAMEBUFFER, attachment, -1, -1, -1, -1, 0, 0);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, null);
+ gl.deleteRenderbuffer(renderbufferID);
+};
+
+es3fFboStateQueryTests.AttachmentSizeRboCase.prototype.testDepthAttachment = function(internalFormat, attachment, depth, stencil) {
+ var renderbufferID = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbufferID);
+ gl.renderbufferStorage(gl.RENDERBUFFER, internalFormat, 128, 128);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, renderbufferID);
+
+ checkAttachmentComponentSizeAtLeast.bind(this, gl.FRAMEBUFFER, attachment, -1, -1, -1, -1, depth, stencil);
+ checkAttachmentComponentSizeExactly.bind(this, gl.FRAMEBUFFER, attachment, 0, 0, 0, 0, -1, -1);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, null);
+ gl.deleteRenderbuffer(renderbufferID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboStateQueryTests.AttachmentSizeCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fFboStateQueryTests.AttachmentSizeTextureCase = function(name, description) {
+ es3fFboStateQueryTests.AttachmentSizeCase.call(this, name, description);
+};
+
+setParentClass(es3fFboStateQueryTests.AttachmentSizeTextureCase, es3fFboStateQueryTests.AttachmentSizeCase);
+
+es3fFboStateQueryTests.AttachmentSizeTextureCase.prototype.testColorAttachment = function(internalFormat, attachment, r, g, b, a) {
+ var textureID = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, textureID);
+ gl.texStorage2D(gl.TEXTURE_2D, 1, internalFormat, 128, 128);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureID, 0);
+
+ checkAttachmentComponentSizeAtLeast.bind(this, gl.FRAMEBUFFER, attachment, r, g, b, a, -1, -1);
+ checkAttachmentComponentSizeExactly.bind(this, gl.FRAMEBUFFER, attachment, -1, -1, -1, -1, 0, 0);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, null, 0);
+ gl.deleteTexture(textureID);
+};
+
+es3fFboStateQueryTests.AttachmentSizeTextureCase.prototype.testDepthAttachment = function(internalFormat, attachment, depth, stencil) {
+ // don't test stencil formats with textures
+ if (attachment == gl.DEPTH_STENCIL_ATTACHMENT)
+ return;
+
+ var textureID = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, textureID);
+ gl.texStorage2D(gl.TEXTURE_2D, 1, internalFormat, 128, 128);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureID, 0);
+
+ checkAttachmentComponentSizeAtLeast.bind(this, gl.FRAMEBUFFER, attachment, -1, -1, -1, -1, depth, stencil);
+ checkAttachmentComponentSizeExactly.bind(this, gl.FRAMEBUFFER, attachment, 0, 0, 0, 0, -1, -1);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, null, 0);
+ gl.deleteTexture(textureID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fFboStateQueryTests.UnspecifiedAttachmentTextureColorCodingCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fFboStateQueryTests.UnspecifiedAttachmentTextureColorCodingCase, es3fApiCase.ApiCase);
+
+es3fFboStateQueryTests.UnspecifiedAttachmentTextureColorCodingCase.prototype.test = function() {
+ var framebufferID = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebufferID);
+ // color
+ var renderbufferID = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbufferID);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbufferID);
+
+ this.check(glsStateQuery.verifyColorAttachment(gl.FRAMEBUFFER, gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, gl.LINEAR));
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
+ gl.deleteRenderbuffer(renderbufferID);
+
+ // depth
+ renderbufferID = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbufferID);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbufferID);
+
+ this.check(glsStateQuery.verifyAttachment(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, gl.LINEAR));
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
+ gl.deleteRenderbuffer(renderbufferID);
+ gl.deleteFramebuffer(framebufferID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fFboStateQueryTests.UnspecifiedAttachmentSizeCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fFboStateQueryTests.UnspecifiedAttachmentSizeCase, es3fApiCase.ApiCase);
+
+es3fFboStateQueryTests.UnspecifiedAttachmentSizeCase.prototype.test = function() {
+ var framebufferID = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebufferID);
+ // check color target
+ this.testColorAttachment();
+
+ // check depth target
+ this.testDepthAttachment();
+ gl.deleteFramebuffer(framebufferID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboStateQueryTests.UnspecifiedAttachmentSizeCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fFboStateQueryTests.UnspecifiedAttachmentSizeRboCase = function(name, description) {
+ es3fFboStateQueryTests.UnspecifiedAttachmentSizeCase.call(this, name, description);
+};
+
+setParentClass(es3fFboStateQueryTests.UnspecifiedAttachmentSizeRboCase, es3fFboStateQueryTests.UnspecifiedAttachmentSizeCase);
+
+es3fFboStateQueryTests.UnspecifiedAttachmentSizeRboCase.prototype.testColorAttachment = function() {
+ var renderbufferID = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbufferID);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbufferID);
+
+ checkAttachmentComponentSizeExactly.bind(this, gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, 0, 0, 0, 0, 0, 0);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
+ gl.deleteRenderbuffer(renderbufferID);
+};
+
+es3fFboStateQueryTests.UnspecifiedAttachmentSizeRboCase.prototype.testDepthAttachment = function() {
+ var renderbufferID = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbufferID);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbufferID);
+
+ checkAttachmentComponentSizeExactly.bind(this, gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, 0, 0, 0, 0, 0, 0);
+
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, null);
+ gl.deleteRenderbuffer(renderbufferID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fFboStateQueryTests.UnspecifiedAttachmentSizeCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fFboStateQueryTests.UnspecifiedAttachmentSizeTextureCase = function(name, description) {
+ es3fFboStateQueryTests.UnspecifiedAttachmentSizeCase.call(this, name, description);
+};
+
+setParentClass(es3fFboStateQueryTests.UnspecifiedAttachmentSizeTextureCase, es3fFboStateQueryTests.UnspecifiedAttachmentSizeCase);
+
+es3fFboStateQueryTests.UnspecifiedAttachmentSizeTextureCase.prototype.testColorAttachment = function() {
+ var textureID = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, textureID);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureID, 0);
+
+ checkAttachmentComponentSizeExactly.bind(this, gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, 0, 0, 0, 0, 0, 0);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
+ gl.deleteTexture(textureID);
+};
+
+es3fFboStateQueryTests.UnspecifiedAttachmentSizeTextureCase.prototype.testDepthAttachment = function() {
+ var textureID = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, textureID);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, textureID, 0);
+
+ checkAttachmentComponentSizeExactly.bind(this, gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, 0, 0, 0, 0, 0, 0);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, null, 0);
+ gl.deleteTexture(textureID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fFboStateQueryTests.UnspecifiedAttachmentTextureComponentTypeCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fFboStateQueryTests.UnspecifiedAttachmentTextureComponentTypeCase, es3fApiCase.ApiCase);
+
+es3fFboStateQueryTests.UnspecifiedAttachmentTextureComponentTypeCase.prototype.test = function() {
+};
+
+/**
+* @constructor
+* @extends {tcuTestCase.DeqpTest}
+*/
+es3fFboStateQueryTests.FboStateQueryTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'fbo', 'Fbo State Query tests');
+};
+
+es3fFboStateQueryTests.FboStateQueryTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fFboStateQueryTests.FboStateQueryTests.prototype.constructor = es3fFboStateQueryTests.FboStateQueryTests;
+
+es3fFboStateQueryTests.FboStateQueryTests.prototype.init = function() {
+ var red = /** @type {number} */ (gl.getParameter(gl.RED_BITS));
+ var green = /** @type {number} */ (gl.getParameter(gl.GREEN_BITS));
+ var blue = /** @type {number} */ (gl.getParameter(gl.BLUE_BITS));
+ var alpha = /** @type {number} */ (gl.getParameter(gl.ALPHA_BITS));
+ es3fFboStateQueryTests.colorBits = [red, green, blue, alpha];
+ es3fFboStateQueryTests.depthBits = /** @type {number} */ (gl.getParameter(gl.DEPTH_BITS));
+ es3fFboStateQueryTests.stencilBits = /** @type {number} */ (gl.getParameter(gl.STENCIL_BITS));
+
+ this.addChild(new es3fFboStateQueryTests.DefaultFramebufferCase('draw_framebuffer_default_framebuffer', 'default framebuffer', gl.DRAW_FRAMEBUFFER));
+ this.addChild(new es3fFboStateQueryTests.DefaultFramebufferCase('read_framebuffer_default_framebuffer', 'default framebuffer', gl.READ_FRAMEBUFFER));
+ this.addChild(new es3fFboStateQueryTests.AttachmentObjectCase('framebuffer_attachment_object', 'FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE and FRAMEBUFFER_ATTACHMENT_OBJECT_NAME'));
+ this.addChild(new es3fFboStateQueryTests.AttachmentTextureLevelCase('framebuffer_attachment_texture_level', 'FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL'));
+ this.addChild(new es3fFboStateQueryTests.AttachmentTextureCubeMapFaceCase('framebuffer_attachment_texture_cube_map_face', 'FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE'));
+ this.addChild(new es3fFboStateQueryTests.AttachmentTextureLayerCase('framebuffer_attachment_texture_layer', 'FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER'));
+ this.addChild(new es3fFboStateQueryTests.AttachmentTextureColorCodingCase('framebuffer_attachment_color_encoding', 'FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING'));
+ this.addChild(new es3fFboStateQueryTests.AttachmentTextureComponentTypeCase('framebuffer_attachment_component_type', 'FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE'));
+ this.addChild(new es3fFboStateQueryTests.AttachmentSizeInitialCase('framebuffer_attachment_x_size_initial', 'FRAMEBUFFER_ATTACHMENT_x_SIZE'));
+ this.addChild(new es3fFboStateQueryTests.AttachmentSizeRboCase('framebuffer_attachment_x_size_rbo', 'FRAMEBUFFER_ATTACHMENT_x_SIZE'));
+ this.addChild(new es3fFboStateQueryTests.AttachmentSizeTextureCase('framebuffer_attachment_x_size_texture', 'FRAMEBUFFER_ATTACHMENT_x_SIZE'));
+ this.addChild(new es3fFboStateQueryTests.UnspecifiedAttachmentTextureColorCodingCase('framebuffer_unspecified_attachment_color_encoding', 'FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING'));
+ this.addChild(new es3fFboStateQueryTests.UnspecifiedAttachmentTextureComponentTypeCase('framebuffer_unspecified_attachment_component_type', 'FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE'));
+ this.addChild(new es3fFboStateQueryTests.UnspecifiedAttachmentSizeRboCase('framebuffer_unspecified_attachment_x_size_rbo', 'FRAMEBUFFER_ATTACHMENT_x_SIZE'));
+ this.addChild(new es3fFboStateQueryTests.UnspecifiedAttachmentSizeTextureCase('framebuffer_unspecified_attachment_x_size_texture', 'FRAMEBUFFER_ATTACHMENT_x_SIZE'));
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fFboStateQueryTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fFboStateQueryTests.FboStateQueryTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fFboStateQueryTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboStencilbufferTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboStencilbufferTests.js
new file mode 100644
index 0000000000..4cebe7e4a9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboStencilbufferTests.js
@@ -0,0 +1,325 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+'use strict';
+goog.provide('functional.gles3.es3fFboStencilbufferTests');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('framework.referencerenderer.rrUtil');
+goog.require('functional.gles3.es3fFboTestCase');
+goog.require('functional.gles3.es3fFboTestUtil');
+
+goog.scope(function() {
+
+ var es3fFboStencilbufferTests = functional.gles3.es3fFboStencilbufferTests;
+ var es3fFboTestCase = functional.gles3.es3fFboTestCase;
+ var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuTexture = framework.common.tcuTexture;
+ var rrUtil = framework.referencerenderer.rrUtil;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluTextureUtil = framework.opengl.gluTextureUtil;
+
+ /** @type {WebGL2RenderingContext} */ var gl;
+
+ var DE_ASSERT = function(x) {
+ if (!x)
+ throw new Error('Assert failed');
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {Array<number>} size
+ * @param {boolean} useDepth
+ */
+ es3fFboStencilbufferTests.BasicFboStencilCase = function(name, desc, format, size, useDepth) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ /** @type {number} */ this.m_format = format;
+ /** @type {Array<number>} */ this.m_size = size;
+ /** @type {boolean} */ this.m_useDepth = useDepth;
+ };
+
+ es3fFboStencilbufferTests.BasicFboStencilCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
+ es3fFboStencilbufferTests.BasicFboStencilCase.prototype.constructor = es3fFboStencilbufferTests.BasicFboStencilCase;
+
+ es3fFboStencilbufferTests.BasicFboStencilCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_format);
+ return true; // No exception thrown
+ };
+
+ /**
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFboStencilbufferTests.BasicFboStencilCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ /** @const {number} */ var colorFormat = gl.RGBA8;
+
+ /** @type {es3fFboTestUtil.GradientShader} */ var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ /** @type {es3fFboTestUtil.FlatColorShader} */ var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var flatShaderID = this.getCurrentContext().createProgram(flatShader);
+ var gradShaderID = this.getCurrentContext().createProgram(gradShader);
+
+ var fbo = 0;
+ var colorRbo = 0;
+ var depthStencilRbo = 0;
+
+ // Colorbuffer.
+ colorRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.m_size[0], this.m_size[1]);
+
+ // Stencil (and depth) buffer.
+ depthStencilRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_format, this.m_size[0], this.m_size[1]);
+
+ // Framebuffer.
+ fbo = ctx.createFramebuffer();
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
+ if (this.m_useDepth)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthStencilRbo);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.viewport(0, 0, this.m_size[0], this.m_size[1]);
+
+ // Clear framebuffer.
+ ctx.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 0.0, 0.0]);
+ ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0);
+
+ // Render intersecting quads - increment stencil on depth pass
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilFunc(gl.ALWAYS, 0, 0xff);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);
+
+ flatShader.setColor(this.getCurrentContext(), flatShaderID, [1.0, 0.0, 0.0, 1.0]);
+
+ rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]);
+
+ gradShader.setGradient(this.getCurrentContext(), gradShaderID, [0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]);
+
+ rrUtil.drawQuad(this.getCurrentContext(), gradShaderID, [-1.0, -1.0, -1.0], [1.0, 1.0, 1.0]);
+
+ ctx.disable(gl.DEPTH_TEST);
+
+ // Draw quad with stencil test (stencil == 1 or 2 depending on depth) - decrement on stencil failure
+ ctx.stencilFunc(gl.EQUAL, this.m_useDepth ? 2 : 1, 0xff);
+ ctx.stencilOp(gl.DECR, gl.KEEP, gl.KEEP);
+
+ flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 1.0, 0.0, 1.0]);
+
+ rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-0.5, -0.5, 0.0], [0.5, 0.5, 0.0]);
+
+ // Draw quad with stencil test where stencil > 1 or 2 depending on depth buffer
+ ctx.stencilFunc(gl.GREATER, this.m_useDepth ? 1 : 2, 0xff);
+
+ flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 0.0, 1.0, 1.0]);
+
+ rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]);
+
+ this.readPixelsUsingFormat(dst, 0, 0, this.m_size[0], this.m_size[1], gluTextureUtil.mapGLInternalFormat(colorFormat), [1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} attachDepth
+ */
+ es3fFboStencilbufferTests.DepthStencilAttachCase = function(name, desc, attachDepth, attachStencil) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ /** @type {number} */ this.m_attachDepth = attachDepth;
+ /** @type {number} */ this.m_attachStencil = attachStencil;
+ DE_ASSERT(this.m_attachDepth == gl.DEPTH_ATTACHMENT || this.m_attachDepth == gl.DEPTH_STENCIL_ATTACHMENT || this.m_attachDepth == gl.NONE);
+ DE_ASSERT(this.m_attachStencil == gl.STENCIL_ATTACHMENT || this.m_attachStencil == gl.NONE);
+ DE_ASSERT(this.m_attachDepth != gl.DEPTH_STENCIL || this.m_attachStencil == gl.NONE);
+ };
+
+ es3fFboStencilbufferTests.DepthStencilAttachCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
+ es3fFboStencilbufferTests.DepthStencilAttachCase.prototype.constructor = es3fFboStencilbufferTests.DepthStencilAttachCase;
+
+ /**
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFboStencilbufferTests.DepthStencilAttachCase.prototype.render = function(dst) {
+
+ var ctx = this.getCurrentContext();
+ /** @const {number} */ var colorFormat = gl.RGBA8;
+ /** @const {number} */ var depthStencilFormat = gl.DEPTH24_STENCIL8;
+ /** @const {number} */ var width = 128;
+ /** @const {number} */ var height = 128;
+ /** @const {boolean} */ var hasDepth = this.m_attachDepth == gl.DEPTH_STENCIL || this.m_attachDepth == gl.DEPTH_ATTACHMENT;
+ // /** @const {boolean} */ var hasStencil = this.m_attachDepth == gl.DEPTH_STENCIL || this.m_attachStencil == gl.DEPTH_STENCIL_ATTACHMENT); // commented out in original code
+
+ /** @type {es3fFboTestUtil.GradientShader} */ var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ /** @type {es3fFboTestUtil.FlatColorShader} */ var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var flatShaderID = this.getCurrentContext().createProgram(flatShader);
+ var gradShaderID = this.getCurrentContext().createProgram(gradShader);
+
+ var fbo = 0;
+ var colorRbo = 0;
+ var depthStencilRbo = 0;
+
+ // Colorbuffer.
+ colorRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, colorRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, width, height);
+
+ // Depth-stencil buffer.
+ depthStencilRbo = ctx.createRenderbuffer();
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, depthStencilRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, depthStencilFormat, width, height);
+
+ // Framebuffer.
+ fbo = ctx.createFramebuffer();
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRbo);
+
+ if (this.m_attachDepth != gl.NONE)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, this.m_attachDepth, gl.RENDERBUFFER, depthStencilRbo);
+ if (this.m_attachStencil != gl.NONE)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, this.m_attachStencil, gl.RENDERBUFFER, depthStencilRbo);
+
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.viewport(0, 0, width, height);
+
+ // Clear framebuffer.
+ ctx.clearBufferfv(gl.COLOR, 0, [0.0, 0.0, 0.0, 0.0]);
+ ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0);
+
+ // Render intersecting quads - increment stencil on depth pass
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilFunc(gl.ALWAYS, 0, 0xff);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);
+
+ flatShader.setColor(this.getCurrentContext(), flatShaderID, [1.0, 0.0, 0.0, 1.0]);
+
+ rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]);
+
+ gradShader.setGradient(this.getCurrentContext(), gradShaderID, [0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]);
+
+ rrUtil.drawQuad(this.getCurrentContext(), gradShaderID, [-1.0, -1.0, -1.0], [1.0, 1.0, 1.0]);
+
+ ctx.disable(gl.DEPTH_TEST);
+
+ // Draw quad with stencil test (stencil == 1 or 2 depending on depth) - decrement on stencil failure
+ ctx.stencilFunc(gl.EQUAL, hasDepth ? 2 : 1, 0xff);
+ ctx.stencilOp(gl.DECR, gl.KEEP, gl.KEEP);
+
+ flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 1.0, 0.0, 1.0]);
+
+ rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-0.5, -0.5, 0.0], [0.5, 0.5, 0.0]);
+
+ // Draw quad with stencil test where stencil > 1 or 2 depending on depth buffer
+ ctx.stencilFunc(gl.GREATER, hasDepth ? 1 : 2, 0xff);
+
+ flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 0.0, 1.0, 1.0]);
+
+ rrUtil.drawQuad(this.getCurrentContext(), flatShaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]);
+
+ this.readPixelsUsingFormat(dst, 0, 0, width, height, gluTextureUtil.mapGLInternalFormat(colorFormat), [1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]);
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fFboStencilbufferTests.FboStencilTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'stencil', 'FBO Stencilbuffer tests');
+ };
+
+ es3fFboStencilbufferTests.FboStencilTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fFboStencilbufferTests.FboStencilTests.prototype.constructor = es3fFboStencilbufferTests.FboStencilTests;
+
+ es3fFboStencilbufferTests.FboStencilTests.prototype.init = function() {
+ /** @const {Array<number>} */ var stencilFormats = [
+ gl.DEPTH32F_STENCIL8,
+ gl.DEPTH24_STENCIL8,
+ gl.STENCIL_INDEX8
+ ];
+
+ // .basic
+ /** @type {tcuTestCase.DeqpTest} */
+ var basicGroup = tcuTestCase.newTest('basic', 'Basic stencil tests');
+ this.addChild(basicGroup);
+
+ for (var fmtNdx = 0; fmtNdx < stencilFormats.length; fmtNdx++) {
+ /** @type {number} */ var format = stencilFormats[fmtNdx];
+ /** @type {tcuTexture.TextureFormat} */ var texFmt = gluTextureUtil.mapGLInternalFormat(format);
+
+ basicGroup.addChild(new es3fFboStencilbufferTests.BasicFboStencilCase(es3fFboTestUtil.getFormatName(format), '', format, [111, 132], false));
+
+ if (texFmt.order == tcuTexture.ChannelOrder.DS)
+ basicGroup.addChild(new es3fFboStencilbufferTests.BasicFboStencilCase(es3fFboTestUtil.getFormatName(format) + '_depth', '', format, [111, 132], true));
+ }
+
+ // .attach
+ /** @type {tcuTestCase.DeqpTest} */
+ var attachGroup = tcuTestCase.newTest('attach', 'Attaching depth stencil');
+ this.addChild(attachGroup);
+
+ attachGroup.addChild(new es3fFboStencilbufferTests.DepthStencilAttachCase('depth_only', 'Only depth part of depth-stencil RBO attached', gl.DEPTH_ATTACHMENT, gl.NONE));
+ attachGroup.addChild(new es3fFboStencilbufferTests.DepthStencilAttachCase('stencil_only', 'Only stencil part of depth-stencil RBO attached', gl.NONE, gl.STENCIL_ATTACHMENT));
+ attachGroup.addChild(new es3fFboStencilbufferTests.DepthStencilAttachCase('depth_stencil_separate', 'Depth and stencil attached separately', gl.DEPTH_ATTACHMENT, gl.STENCIL_ATTACHMENT));
+ attachGroup.addChild(new es3fFboStencilbufferTests.DepthStencilAttachCase('depth_stencil_attachment', 'Depth and stencil attached with DEPTH_STENCIL_ATTACHMENT', gl.DEPTH_STENCIL_ATTACHMENT, gl.NONE));
+ };
+
+ es3fFboStencilbufferTests.run = function(context) {
+ gl = context;
+ //Set up root Test
+ var state = tcuTestCase.runner;
+
+ var test = new es3fFboStencilbufferTests.FboStencilTests();
+ var testName = test.fullName();
+ var testDescription = test.getDescription();
+
+ state.testName = testName;
+ state.setRoot(test);
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ test.init();
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fFboStencilbufferTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboTestCase.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboTestCase.js
new file mode 100644
index 0000000000..cdaa7d352f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboTestCase.js
@@ -0,0 +1,483 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fFboTestCase');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuPixelFormat');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.simplereference.sglrGLContext');
+goog.require('framework.opengl.simplereference.sglrReferenceContext');
+goog.require('framework.referencerenderer.rrRenderer');
+goog.require('functional.gles3.es3fFboTestUtil');
+
+goog.scope(function() {
+
+var es3fFboTestCase = functional.gles3.es3fFboTestCase;
+var tcuTestCase = framework.common.tcuTestCase;
+var deMath = framework.delibs.debase.deMath;
+var tcuSurface = framework.common.tcuSurface;
+var tcuTexture = framework.common.tcuTexture;
+var rrRenderer = framework.referencerenderer.rrRenderer;
+var sglrReferenceContext = framework.opengl.simplereference.sglrReferenceContext;
+var tcuPixelFormat = framework.common.tcuPixelFormat;
+var tcuImageCompare = framework.common.tcuImageCompare;
+var deString = framework.delibs.debase.deString;
+var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
+var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
+var deRandom = framework.delibs.debase.deRandom;
+
+/** @typedef {(sglrGLContext.GLContext | WebGL2RenderingContext | sglrReferenceContext.ReferenceContext)} */
+es3fFboTestCase.Context;
+
+var DE_ASSERT = function(x) {
+ if (!x)
+ throw new Error('Assert failed');
+};
+
+ /**
+ * es3fFboTestCase.FboTestCase class, inherits from TestCase and sglrContextWrapper
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ * @param {boolean=} useScreenSizedViewport
+ */
+ es3fFboTestCase.FboTestCase = function(name, description, useScreenSizedViewport /*= false */) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ /** @type {number} */ this.m_viewportWidth = useScreenSizedViewport === undefined ? gl.drawingBufferWidth : 128;
+ /** @type {number} */ this.m_viewportHeight = useScreenSizedViewport === undefined ? gl.drawingBufferHeight : 128;
+ /** @type {es3fFboTestCase.Context} */ this.m_curCtx = null;
+ };
+
+ es3fFboTestCase.FboTestCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fFboTestCase.FboTestCase.prototype.constructor = es3fFboTestCase.FboTestCase;
+
+ es3fFboTestCase.FboTestCase.prototype.getWidth = function() {
+ return Math.min(gl.drawingBufferWidth, this.m_viewportWidth);
+ };
+
+ es3fFboTestCase.FboTestCase.prototype.getHeight = function() {
+ return Math.min(gl.drawingBufferHeight, this.m_viewportHeight);
+ };
+
+ /**
+ * Sets the current context (inherited from sglrContextWrapper)
+ * @param {es3fFboTestCase.Context} context
+ */
+ es3fFboTestCase.FboTestCase.prototype.setContext = function(context) {
+ this.m_curCtx = context;
+ };
+
+ /**
+ * Gets the current context (inherited from sglrContextWrapper)
+ * @return {es3fFboTestCase.Context}
+ */
+ es3fFboTestCase.FboTestCase.prototype.getCurrentContext = function() {
+ return this.m_curCtx;
+ };
+
+ /**
+ * @param {tcuSurface.Surface} reference
+ * @param {tcuSurface.Surface} result
+ */
+ es3fFboTestCase.FboTestCase.prototype.compare = function(reference, result) {
+ return tcuImageCompare.fuzzyCompare('Result', 'Image comparison result', reference.getAccess(), result.getAccess(), 0.05, tcuImageCompare.CompareLogMode.RESULT);
+ };
+
+ /**
+ * @param {number} sizedFormat
+ */
+ es3fFboTestCase.FboTestCase.prototype.checkFormatSupport = function(sizedFormat) {
+ /** @const @type {boolean} */ var isCoreFormat = es3fFboTestCase.isRequiredFormat(sizedFormat);
+ /** @const @type {Array<string>} */ var requiredExts = (!isCoreFormat) ? es3fFboTestCase.getEnablingExtensions(sizedFormat) : [];
+
+ // Check that we don't try to use invalid formats.
+ DE_ASSERT(isCoreFormat || requiredExts);
+ if (requiredExts.length > 0 && !es3fFboTestCase.isAnyExtensionSupported(gl, requiredExts)) {
+ var msg = 'SKIP: Format ' + WebGLTestUtils.glEnumToString(gl, sizedFormat) + ' not supported';
+ debug(msg);
+ throw new TestFailedException(msg);
+ }
+ };
+
+ /**
+ * @param {number} sizedFormat deUint32
+ * @param {number} numSamples
+ */
+ es3fFboTestCase.FboTestCase.prototype.checkSampleCount = function(sizedFormat, numSamples) {
+ /** @const @type {number} */ var minSampleCount = es3fFboTestCase.getMinimumSampleCount(sizedFormat);
+
+ if (numSamples > minSampleCount) {
+ // Exceeds spec-mandated minimum - need to check.
+ /** @const @type {goog.NumberArray} */ var supportedSampleCounts = es3fFboTestCase.querySampleCounts(sizedFormat);
+ var supported = Array.prototype.slice.call(supportedSampleCounts);
+ if (supported.indexOf(numSamples) == -1) {
+ if (minSampleCount == 0 || numSamples > gl.getParameter(gl.MAX_SAMPLES)) {
+ checkMessage(false, "Sample count not supported, but it is allowed.");
+ return false;
+ } else {
+ throw new Error('Sample count not supported');
+ }
+ }
+ return true;
+ }
+ return true;
+ };
+
+ /**
+ * @param {tcuSurface.Surface} dst
+ * @param {number} x
+ * @param {number} y
+ * @param {number} width
+ * @param {number} height
+ * @param {tcuTexture.TextureFormat} format
+ * @param {Array<number>} scale Vec4
+ * @param {Array<number>} bias Vec4
+ */
+ es3fFboTestCase.FboTestCase.prototype.readPixelsUsingFormat = function(dst, x, y, width, height, format, scale, bias) {
+ dst.setSize(width, height);
+ es3fFboTestUtil.readPixels(this.getCurrentContext(), dst, x, y, width, height, format, scale, bias);
+ };
+
+ /**
+ * @param {tcuSurface.Surface} dst
+ * @param {number} x
+ * @param {number} y
+ * @param {number} width
+ * @param {number} height
+ */
+ es3fFboTestCase.FboTestCase.prototype.readPixels = function(dst, x, y, width, height) {
+ dst.readViewport(this.getCurrentContext(), [x, y, width, height]);
+ };
+
+ /**
+ * @param {number} target
+ */
+ es3fFboTestCase.FboTestCase.prototype.checkFramebufferStatus = function(target) {
+ /** @type {number} */ var status = this.getCurrentContext().checkFramebufferStatus(target);
+ if (status != gl.FRAMEBUFFER_COMPLETE)
+ throw new Error('Framebuffer Status: ' + WebGLTestUtils.glEnumToString(gl, status));
+ };
+
+ es3fFboTestCase.FboTestCase.prototype.checkError = function() {
+ /** @type {number} */ var err = this.getCurrentContext().getError();
+ if (err != gl.NO_ERROR)
+ throw new Error('glError: ' + WebGLTestUtils.glEnumToString(gl, err));
+ };
+
+ /**
+ * @param {tcuTexture.TextureFormat} format
+ * @param {Array<number>=} value Vec4
+ */
+ es3fFboTestCase.FboTestCase.prototype.clearColorBuffer = function(format, value) {
+ if (value === undefined) value = [0.0, 0.0, 0.0, 0.0];
+ es3fFboTestUtil.clearColorBuffer(this.getCurrentContext(), format, value);
+ };
+
+ es3fFboTestCase.FboTestCase.prototype.iterate = function() {
+ // Viewport.
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name));
+ /** @type {number} */ var width = Math.min(gl.drawingBufferWidth, this.m_viewportWidth);
+ /** @type {number} */ var height = Math.min(gl.drawingBufferHeight, this.m_viewportHeight);
+ /** @type {number} */ var x = rnd.getInt(0, gl.drawingBufferWidth - width);
+ /** @type {number} */ var y = rnd.getInt(0, gl.drawingBufferHeight - height);
+
+ // Surface format and storage is choosen by render().
+ /** @type {tcuSurface.Surface} */ var reference = new tcuSurface.Surface(width, height);
+ /** @type {tcuSurface.Surface} */ var result = new tcuSurface.Surface(width, height);
+
+ // Call preCheck() that can throw exception if some requirement is not met.
+ if (this.preCheck && !this.preCheck())
+ return tcuTestCase.IterateResult.STOP;
+
+ // Render using GLES3.
+ try {
+ /** @type {sglrGLContext.GLContext} */ var context = new sglrGLContext.GLContext(
+ gl,
+ [x, y, width, height]);
+
+ this.setContext(context);
+ this.render(result);
+
+ // Check error.
+ /** @type {number} */ var err = context.getError();
+ if (err != gl.NO_ERROR)
+ throw new Error('glError: ' + context);
+
+ this.setContext(null);
+ } catch (e) {
+ if (e instanceof es3fFboTestUtil.FboIncompleteException)
+ if (e.getReason() == gl.FRAMEBUFFER_UNSUPPORTED) {
+ // log << e;
+ // m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, 'Not supported');
+ assertMsgOptions(false, 'Not supported', true, false);
+ return tcuTestCase.IterateResult.STOP;
+ }
+ throw e;
+ }
+
+ // Render reference.
+ var alphaBits = /** @type {number} */ (gl.getParameter(gl.ALPHA_BITS));
+ /** @type {sglrReferenceContext.ReferenceContextBuffers} */
+ var buffers = new sglrReferenceContext.ReferenceContextBuffers(new tcuPixelFormat.PixelFormat(
+ 8,
+ 8,
+ 8,
+ alphaBits > 0 ? 8 : 0),
+ /** @type {number} */ (gl.getParameter(gl.DEPTH_BITS)),
+ /** @type {number} */ (gl.getParameter(gl.STENCIL_BITS)),
+ width,
+ height);
+ /** @type {sglrReferenceContext.ReferenceContext} */
+ var refContext = new sglrReferenceContext.ReferenceContext(new sglrReferenceContext.ReferenceContextLimits(gl),
+ buffers.getColorbuffer(),
+ buffers.getDepthbuffer(),
+ buffers.getStencilbuffer());
+ refContext.getError();
+ this.setContext(refContext);
+ this.render(reference);
+ this.setContext(null);
+
+ /** @type {boolean} */ var isOk = this.compare(reference, result);
+
+ assertMsgOptions(isOk, '', true, false);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * Deinit. Clear some GL state variables
+ */
+ es3fFboTestCase.FboTestCase.prototype.deinit = function () {
+ // Pixel operations
+ {
+ gl.disable(gl.SCISSOR_TEST);
+
+ gl.disable(gl.STENCIL_TEST);
+ gl.stencilFunc(gl.ALWAYS, 0, 0xffff);
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
+
+ gl.disable(gl.DEPTH_TEST);
+ gl.depthFunc(gl.LESS);
+
+ gl.disable(gl.BLEND);
+ gl.blendFunc(gl.ONE, gl.ZERO);
+ gl.blendEquation(gl.FUNC_ADD);
+ gl.blendColor(0.0, 0.0, 0.0, 0.0);
+
+ gl.enable(gl.DITHER);
+ }
+
+ // Framebuffer control
+ {
+ gl.colorMask(true, true, true, true);
+ gl.depthMask(true);
+ gl.stencilMask(0xffff);
+
+ gl.clearColor(0.0, 0.0, 0.0, 0.0);
+ gl.clearDepth(1.0);
+ gl.clearStencil(0.0);
+ // Do not call clear() here because it might generate an INVALID_OPERATION if
+ // some color buffers are of integer formats due to WebGL2 specific constraint.
+ // The tests do not rely on clear() here.
+ }
+ };
+
+ /**
+ * @param {number} format
+ * @return {boolean}
+ */
+ es3fFboTestCase.isRequiredFormat = function(format) {
+ switch (format) {
+ // Color-renderable formats
+ case gl.RGBA32I:
+ case gl.RGBA32UI:
+ case gl.RGBA16I:
+ case gl.RGBA16UI:
+ case gl.RGBA8:
+ case gl.RGBA8I:
+ case gl.RGBA8UI:
+ case gl.SRGB8_ALPHA8:
+ case gl.RGB10_A2:
+ case gl.RGB10_A2UI:
+ case gl.RGBA4:
+ case gl.RGB5_A1:
+ case gl.RGB8:
+ case gl.RGB565:
+ case gl.RG32I:
+ case gl.RG32UI:
+ case gl.RG16I:
+ case gl.RG16UI:
+ case gl.RG8:
+ case gl.RG8I:
+ case gl.RG8UI:
+ case gl.R32I:
+ case gl.R32UI:
+ case gl.R16I:
+ case gl.R16UI:
+ case gl.R8:
+ case gl.R8I:
+ case gl.R8UI:
+ return true;
+
+ // Depth formats
+ case gl.DEPTH_COMPONENT32F:
+ case gl.DEPTH_COMPONENT24:
+ case gl.DEPTH_COMPONENT16:
+ return true;
+
+ // Depth+stencil formats
+ case gl.DEPTH32F_STENCIL8:
+ case gl.DEPTH24_STENCIL8:
+ return true;
+
+ // Stencil formats
+ case gl.STENCIL_INDEX8:
+ return true;
+
+ default:
+ return false;
+ }
+ };
+
+ /**
+ * @param {number} format deUint32
+ * @return {Array<string>}
+ */
+ es3fFboTestCase.getEnablingExtensions = function(format) {
+ /** @return {Array<string>} */ var out = [];
+
+ DE_ASSERT(!es3fFboTestCase.isRequiredFormat(format));
+
+ switch (format) {
+ case gl.RGBA16F:
+ case gl.RG16F:
+ case gl.R16F:
+ case gl.RGBA32F:
+ case gl.RGB32F:
+ case gl.R11F_G11F_B10F:
+ case gl.RG32F:
+ case gl.R32F:
+ out.push('EXT_color_buffer_float');
+ break;
+ case gl.RGB16F:
+ // EXT_color_buffer_half_float is not exposed in WebGL 2.0.
+ break;
+ default:
+ break;
+ }
+
+ return out;
+ };
+
+ /**
+ * @param {es3fFboTestCase.Context} context
+ * @param {Array<string>} requiredExts
+ * @return {boolean}
+ */
+ es3fFboTestCase.isAnyExtensionSupported = function(context, requiredExts) {
+ for (var iter in requiredExts) {
+ /** @const @type {string} */ var extension = requiredExts[iter];
+
+ if (sglrGLContext.isExtensionSupported(gl, extension)) {
+ // enable the extension
+ gl.getExtension(extension);
+ return true;
+ }
+ }
+
+ return false;
+ };
+
+/**
+ * @param {number} format GL format
+ * @return {number}
+ */
+es3fFboTestCase.getMinimumSampleCount = function(format) {
+ switch (format) {
+ // Core formats
+ case gl.RGBA32I:
+ case gl.RGBA32UI:
+ case gl.RGBA16I:
+ case gl.RGBA16UI:
+ case gl.RGBA8:
+ case gl.RGBA8I:
+ case gl.RGBA8UI:
+ case gl.SRGB8_ALPHA8:
+ case gl.RGB10_A2:
+ case gl.RGB10_A2UI:
+ case gl.RGBA4:
+ case gl.RGB5_A1:
+ case gl.RGB8:
+ case gl.RGB565:
+ case gl.RG32I:
+ case gl.RG32UI:
+ case gl.RG16I:
+ case gl.RG16UI:
+ case gl.RG8:
+ case gl.RG8I:
+ case gl.RG8UI:
+ case gl.R32I:
+ case gl.R32UI:
+ case gl.R16I:
+ case gl.R16UI:
+ case gl.R8:
+ case gl.R8I:
+ case gl.R8UI:
+ case gl.DEPTH_COMPONENT32F:
+ case gl.DEPTH_COMPONENT24:
+ case gl.DEPTH_COMPONENT16:
+ case gl.DEPTH32F_STENCIL8:
+ case gl.DEPTH24_STENCIL8:
+ case gl.STENCIL_INDEX8:
+ return 4;
+
+ // gl.EXT_color_buffer_float
+ case gl.R11F_G11F_B10F:
+ case gl.RG16F:
+ case gl.R16F:
+ return 4;
+
+ case gl.RGBA32F:
+ case gl.RGBA16F:
+ case gl.RG32F:
+ case gl.R32F:
+ return 0;
+
+ // gl.EXT_color_buffer_half_float
+ case gl.RGB16F:
+ return 0;
+
+ default:
+ throw new Error('Unknown format:' + format);
+ }
+};
+
+es3fFboTestCase.querySampleCounts = function(format) {
+ return gl.getInternalformatParameter(gl.RENDERBUFFER, format, gl.SAMPLES);
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboTestUtil.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboTestUtil.js
new file mode 100644
index 0000000000..ed152a43e4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFboTestUtil.js
@@ -0,0 +1,1324 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fFboTestUtil');
+goog.require('framework.common.tcuMatrix');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('framework.opengl.simplereference.sglrGLContext');
+goog.require('framework.opengl.simplereference.sglrReferenceContext');
+goog.require('framework.opengl.simplereference.sglrShaderProgram');
+goog.require('framework.referencerenderer.rrFragmentOperations');
+goog.require('framework.referencerenderer.rrGenericVector');
+goog.require('framework.referencerenderer.rrShadingContext');
+goog.require('framework.referencerenderer.rrVertexAttrib');
+goog.require('framework.referencerenderer.rrVertexPacket');
+
+goog.scope(function() {
+
+var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
+var tcuTexture = framework.common.tcuTexture;
+var tcuTextureUtil = framework.common.tcuTextureUtil;
+var tcuRGBA = framework.common.tcuRGBA;
+var gluTextureUtil = framework.opengl.gluTextureUtil;
+var deMath = framework.delibs.debase.deMath;
+var rrShadingContext = framework.referencerenderer.rrShadingContext;
+var rrVertexPacket = framework.referencerenderer.rrVertexPacket;
+var rrVertexAttrib = framework.referencerenderer.rrVertexAttrib;
+var gluShaderUtil = framework.opengl.gluShaderUtil;
+var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
+var sglrReferenceContext = framework.opengl.simplereference.sglrReferenceContext;
+var sglrShaderProgram = framework.opengl.simplereference.sglrShaderProgram;
+var rrGenericVector = framework.referencerenderer.rrGenericVector;
+var tcuMatrix = framework.common.tcuMatrix;
+var rrFragmentOperations = framework.referencerenderer.rrFragmentOperations;
+var tcuSurface = framework.common.tcuSurface;
+
+var DE_ASSERT = function(x) {
+ if (!x)
+ throw new Error('Assert failed');
+};
+
+/**
+ * Defines the exception type for a test failure.
+ * @constructor
+ * @param {number} reason The error code.
+ */
+es3fFboTestUtil.FboIncompleteException = function(reason) {
+ this.reason = reason;
+ this.name = 'es3fFboTestUtil.FboIncompleteException';
+};
+
+/** @typedef { (WebGL2RenderingContext|sglrReferenceContext.ReferenceContext)} */
+es3fFboTestUtil.Context;
+
+es3fFboTestUtil.FboIncompleteException.prototype.getReason = function() {return this.reason; };
+
+ /**
+ * @param {gluShaderUtil.DataType} type
+ * @return {rrGenericVector.GenericVecType}
+ */
+ es3fFboTestUtil.mapDataTypeToGenericVecType = function(type) {
+ switch (type) {
+ case gluShaderUtil.DataType.FLOAT_VEC4: return rrGenericVector.GenericVecType.FLOAT;
+ case gluShaderUtil.DataType.INT_VEC4: return rrGenericVector.GenericVecType.INT32;
+ case gluShaderUtil.DataType.UINT_VEC4: return rrGenericVector.GenericVecType.UINT32;
+ default:
+ throw new Error('Unrecognized type: ' + type);
+ }
+ };
+
+ /**
+ * @param {Array<number>} input
+ * @param {{max: number, min: number}} type min, max information
+ * @return {Array<number>}
+ */
+ es3fFboTestUtil.castVectorSaturate = function(input, type) {
+ return [
+ (input[0] + 0.5 >= type.max) ? (type.max) : ((input[0] - 0.5 <= type.min) ? (type.min) : Math.round(input[0])),
+ (input[1] + 0.5 >= type.max) ? (type.max) : ((input[1] - 0.5 <= type.min) ? (type.min) : Math.round(input[1])),
+ (input[2] + 0.5 >= type.max) ? (type.max) : ((input[2] - 0.5 <= type.min) ? (type.min) : Math.round(input[2])),
+ (input[3] + 0.5 >= type.max) ? (type.max) : ((input[3] - 0.5 <= type.min) ? (type.min) : Math.round(input[3]))
+ ];
+ };
+
+ /**
+ * es3fFboTestUtil.FlatColorShader inherits from sglrShaderProgram
+ * @constructor
+ * @extends {sglrShaderProgram.ShaderProgram}
+ * @param {gluShaderUtil.DataType} outputType
+ * @param {number=} pointSize
+ */
+ es3fFboTestUtil.FlatColorShader = function(outputType, pointSize) {
+ pointSize = pointSize || 1;
+ /** @type {sglrShaderProgram.ShaderProgramDeclaration} */
+ var decl = new sglrShaderProgram.ShaderProgramDeclaration();
+ /** @type {gluShaderUtil.DataType} */ this.m_outputType = outputType;
+
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
+ decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
+ decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(es3fFboTestUtil.mapDataTypeToGenericVecType(outputType)));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_color', gluShaderUtil.DataType.FLOAT_VEC4));
+ decl.pushVertexSource(new sglrShaderProgram.VertexSource(
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ ' gl_PointSize = ' + pointSize + '.0;\n' +
+ '}\n'));
+ decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(
+ '#version 300 es\n' +
+ 'uniform highp vec4 u_color;\n' +
+ 'layout(location = 0) out highp ' + gluShaderUtil.getDataTypeName(outputType) + ' o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = ' + gluShaderUtil.getDataTypeName(outputType) + '(u_color);\n' +
+ '}\n'));
+ sglrShaderProgram.ShaderProgram.call(this, decl);
+ this.m_pointSize = pointSize;
+ };
+
+ es3fFboTestUtil.FlatColorShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
+ es3fFboTestUtil.FlatColorShader.prototype.constructor = es3fFboTestUtil.FlatColorShader;
+
+ /**
+ * @param {(WebGL2RenderingContext|sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext)} context
+ * @param program GL program object
+ * @param {Array<number>} color
+ */
+ es3fFboTestUtil.FlatColorShader.prototype.setColor = function(context, program, color) {
+ /** @type {number} */ var location = context.getUniformLocation(program, 'u_color');
+
+ context.useProgram(program);
+ context.uniform4fv(location, color);
+ };
+
+ /**
+ * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
+ * @param {Array<rrVertexPacket.VertexPacket>} packets
+ * @param {number} numPackets
+ */
+ es3fFboTestUtil.FlatColorShader.prototype.shadeVertices = function(inputs, packets, numPackets) {
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
+ /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
+ packet.position = rrVertexAttrib.readVertexAttrib(inputs[0], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
+ packet.pointSize = this.m_pointSize;
+ }
+ };
+
+ /**
+ * @param {Array<rrFragmentOperations.Fragment>} packet
+ * @param {rrShadingContext.FragmentShadingContext} context
+ */
+ es3fFboTestUtil.FlatColorShader.prototype.shadeFragments = function(packet, context) {
+ var numPackets = packet.length;
+ /** @const {Array<number>} */ var color = this.m_uniforms[0].value;
+ /** @const {Array<number>} */ var icolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deInt32);
+ /** @const {Array<number>} */ var uicolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deUint32);
+
+ if (this.m_outputType == gluShaderUtil.DataType.FLOAT_VEC4) {
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx)
+ packet[packetNdx].value = color;
+ } else if (this.m_outputType == gluShaderUtil.DataType.INT_VEC4) {
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx)
+ packet[packetNdx].value = icolor;
+ } else if (this.m_outputType == gluShaderUtil.DataType.UINT_VEC4) {
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx)
+ packet[packetNdx].value = uicolor;
+ } else
+ throw new Error('Invalid output type: ' + this.m_outputType);
+ };
+
+ /**
+ * es3fFboTestUtil.GradientShader inherits from sglrShaderProgram
+ * @constructor
+ * @extends {sglrShaderProgram.ShaderProgram}
+ * @param {gluShaderUtil.DataType} outputType
+ */
+ es3fFboTestUtil.GradientShader = function(outputType) {
+ /** @type {sglrShaderProgram.ShaderProgramDeclaration} */
+ var decl = new sglrShaderProgram.ShaderProgramDeclaration();
+ /** @type {gluShaderUtil.DataType} */ this.m_outputType = outputType;
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_coord', rrGenericVector.GenericVecType.FLOAT));
+ decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
+ decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(es3fFboTestUtil.mapDataTypeToGenericVecType(outputType)));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_gradientMin', gluShaderUtil.DataType.FLOAT_VEC4));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_gradientMax', gluShaderUtil.DataType.FLOAT_VEC4));
+ decl.pushVertexSource(new sglrShaderProgram.VertexSource(
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in highp vec4 a_coord;\n' +
+ 'out highp vec4 v_coord;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ ' v_coord = a_coord;\n' +
+ '}\n'));
+ decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(
+ '#version 300 es\n' +
+ 'in highp vec4 v_coord;\n' +
+ 'uniform highp vec4 u_gradientMin;\n' +
+ 'uniform highp vec4 u_gradientMax;\n' +
+ 'layout(location = 0) out highp ' + gluShaderUtil.getDataTypeName(outputType) + ' o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' highp float x = v_coord.x;\n' +
+ ' highp float y = v_coord.y;\n' +
+ ' highp float f0 = (x + y) * 0.5;\n' +
+ ' highp float f1 = 0.5 + (x - y) * 0.5;\n' +
+ ' highp vec4 fv = vec4(f0, f1, 1.0f-f0, 1.0f-f1);\n' +
+ ' o_color = ' + gluShaderUtil.getDataTypeName(outputType) + '(u_gradientMin + (u_gradientMax-u_gradientMin)*fv);\n' +
+ '}\n'));
+ sglrShaderProgram.ShaderProgram.call(this, decl);
+ };
+
+ es3fFboTestUtil.GradientShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
+ es3fFboTestUtil.GradientShader.prototype.constructor = es3fFboTestUtil.GradientShader;
+
+ /**
+ * @param {es3fFboTestUtil.Context} ctx GL-like context
+ * @param program GL program
+ * @param {Array<number>} gradientMin
+ * @param {Array<number>} gradientMax
+ */
+ es3fFboTestUtil.GradientShader.prototype.setGradient = function(ctx, program, gradientMin, gradientMax) {
+ ctx.useProgram(program);
+ ctx.uniform4fv(ctx.getUniformLocation(program, 'u_gradientMin'), gradientMin);
+ ctx.uniform4fv(ctx.getUniformLocation(program, 'u_gradientMax'), gradientMax);
+ };
+
+ /**
+ * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
+ * @param {Array<rrVertexPacket.VertexPacket>} packets
+ * @param {number} numPackets
+ */
+ es3fFboTestUtil.GradientShader.prototype.shadeVertices = function(inputs, packets, numPackets) {
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
+ /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
+
+ packet.position = rrVertexAttrib.readVertexAttrib(inputs[0], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
+ packet.outputs[0] = rrVertexAttrib.readVertexAttrib(inputs[1], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
+ }
+ };
+
+ /**
+ * @param {Array<rrFragmentOperations.Fragment>} packet
+ * @param {rrShadingContext.FragmentShadingContext} context
+ */
+ es3fFboTestUtil.GradientShader.prototype.shadeFragments = function(packet, context) {
+ var numPackets = packet.length;
+ /** @const {Array<number>} */ var gradientMin = this.m_uniforms[0].value;
+ /** @const {Array<number>} */ var gradientMax = this.m_uniforms[1].value;
+
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
+ /** @const {Array<number>} */ var coord = rrShadingContext.readTriangleVarying(packet[packetNdx], context, 0);
+ /** @const {number} */ var x = coord[0];
+ /** @const {number} */ var y = coord[1];
+ /** @const {number} */ var f0 = (x + y) * 0.5;
+ /** @const {number} */ var f1 = 0.5 + (x - y) * 0.5;
+ /** @const {Array<number>} */ var fv = [f0, f1, 1.0 - f0, 1.0 - f1];
+
+ /** @const {Array<number>} */ var color = deMath.add(gradientMin, deMath.multiply(deMath.subtract(gradientMax, gradientMin), fv));
+ /** @const {Array<number>} */ var icolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deInt32);
+ /** @const {Array<number>} */ var uicolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deUint32);
+
+ if (this.m_outputType == gluShaderUtil.DataType.FLOAT_VEC4)
+ packet[packetNdx].value = color;
+ else if (this.m_outputType == gluShaderUtil.DataType.INT_VEC4)
+ packet[packetNdx].value = icolor;
+ else if (this.m_outputType == gluShaderUtil.DataType.UINT_VEC4)
+ packet[packetNdx].value = uicolor;
+ else
+ throw new Error('Invalid output type: ' + this.m_outputType);
+ }
+ };
+
+ /**
+ * @param {Array<gluShaderUtil.DataType>} samplerTypes
+ * @param {gluShaderUtil.DataType} outputType
+ * @return {string}
+ */
+ es3fFboTestUtil.genTexFragmentShader = function(samplerTypes, outputType) {
+ /** @type {string} */ var precision = 'highp';
+ /** @type {string} */ var src = '';
+
+ src = '#version 300 es\n' +
+ 'layout(location = 0) out highp ' + gluShaderUtil.getDataTypeName(outputType) + ' o_color0;\n' +
+ 'in highp vec2 v_coord;\n';
+
+ for (var samplerNdx = 0; samplerNdx < samplerTypes.length; samplerNdx++) {
+ src += 'uniform ' + precision + ' ' + gluShaderUtil.getDataTypeName(samplerTypes[samplerNdx]) + ' u_sampler' + samplerNdx + ';\n' +
+ 'uniform ' + precision + ' vec4 u_texScale' + samplerNdx + ';\n' +
+ 'uniform ' + precision + ' vec4 u_texBias' + samplerNdx + ';\n';
+ }
+
+ // Output scale & bias
+ src += 'uniform ' + precision + ' vec4 u_outScale0;\n' +
+ 'uniform ' + precision + ' vec4 u_outBias0;\n';
+
+ src += '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ' + precision + ' vec4 out0 = vec4(0.0);\n';
+
+ // Texture input fetch and combine.
+ for (var inNdx = 0; inNdx < samplerTypes.length; inNdx++)
+ src += '\tout0 += vec4(' +
+ 'texture(u_sampler' + inNdx + ', v_coord)) * u_texScale' + inNdx + ' + u_texBias' + inNdx + ';\n';
+
+ // Write output.
+ src += ' o_color0 = ' + gluShaderUtil.getDataTypeName(outputType) + '(out0 * u_outScale0 + u_outBias0);\n' +
+ '}\n';
+
+ return src;
+ };
+
+ /**
+ * @param {Array<gluShaderUtil.DataType>} samplerTypes
+ * @param {gluShaderUtil.DataType} outputType
+ * @return {sglrShaderProgram.ShaderProgramDeclaration}
+ */
+ es3fFboTestUtil.genTexture2DShaderDecl = function(samplerTypes, outputType) {
+ /** @type {sglrShaderProgram.ShaderProgramDeclaration} */
+ var decl = new sglrShaderProgram.ShaderProgramDeclaration();
+
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_coord', rrGenericVector.GenericVecType.FLOAT));
+ decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
+ decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(es3fFboTestUtil.mapDataTypeToGenericVecType(outputType)));
+
+ decl.pushVertexSource(new sglrShaderProgram.VertexSource(
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in highp vec2 a_coord;\n' +
+ 'out highp vec2 v_coord;\n' +
+ 'void main(void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ ' v_coord = a_coord;\n' +
+ '}\n'));
+
+ decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(es3fFboTestUtil.genTexFragmentShader(samplerTypes, outputType)));
+
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_outScale0', gluShaderUtil.DataType.FLOAT_VEC4));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_outBias0', gluShaderUtil.DataType.FLOAT_VEC4));
+
+ for (var ndx = 0; ndx < samplerTypes.length; ++ndx) {
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_sampler' + ndx, samplerTypes[ndx]));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_texScale' + ndx, gluShaderUtil.DataType.FLOAT_VEC4));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_texBias' + ndx, gluShaderUtil.DataType.FLOAT_VEC4));
+ }
+
+ return decl;
+ };
+
+ /**
+ * For use in es3fFboTestUtil.Texture2DShader
+ * @constructor
+ */
+ es3fFboTestUtil.Input = function() {
+ /** @type {number} */ this.unitNdx;
+ /** @type {Array<number>} */ this.scale;
+ /** @type {Array<number>} */ this.bias;
+ };
+
+ /**
+ * es3fFboTestUtil.Texture2DShader inherits from sglrShaderProgram
+ * @constructor
+ * @extends {sglrShaderProgram.ShaderProgram}
+ * @param {Array<gluShaderUtil.DataType>} samplerTypes
+ * @param {gluShaderUtil.DataType} outputType
+ * @param {Array<number>=} outScale - default [1.0, 1.0, 1.0, 1.0]
+ * @param {Array<number>=} outBias - default [0.0, 0.0, 0.0, 0.0]
+ */
+ es3fFboTestUtil.Texture2DShader = function(samplerTypes, outputType, outScale, outBias) {
+ if (outScale === undefined) outScale = [1.0, 1.0, 1.0, 1.0];
+ if (outBias === undefined) outBias = [0.0, 0.0, 0.0, 0.0];
+ sglrShaderProgram.ShaderProgram.call(this, es3fFboTestUtil.genTexture2DShaderDecl(samplerTypes, outputType));
+ /** @type {Array<es3fFboTestUtil.Input>} */ this.m_inputs = [];
+ /** @type {Array<number>} */ this.m_outScale = outScale;
+ /** @type {Array<number>} */ this.m_outBias = outBias;
+ /** @const {gluShaderUtil.DataType} */ this.m_outputType = outputType;
+ for (var ndx = 0; ndx < samplerTypes.length; ndx++) {
+ var input = new es3fFboTestUtil.Input();
+ input.unitNdx = ndx;
+ input.scale = [1.0, 1.0, 1.0, 1.0];
+ input.bias = [0.0, 0.0, 0.0, 0.0];
+ this.m_inputs[ndx] = input;
+ }
+ };
+
+ es3fFboTestUtil.Texture2DShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
+ es3fFboTestUtil.Texture2DShader.prototype.constructor = es3fFboTestUtil.Texture2DShader;
+
+ /**
+ * @param {number} inputNdx
+ * @param {number} unitNdx
+ */
+ es3fFboTestUtil.Texture2DShader.prototype.setUnit = function(inputNdx, unitNdx) {
+ this.m_inputs[inputNdx].unitNdx = unitNdx;
+ };
+
+ /**
+ * @param {number} inputNdx
+ * @param {Array<number>} scale
+ * @param {Array<number>} bias
+ */
+ es3fFboTestUtil.Texture2DShader.prototype.setTexScaleBias = function(inputNdx, scale, bias) {
+ this.m_inputs[inputNdx].scale = scale;
+ this.m_inputs[inputNdx].bias = bias;
+ };
+
+ /**
+ * @param {Array<number>} scale
+ * @param {Array<number>} bias
+ */
+ es3fFboTestUtil.Texture2DShader.prototype.setOutScaleBias = function(scale, bias) {
+ this.m_outScale = scale;
+ this.m_outBias = bias;
+ };
+
+ /**
+ * @param context GL-like context
+ * @param program
+ */
+ es3fFboTestUtil.Texture2DShader.prototype.setUniforms = function(context, program) {
+ context.useProgram(program);
+
+ for (var texNdx = 0; texNdx < this.m_inputs.length; texNdx++) {
+ /** @type {string} */ var samplerName = 'u_sampler' + texNdx;
+ /** @type {string} */ var scaleName = 'u_texScale' + texNdx;
+ /** @type {string} */ var biasName = 'u_texBias' + texNdx;
+
+ context.uniform1i(context.getUniformLocation(program, samplerName), this.m_inputs[texNdx].unitNdx);
+ context.uniform4fv(context.getUniformLocation(program, scaleName), this.m_inputs[texNdx].scale);
+ context.uniform4fv(context.getUniformLocation(program, biasName), this.m_inputs[texNdx].bias);
+ }
+
+ context.uniform4fv(context.getUniformLocation(program, 'u_outScale0'), this.m_outScale);
+ context.uniform4fv(context.getUniformLocation(program, 'u_outBias0'), this.m_outBias);
+ };
+
+ /**
+ * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
+ * @param {Array<rrVertexPacket.VertexPacket>} packets
+ * @param {number} numPackets
+ */
+ es3fFboTestUtil.Texture2DShader.prototype.shadeVertices = function(inputs, packets, numPackets) {
+ // TODO: implement rrVertexAttrib.readVertexAttribFloat
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
+ /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
+ packet.position = rrVertexAttrib.readVertexAttrib(inputs[0], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
+ packet.outputs[0] = rrVertexAttrib.readVertexAttrib(inputs[1], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
+ }
+ };
+
+ /**
+ * @param {Array<rrFragmentOperations.Fragment>} packet
+ * @param {rrShadingContext.FragmentShadingContext} context
+ */
+ es3fFboTestUtil.Texture2DShader.prototype.shadeFragments = function(packet, context) {
+ var numPackets = packet.length;
+ /** @type {Array<number>} */ var outScale = this.m_uniforms[0].value;
+ /** @type {Array<number>} */ var outBias = this.m_uniforms[1].value;
+ var texCoords = [];
+ var colors = [];
+
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
+ // setup tex coords
+ /** @const {Array<number>} */ var coord = rrShadingContext.readTriangleVarying(packet[packetNdx], context, 0);
+ texCoords = [coord[0], coord[1]];
+
+ // clear result
+ colors = [0.0, 0.0, 0.0, 0.0];
+
+ // sample each texture
+ for (var ndx = 0; ndx < this.m_inputs.length; ndx++) {
+ var tex = this.m_uniforms[2 + ndx * 3].sampler;
+ var ratioX = tex.m_view.getWidth() / context.getWidth();
+ var ratioY = tex.m_view.getHeight() / context.getHeight();
+ var lod = Math.floor(Math.log2(Math.max(ratioX, ratioY)));
+
+ /** @const {Array<number>} */ var scale = this.m_uniforms[2 + ndx * 3 + 1].value;
+ /** @const {Array<number>} */ var bias = this.m_uniforms[2 + ndx * 3 + 2].value;
+
+ var tmpColors = tex.sample(texCoords, lod);
+
+ colors = deMath.add(colors, deMath.add(deMath.multiply(tmpColors, scale), bias));
+ }
+
+ // write out
+ /** @const {Array<number>} */ var color = deMath.add(deMath.multiply(colors, outScale), outBias);
+ /** @const {Array<number>} */ var icolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deInt32);
+ /** @const {Array<number>} */ var uicolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deUint32);
+
+ if (this.m_outputType == gluShaderUtil.DataType.FLOAT_VEC4)
+ packet[packetNdx].value = color;
+ else if (this.m_outputType == gluShaderUtil.DataType.INT_VEC4)
+ packet[packetNdx].value = icolor;
+ else if (this.m_outputType == gluShaderUtil.DataType.UINT_VEC4)
+ packet[packetNdx].value = uicolor;
+ }
+ };
+
+ /**
+ * es3fFboTestUtil.TextureCubeShader inherits from sglrShaderProgram
+ * @constructor
+ * @extends {sglrShaderProgram.ShaderProgram}
+ * @param {gluShaderUtil.DataType} samplerType
+ * @param {gluShaderUtil.DataType} outputType
+ */
+ es3fFboTestUtil.TextureCubeShader = function(samplerType, outputType) {
+ /** @type {sglrShaderProgram.ShaderProgramDeclaration} */
+ var decl = new sglrShaderProgram.ShaderProgramDeclaration();
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_coord', rrGenericVector.GenericVecType.FLOAT));
+ decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
+ decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(es3fFboTestUtil.mapDataTypeToGenericVecType(outputType)));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_coordMat', gluShaderUtil.DataType.FLOAT_MAT3));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_sampler0', samplerType));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_scale', gluShaderUtil.DataType.FLOAT_VEC4));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_bias', gluShaderUtil.DataType.FLOAT_VEC4));
+ decl.pushVertexSource(new sglrShaderProgram.VertexSource(
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in mediump vec2 a_coord;\n' +
+ 'uniform mat3 u_coordMat;\n' +
+ 'out mediump vec3 v_coord;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ ' v_coord = u_coordMat * vec3(a_coord, 1.0);\n' +
+ '}\n'));
+ decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(
+ '#version 300 es\n' +
+ 'uniform highp ' + gluShaderUtil.getDataTypeName(samplerType) + ' u_sampler0;\n' +
+ 'uniform highp vec4 u_scale;\n' +
+ 'uniform highp vec4 u_bias;\n' +
+ 'in mediump vec3 v_coord;\n' +
+ 'layout(location = 0) out highp ' + gluShaderUtil.getDataTypeName(outputType) + ' o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = ' + gluShaderUtil.getDataTypeName(outputType) + '(vec4(texture(u_sampler0, v_coord)) * u_scale + u_bias);\n' +
+ '}\n'));
+ sglrShaderProgram.ShaderProgram.call(this, decl);
+ /** @type {Array<number>} */ this.m_texScale = [1.0, 1.0, 1.0, 1.0];
+ /** @type {Array<number>} */ this.m_texBias = [0.0, 0.0, 0.0, 0.0];
+ /** @type {tcuMatrix.Mat3} */ this.m_coordMat;
+ /** @type {gluShaderUtil.DataType} */ this.m_outputType = outputType;
+ };
+
+ es3fFboTestUtil.TextureCubeShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
+ es3fFboTestUtil.TextureCubeShader.prototype.constructor = es3fFboTestUtil.TextureCubeShader;
+
+ /**
+ * @param {tcuTexture.CubeFace} face
+ */
+ es3fFboTestUtil.TextureCubeShader.prototype.setFace = function(face) {
+ /** @const {Array<Array<number>>} */ var s_cubeTransforms = [
+ // Face -X: (x, y, 1) -> (-1, -(2*y-1), +(2*x-1))
+ [0, 0, -1,
+ 0, -2, 1,
+ 2, 0, -1],
+ // Face +X: (x, y, 1) -> (+1, -(2*y-1), -(2*x-1))
+ [0, 0, 1,
+ 0, -2, 1,
+ -2, 0, 1],
+ // Face -Y: (x, y, 1) -> (+(2*x-1), -1, -(2*y-1))
+ [2, 0, -1,
+ 0, 0, -1,
+ 0, -2, 1],
+ // Face +Y: (x, y, 1) -> (+(2*x-1), +1, +(2*y-1))
+ [2, 0, -1,
+ 0, 0, 1,
+ 0, 2, -1],
+ // Face -Z: (x, y, 1) -> (-(2*x-1), -(2*y-1), -1)
+ [-2, 0, 1,
+ 0, -2, 1,
+ 0, 0, -1],
+ // Face +Z: (x, y, 1) -> (+(2*x-1), -(2*y-1), +1)
+ [2, 0, -1,
+ 0, -2, 1,
+ 0, 0, 1]];
+ this.m_coordMat = /** @type {tcuMatrix.Mat3} */ (tcuMatrix.matrixFromArray(3, 3, s_cubeTransforms[face]));
+ };
+
+ /**
+ * @param {Array<number>} scale
+ * @param {Array<number>} bias
+ */
+ es3fFboTestUtil.TextureCubeShader.prototype.setTexScaleBias = function(scale, bias) {
+ this.m_texScale = scale;
+ this.m_texBias = bias;
+ };
+
+ /**
+ * @param ctx GL-like context
+ * @param program
+ */
+ es3fFboTestUtil.TextureCubeShader.prototype.setUniforms = function(ctx, program) {
+ ctx.useProgram(program);
+
+ ctx.uniform1i(ctx.getUniformLocation(program, 'u_sampler0'), 0);
+ ctx.uniformMatrix3fv(ctx.getUniformLocation(program, 'u_coordMat'), false, this.m_coordMat.getColumnMajorData());
+ ctx.uniform4fv(ctx.getUniformLocation(program, 'u_scale'), this.m_texScale);
+ ctx.uniform4fv(ctx.getUniformLocation(program, 'u_bias'), this.m_texBias);
+ };
+
+ /**
+ * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
+ * @param {Array<rrVertexPacket.VertexPacket>} packets
+ * @param {number} numPackets
+ */
+ es3fFboTestUtil.TextureCubeShader.prototype.shadeVertices = function(inputs, packets, numPackets) {
+ /** @type {tcuMatrix.Matrix} */ var texCoordMat = tcuMatrix.matrixFromArray(3, 3, this.m_uniforms[0].value);
+
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
+ /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
+ var x = rrVertexAttrib.readVertexAttrib(inputs[1], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT)[0];
+ var y = rrVertexAttrib.readVertexAttrib(inputs[1], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT)[1];
+ /** @type {Array<number>} */ var a_coord = [x, y];
+ /** @type {Array<number>} */ var v_coord = tcuMatrix.multiplyMatVec(texCoordMat, [a_coord[0], a_coord[1], 1.0]);
+
+ packet.position = rrVertexAttrib.readVertexAttrib(inputs[0], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
+ packet.outputs[0] = [v_coord[0], v_coord[1], v_coord[2], 0.0];
+ }
+ };
+
+ /**
+ * @param {Array<rrFragmentOperations.Fragment>} packet
+ * @param {rrShadingContext.FragmentShadingContext} context
+ */
+ es3fFboTestUtil.TextureCubeShader.prototype.shadeFragments = function(packet, context) {
+ var numPackets = packet.length;
+ /** @const {Array<number>} */ var texScale = this.m_uniforms[2].value;
+ /** @const {Array<number>} */ var texBias = this.m_uniforms[3].value;
+
+ var texCoords = [];
+ var colors = [];
+
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
+ var tex = this.m_uniforms[1].sampler;
+ var ratioX = tex.m_view.getSize() / context.getWidth();
+ var ratioY = tex.m_view.getSize() / context.getHeight();
+ var lod = Math.floor(Math.log2(Math.max(ratioX, ratioY)));
+
+ var coord = rrShadingContext.readTriangleVarying(packet[packetNdx], context, 0);
+ texCoords = [coord[0], coord[1], coord[2]];
+
+ colors = tex.sample(texCoords, lod);
+
+ var color = deMath.add(deMath.multiply(colors, texScale), texBias);
+ var icolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deInt32);
+ var uicolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deUint32);
+
+ if (this.m_outputType == gluShaderUtil.DataType.FLOAT_VEC4)
+ packet[packetNdx].value = color;
+ else if (this.m_outputType == gluShaderUtil.DataType.INT_VEC4)
+ packet[packetNdx].value = icolor;
+ else if (this.m_outputType == gluShaderUtil.DataType.UINT_VEC4)
+ packet[packetNdx].value = uicolor;
+ }
+ };
+
+ /**
+ * es3fFboTestUtil.Texture2DArrayShader inherits from sglrShaderProgram
+ * @constructor
+ * @extends {sglrShaderProgram.ShaderProgram}
+ * @param {gluShaderUtil.DataType} samplerType
+ * @param {gluShaderUtil.DataType} outputType
+ */
+ es3fFboTestUtil.Texture2DArrayShader = function(samplerType, outputType) {
+ /** @type {sglrShaderProgram.ShaderProgramDeclaration} */
+ var decl = new sglrShaderProgram.ShaderProgramDeclaration();
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_coord', rrGenericVector.GenericVecType.FLOAT));
+ decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
+ decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(es3fFboTestUtil.mapDataTypeToGenericVecType(outputType)));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_sampler0', samplerType));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_scale', gluShaderUtil.DataType.FLOAT_VEC4));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_bias', gluShaderUtil.DataType.FLOAT_VEC4));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_layer', gluShaderUtil.DataType.INT));
+ decl.pushVertexSource(new sglrShaderProgram.VertexSource(
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in highp vec2 a_coord;\n' +
+ 'out highp vec2 v_coord;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ ' v_coord = a_coord;\n' +
+ '}\n'));
+ decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(
+ '#version 300 es\n' +
+ 'uniform highp ' + gluShaderUtil.getDataTypeName(samplerType) + ' u_sampler0;\n' +
+ 'uniform highp vec4 u_scale;\n' +
+ 'uniform highp vec4 u_bias;\n' +
+ 'uniform highp int u_layer;\n' +
+ 'in highp vec2 v_coord;\n' +
+ 'layout(location = 0) out highp ' + gluShaderUtil.getDataTypeName(outputType) + ' o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = ' + gluShaderUtil.getDataTypeName(outputType) + '(vec4(texture(u_sampler0, vec3(v_coord, u_layer))) * u_scale + u_bias);\n' +
+ '}\n'));
+ sglrShaderProgram.ShaderProgram.call(this, decl);
+ /** @type {Array<number>} */ this.m_texScale = [1.0, 1.0, 1.0, 1.0];
+ /** @type {Array<number>} */ this.m_texBias = [0.0, 0.0, 0.0, 0.0];
+ /** @type {number} */ this.m_layer = 0;
+ /** @type {gluShaderUtil.DataType} */ this.m_outputType = outputType;
+ };
+
+ es3fFboTestUtil.Texture2DArrayShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
+ es3fFboTestUtil.Texture2DArrayShader.prototype.constructor = es3fFboTestUtil.Texture2DArrayShader;
+
+ /**
+ * @param {number} layer
+ */
+ es3fFboTestUtil.Texture2DArrayShader.prototype.setLayer = function(layer) {
+ this.m_layer = layer;
+ };
+ /**
+ * @param {Array<number>} scale
+ * @param {Array<number>} bias
+ */
+ es3fFboTestUtil.Texture2DArrayShader.prototype.setTexScaleBias = function(scale, bias) {
+ this.m_texScale = scale;
+ this.m_texBias = bias;
+ };
+ /**
+ * @param {es3fFboTestUtil.Context} ctx GL-like context
+ * @param program
+ */
+ es3fFboTestUtil.Texture2DArrayShader.prototype.setUniforms = function(ctx, program) {
+ ctx.useProgram(program);
+
+ ctx.uniform1i(ctx.getUniformLocation(program, 'u_sampler0'), 0);
+ ctx.uniform1i(ctx.getUniformLocation(program, 'u_layer'), this.m_layer);
+ ctx.uniform4fv(ctx.getUniformLocation(program, 'u_scale'), this.m_texScale);
+ ctx.uniform4fv(ctx.getUniformLocation(program, 'u_bias'), this.m_texBias);
+ };
+
+ /**
+ * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
+ * @param {Array<rrVertexPacket.VertexPacket>} packets
+ * @param {number} numPackets
+ */
+ es3fFboTestUtil.Texture2DArrayShader.prototype.shadeVertices = function(inputs, packets, numPackets) {
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
+ /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
+
+ packet.position = rrVertexAttrib.readVertexAttrib(inputs[0], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
+ packet.outputs[0] = rrVertexAttrib.readVertexAttrib(inputs[1], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
+ }
+ };
+
+ /**
+ * @param {Array<rrFragmentOperations.Fragment>} packet
+ * @param {rrShadingContext.FragmentShadingContext} context
+ */
+ es3fFboTestUtil.Texture2DArrayShader.prototype.shadeFragments = function(packet, context) {
+ var numPackets = packet.length;
+ /** @const {Array<number>} */ var texScale = this.m_uniforms[1].value;
+ /** @const {Array<number>} */ var texBias = this.m_uniforms[2].value;
+ /** @const {number} */ var layer = this.m_uniforms[3].value[0];
+
+ var texCoords = [];
+ var colors = [];
+
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
+ var tex = this.m_uniforms[0].sampler;
+ var ratioX = tex.m_view.getWidth() / context.getWidth();
+ var ratioY = tex.m_view.getHeight() / context.getHeight();
+ var lod = Math.floor(Math.log2(Math.max(ratioX, ratioY)));
+
+ /** @const {Array<number>} */ var coord = rrShadingContext.readTriangleVarying(packet[packetNdx], context, 0);
+ texCoords = [coord[0], coord[1], layer];
+
+ colors = tex.sample(texCoords, lod);
+
+ /** @const {Array<number>} */ var color = deMath.add(deMath.multiply(colors, texScale), texBias);
+ /** @const {Array<number>} */ var icolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deInt32);
+ /** @const {Array<number>} */ var uicolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deUint32);
+
+ if (this.m_outputType == gluShaderUtil.DataType.FLOAT_VEC4)
+ packet[packetNdx].value = color;
+ else if (this.m_outputType == gluShaderUtil.DataType.INT_VEC4)
+ packet[packetNdx].value = icolor;
+ else if (this.m_outputType == gluShaderUtil.DataType.UINT_VEC4)
+ packet[packetNdx].value = uicolor;
+ }
+ };
+
+ /**
+ * es3fFboTestUtil.Texture3DShader inherits from sglrShaderProgram
+ * @constructor
+ * @extends {sglrShaderProgram.ShaderProgram}
+ * @param {gluShaderUtil.DataType} samplerType
+ * @param {gluShaderUtil.DataType} outputType
+ */
+ es3fFboTestUtil.Texture3DShader = function(samplerType, outputType) {
+ /** @type {sglrShaderProgram.ShaderProgramDeclaration} */
+ var decl = new sglrShaderProgram.ShaderProgramDeclaration();
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_coord', rrGenericVector.GenericVecType.FLOAT));
+ decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
+ decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(es3fFboTestUtil.mapDataTypeToGenericVecType(outputType)));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_sampler0', samplerType));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_scale', gluShaderUtil.DataType.FLOAT_VEC4));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_bias', gluShaderUtil.DataType.FLOAT_VEC4));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_depth', gluShaderUtil.DataType.FLOAT));
+ decl.pushVertexSource(new sglrShaderProgram.VertexSource(
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in highp vec2 a_coord;\n' +
+ 'out highp vec2 v_coord;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ ' v_coord = a_coord;\n' +
+ '}\n'));
+ decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(
+ '#version 300 es\n' +
+ 'uniform highp ' + gluShaderUtil.getDataTypeName(samplerType) + ' u_sampler0;\n' +
+ 'uniform highp vec4 u_scale;\n' +
+ 'uniform highp vec4 u_bias;\n' +
+ 'uniform highp float u_depth;\n' +
+ 'in highp vec2 v_coord;\n' +
+ 'layout(location = 0) out highp ' + gluShaderUtil.getDataTypeName(outputType) + ' o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = ' + gluShaderUtil.getDataTypeName(outputType) + '(vec4(texture(u_sampler0, vec3(v_coord, u_depth))) * u_scale + u_bias);\n' +
+ '}\n'));
+ sglrShaderProgram.ShaderProgram.call(this, decl);
+ /** @type {Array<number>} */ this.m_texScale = [1.0, 1.0, 1.0, 1.0];
+ /** @type {Array<number>} */ this.m_texBias = [0.0, 0.0, 0.0, 0.0];
+ /** @type {number} */ this.m_depth = 0.0;
+ /** @type {gluShaderUtil.DataType} */ this.m_outputType = outputType;
+ };
+
+ es3fFboTestUtil.Texture3DShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
+ es3fFboTestUtil.Texture3DShader.prototype.constructor = es3fFboTestUtil.Texture3DShader;
+
+ /**
+ * @param {number} depth
+ */
+ es3fFboTestUtil.Texture3DShader.prototype.setDepth = function(depth) {
+ this.m_depth = depth;
+ };
+
+ /**
+ * @param {Array<number>} scale
+ * @param {Array<number>} bias
+ */
+ es3fFboTestUtil.Texture3DShader.prototype.setTexScaleBias = function(scale, bias) {
+ this.m_texScale = scale;
+ this.m_texBias = bias;
+ };
+
+ /**
+ * @param context GL-like context
+ * @param program
+ */
+ es3fFboTestUtil.Texture3DShader.prototype.setUniforms = function(context, program) {
+ context.useProgram(program);
+ context.uniform1i(context.getUniformLocation(program, 'u_sampler0'), 0);
+ context.uniform1f(context.getUniformLocation(program, 'u_depth'), this.m_depth);
+ context.uniform4fv(context.getUniformLocation(program, 'u_scale'), this.m_texScale);
+ context.uniform4fv(context.getUniformLocation(program, 'u_bias'), this.m_texBias);
+ };
+
+ /**
+ * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
+ * @param {Array<rrVertexPacket.VertexPacket>} packets
+ * @param {number} numPackets
+ */
+ es3fFboTestUtil.Texture3DShader.prototype.shadeVertices = function(inputs, packets, numPackets) {
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
+ /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
+
+ packet.position = rrVertexAttrib.readVertexAttrib(inputs[0], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
+ packet.outputs[0] = rrVertexAttrib.readVertexAttrib(inputs[1], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
+ }
+ };
+
+ /**
+ * @param {Array<rrFragmentOperations.Fragment>} packet
+ * @param {rrShadingContext.FragmentShadingContext} context
+ */
+ es3fFboTestUtil.Texture3DShader.prototype.shadeFragments = function(packet, context) {
+ var numPackets = packet.length;
+ /** @const {Array<number>} */ var texScale = this.m_uniforms[1].value;
+ /** @const {Array<number>} */ var texBias = this.m_uniforms[2].value;
+ /** @const {number} */ var depth = this.m_uniforms[3].value[0];
+
+ var texCoords = [];
+ var colors = [];
+
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
+ var tex = this.m_uniforms[0].sampler;
+ var ratioX = tex.m_view.getWidth() / context.getWidth();
+ var ratioY = tex.m_view.getHeight() / context.getHeight();
+ // TODO: what to do with Z coordinate?
+ var lod = Math.floor(Math.log2(Math.max(ratioX, ratioY)));
+
+ var coord = rrShadingContext.readTriangleVarying(packet[packetNdx], context, 0);
+ texCoords = [coord[0], coord[1], depth];
+
+ colors = tex.sample(texCoords, lod);
+
+ /** @const {Array<number>} */ var color = deMath.add(deMath.multiply(colors, texScale), texBias);
+ /** @const {Array<number>} */ var icolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deInt32);
+ /** @const {Array<number>} */ var uicolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deUint32);
+
+ if (this.m_outputType == gluShaderUtil.DataType.FLOAT_VEC4)
+ packet[packetNdx].value = color;
+ else if (this.m_outputType == gluShaderUtil.DataType.INT_VEC4)
+ packet[packetNdx].value = icolor;
+ else if (this.m_outputType == gluShaderUtil.DataType.UINT_VEC4)
+ packet[packetNdx].value = uicolor;
+ }
+ };
+
+ /**
+ * es3fFboTestUtil.DepthGradientShader inherits from sglrShaderProgram
+ * @constructor
+ * @extends {sglrShaderProgram.ShaderProgram}
+ * @param {gluShaderUtil.DataType} outputType
+ */
+ es3fFboTestUtil.DepthGradientShader = function(outputType) {
+ /** @type {sglrShaderProgram.ShaderProgramDeclaration} */
+ var decl = new sglrShaderProgram.ShaderProgramDeclaration();
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_position', rrGenericVector.GenericVecType.FLOAT));
+ decl.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('a_coord', rrGenericVector.GenericVecType.FLOAT));
+ decl.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT));
+ decl.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(es3fFboTestUtil.mapDataTypeToGenericVecType(outputType)));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_maxGradient', gluShaderUtil.DataType.FLOAT));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_minGradient', gluShaderUtil.DataType.FLOAT));
+ decl.pushUniform(new sglrShaderProgram.Uniform('u_color', gluShaderUtil.DataType.FLOAT_VEC4));
+ decl.pushVertexSource(new sglrShaderProgram.VertexSource(
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in highp vec4 a_coord;\n' +
+ 'out highp vec4 v_coord;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ ' v_coord = a_coord;\n' +
+ '}\n'));
+ decl.pushFragmentSource(new sglrShaderProgram.FragmentSource(
+ '#version 300 es\n' +
+ 'in highp vec4 v_coord;\n' +
+ 'uniform highp float u_minGradient;\n' +
+ 'uniform highp float u_maxGradient;\n' +
+ 'uniform highp vec4 u_color;\n' +
+ 'layout(location = 0) out highp ' + gluShaderUtil.getDataTypeName(outputType) + ' o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' highp float x = v_coord.x;\n' +
+ ' highp float y = v_coord.y;\n' +
+ ' highp float f0 = (x + y) * 0.5;\n' +
+ ' gl_FragDepth = u_minGradient + (u_maxGradient-u_minGradient)*f0;\n' +
+ ' o_color = ' + gluShaderUtil.getDataTypeName(outputType) + '(u_color);\n' +
+ '}\n'));
+ this.m_outputType = outputType;
+ sglrShaderProgram.ShaderProgram.call(this, decl);
+ /** @const {sglrShaderProgram.Uniform} */ this.u_minGradient = this.getUniformByName('u_minGradient');
+ /** @const {sglrShaderProgram.Uniform} */ this.u_maxGradient = this.getUniformByName('u_maxGradient');
+ /** @const {sglrShaderProgram.Uniform} */ this.u_color = this.getUniformByName('u_color');
+ };
+
+ es3fFboTestUtil.DepthGradientShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
+ es3fFboTestUtil.DepthGradientShader.prototype.constructor = es3fFboTestUtil.DepthGradientShader;
+
+ /**
+ * @param ctx GL-like context
+ * @param program
+ * @param {number} gradientMin
+ * @param {number} gradientMax
+ * @param {Array<number>} color
+ */
+ es3fFboTestUtil.DepthGradientShader.prototype.setUniforms = function(ctx, program, gradientMin, gradientMax, color) {
+ ctx.useProgram(program);
+ ctx.uniform1fv(ctx.getUniformLocation(program, 'u_minGradient'), [gradientMin]);
+ ctx.uniform1fv(ctx.getUniformLocation(program, 'u_maxGradient'), [gradientMax]);
+ ctx.uniform4fv(ctx.getUniformLocation(program, 'u_color'), color);
+ };
+
+ /**
+ * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
+ * @param {Array<rrVertexPacket.VertexPacket>} packets
+ * @param {number} numPackets
+ */
+ es3fFboTestUtil.DepthGradientShader.prototype.shadeVertices = function(inputs, packets, numPackets) {
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
+ /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
+
+ packet.position = rrVertexAttrib.readVertexAttrib(inputs[0], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
+ packet.outputs[0] = rrVertexAttrib.readVertexAttrib(inputs[1], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
+ }
+ };
+
+ /**
+ * @param {Array<rrFragmentOperations.Fragment>} packet
+ * @param {rrShadingContext.FragmentShadingContext} context
+ */
+ es3fFboTestUtil.DepthGradientShader.prototype.shadeFragments = function(packet, context) {
+ var numPackets = packet.length;
+ /** @const {number} */ var gradientMin = this.u_minGradient.value[0];
+ /** @const {number} */ var gradientMax = this.u_maxGradient.value[0];
+ /** @type {Array<number>} */ var color = this.u_color.value;
+ /** @type {Array<number>} */ var icolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deInt32);
+ /** @type {Array<number>} */ var uicolor = es3fFboTestUtil.castVectorSaturate(color, tcuTexture.deTypes.deUint32);
+
+ for (var packetNdx = 0; packetNdx < numPackets; ++packetNdx) {
+ /** @type {Array<number>} */ var coord = rrShadingContext.readTriangleVarying(packet[packetNdx], context, 0);
+ /** @const {number} */ var x = coord[0];
+ /** @const {number} */ var y = coord[1];
+ /** @const {number} */ var f0 = (x + y) * 0.5;
+
+ packet[packetNdx].sampleDepths[0] = gradientMin + (gradientMax - gradientMin) * f0;
+
+ if (this.m_outputType == gluShaderUtil.DataType.FLOAT_VEC4)
+ packet[packetNdx].value = color;
+ else if (this.m_outputType == gluShaderUtil.DataType.INT_VEC4)
+ packet[packetNdx].value = icolor;
+ else if (this.m_outputType == gluShaderUtil.DataType.UINT_VEC4)
+ packet[packetNdx].value = uicolor;
+ }
+ };
+
+ es3fFboTestUtil.getFormatName = function(format) {
+ switch (format) {
+ case gl.RGB565: return 'rgb565';
+ case gl.RGB5_A1: return 'rgb5_a1';
+ case gl.RGBA4: return 'rgba4';
+ case gl.DEPTH_COMPONENT16: return 'depth_component16';
+ case gl.STENCIL_INDEX8: return 'stencil_index8';
+ case gl.RGBA32F: return 'rgba32f';
+ case gl.RGBA32I: return 'rgba32i';
+ case gl.RGBA32UI: return 'rgba32ui';
+ case gl.RGBA16F: return 'rgba16f';
+ case gl.RGBA16I: return 'rgba16i';
+ case gl.RGBA16UI: return 'rgba16ui';
+ case gl.RGBA8: return 'rgba8';
+ case gl.RGBA8I: return 'rgba8i';
+ case gl.RGBA8UI: return 'rgba8ui';
+ case gl.SRGB8_ALPHA8: return 'srgb8_alpha8';
+ case gl.RGB10_A2: return 'rgb10_a2';
+ case gl.RGB10_A2UI: return 'rgb10_a2ui';
+ case gl.RGBA8_SNORM: return 'rgba8_snorm';
+ case gl.RGB8: return 'rgb8';
+ case gl.R11F_G11F_B10F: return 'r11f_g11f_b10f';
+ case gl.RGB32F: return 'rgb32f';
+ case gl.RGB32I: return 'rgb32i';
+ case gl.RGB32UI: return 'rgb32ui';
+ case gl.RGB16F: return 'rgb16f';
+ case gl.RGB16I: return 'rgb16i';
+ case gl.RGB16UI: return 'rgb16ui';
+ case gl.RGB8_SNORM: return 'rgb8_snorm';
+ case gl.RGB8I: return 'rgb8i';
+ case gl.RGB8UI: return 'rgb8ui';
+ case gl.SRGB8: return 'srgb8';
+ case gl.RGB9_E5: return 'rgb9_e5';
+ case gl.RG32F: return 'rg32f';
+ case gl.RG32I: return 'rg32i';
+ case gl.RG32UI: return 'rg32ui';
+ case gl.RG16F: return 'rg16f';
+ case gl.RG16I: return 'rg16i';
+ case gl.RG16UI: return 'rg16ui';
+ case gl.RG8: return 'rg8';
+ case gl.RG8I: return 'rg8i';
+ case gl.RG8UI: return 'rg8ui';
+ case gl.RG8_SNORM: return 'rg8_snorm';
+ case gl.R32F: return 'r32f';
+ case gl.R32I: return 'r32i';
+ case gl.R32UI: return 'r32ui';
+ case gl.R16F: return 'r16f';
+ case gl.R16I: return 'r16i';
+ case gl.R16UI: return 'r16ui';
+ case gl.R8: return 'r8';
+ case gl.R8I: return 'r8i';
+ case gl.R8UI: return 'r8ui';
+ case gl.R8_SNORM: return 'r8_snorm';
+ case gl.DEPTH_COMPONENT32F: return 'depth_component32f';
+ case gl.DEPTH_COMPONENT24: return 'depth_component24';
+ case gl.DEPTH32F_STENCIL8: return 'depth32f_stencil8';
+ case gl.DEPTH24_STENCIL8: return 'depth24_stencil8';
+
+ default:
+ throw new Error('Unknown format in getFromatName()');
+ }
+ };
+
+ /**
+ * @param {tcuTexture.TextureFormat} format
+ * @return {gluShaderUtil.DataType}
+ */
+ es3fFboTestUtil.getFragmentOutputType = function(format) {
+ switch (tcuTexture.getTextureChannelClass(format.type)) {
+ case tcuTexture.TextureChannelClass.FLOATING_POINT:
+ case tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT:
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
+ return gluShaderUtil.DataType.FLOAT_VEC4;
+
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
+ return gluShaderUtil.DataType.UINT_VEC4;
+
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ return gluShaderUtil.DataType.INT_VEC4;
+
+ default:
+ throw new Error('Unknown format');
+ }
+ };
+
+ /**
+ * @param {tcuTexture.TextureFormat} format
+ * @return {tcuTexture.TextureFormat}
+ */
+ es3fFboTestUtil.getFramebufferReadFormat = function(format) {
+ switch (tcuTexture.getTextureChannelClass(format.type)) {
+ case tcuTexture.TextureChannelClass.FLOATING_POINT:
+ return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.FLOAT);
+
+ case tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT:
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
+ return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8);
+
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
+ return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNSIGNED_INT32);
+
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ return new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.SIGNED_INT32);
+
+ default:
+ throw new Error('Unknown format in es3fFboTestUtil.getFramebufferReadFormat()');
+ }
+ };
+
+ /**
+ * @param {es3fFboTestUtil.Context} ctx GL-like context
+ * @param {tcuTexture.TextureFormat} format
+ * @param {Array<number>} value
+ */
+ es3fFboTestUtil.clearColorBuffer = function(ctx, format, value) {
+ /** @const @type {tcuTexture.TextureChannelClass} */
+ var fmtClass = tcuTexture.getTextureChannelClass(format.type);
+
+ switch (fmtClass) {
+ case tcuTexture.TextureChannelClass.FLOATING_POINT:
+ case tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT:
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
+ ctx.clearBufferfv(gl.COLOR, 0, value);
+ break;
+
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
+ ctx.clearBufferuiv(gl.COLOR, 0, value);
+ break;
+
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ ctx.clearBufferiv(gl.COLOR, 0, value);
+ break;
+
+ default:
+ throw new Error('Invalid channel class: ' + fmtClass);
+ }
+ };
+
+ /**
+ * @param {tcuTexture.TextureFormat} format
+ * @return {tcuRGBA.RGBA}
+ */
+ es3fFboTestUtil.getThresholdFromTextureFormat = function(format) {
+ /** @const @type {Array<number>} */ var bits = tcuTextureUtil.getTextureFormatMantissaBitDepth(format);
+ return tcuRGBA.newRGBAComponents(
+ es3fFboTestUtil.calculateU8ConversionError(bits[0]),
+ es3fFboTestUtil.calculateU8ConversionError(bits[1]),
+ es3fFboTestUtil.calculateU8ConversionError(bits[2]),
+ es3fFboTestUtil.calculateU8ConversionError(bits[3])
+ );
+ };
+
+ /**
+ * @param {number} glFormat
+ * @return {tcuRGBA.RGBA}
+ */
+ es3fFboTestUtil.getFormatThreshold = function(glFormat) {
+ /** @const @type {tcuTexture.TextureFormat} */ var format = gluTextureUtil.mapGLInternalFormat(glFormat);
+ return es3fFboTestUtil.getThresholdFromTextureFormat(format);
+ };
+
+ /**
+ * @param {number} srcBits
+ * @return {number}
+ */
+ es3fFboTestUtil.getToSRGB8ConversionError = function(srcBits) {
+ // \note These are pre-computed based on simulation results.
+ /** @const @type {Array<number>} */ var errors = [
+ 1, // 0 bits - rounding
+ 255, // 1 bits
+ 157, // 2 bits
+ 106, // 3 bits
+ 74, // 4 bits
+ 51, // 5 bits
+ 34, // 6 bits
+ 22, // 7 bits
+ 13, // 8 bits
+ 7, // 9 bits
+ 4, // 10 bits
+ 3, // 11 bits
+ 2 // 12 bits
+ // 1 from this on
+ ];
+
+ DE_ASSERT(srcBits >= 0);
+ if (srcBits < errors.length)
+ return errors[srcBits];
+ else
+ return 1;
+ };
+
+ /**
+ * @param {tcuTexture.TextureFormat} src
+ * @param {tcuTexture.TextureFormat} dst
+ * @return {tcuRGBA.RGBA}
+ */
+ es3fFboTestUtil.getToSRGBConversionThreshold = function(src, dst) {
+ // Only SRGB8 and SRGB8_ALPHA8 formats are supported.
+ DE_ASSERT(dst.type == tcuTexture.ChannelType.UNORM_INT8);
+ DE_ASSERT(dst.order == tcuTexture.ChannelOrder.sRGB || dst.order == tcuTexture.ChannelOrder.sRGBA);
+
+ /** @const @type {Array<number>} */ var bits = tcuTextureUtil.getTextureFormatMantissaBitDepth(src);
+ /** @const @type {boolean} */ var dstHasAlpha = dst.order == tcuTexture.ChannelOrder.sRGBA;
+
+ return tcuRGBA.newRGBAComponents(
+ es3fFboTestUtil.getToSRGB8ConversionError(bits[0]),
+ es3fFboTestUtil.getToSRGB8ConversionError(bits[1]),
+ es3fFboTestUtil.getToSRGB8ConversionError(bits[2]),
+ dstHasAlpha ? es3fFboTestUtil.calculateU8ConversionError(bits[3]) : 0);
+ };
+
+ /**
+ * es3fFboTestUtil.readPixels()
+ * @param {(WebGL2RenderingContext|sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext)} ctx
+ * @param {tcuSurface.Surface} dst
+ * @param {number} x
+ * @param {number} y
+ * @param {number} width
+ * @param {number} height
+ * @param {tcuTexture.TextureFormat} format
+ * @param {Array<number>} scale
+ * @param {Array<number>} bias
+ */
+ es3fFboTestUtil.readPixels = function(ctx, dst, x, y, width, height, format, scale, bias) {
+ /** @type {tcuTexture.TextureFormat} */ var readFormat = es3fFboTestUtil.getFramebufferReadFormat(format);
+ /** @type {gluTextureUtil.TransferFormat} */ var transferFmt = gluTextureUtil.getTransferFormat(readFormat);
+ /** @type {number} */ var alignment = 4; // \note gl.PACK_ALIGNMENT = 4 is assumed.
+ /** @type {number} */ var rowSize = deMath.deAlign32(readFormat.getPixelSize() * width, alignment);
+ var typedArrayType = tcuTexture.getTypedArray(readFormat.type);
+ var data = new typedArrayType(rowSize * height);
+ ctx.readPixels(x, y, width, height, transferFmt.format, transferFmt.dataType, data);
+
+ // Convert to surface.
+ var cpbaDescriptor = {
+ format: readFormat,
+ width: width,
+ height: height,
+ depth: 1,
+ rowPitch: rowSize,
+ slicePitch: 0,
+ data: data.buffer
+ };
+
+ /** @type {tcuTexture.ConstPixelBufferAccess} */
+ var src = new tcuTexture.ConstPixelBufferAccess(cpbaDescriptor);
+
+ dst.setSize(width, height);
+ /** @type {tcuTexture.PixelBufferAccess} */ var dstAccess = dst.getAccess();
+
+ for (var yo = 0; yo < height; yo++)
+ for (var xo = 0; xo < width; xo++)
+ dstAccess.setPixel(deMath.add(deMath.multiply(src.getPixel(xo, yo), scale), bias), xo, yo);
+ };
+
+ /**
+ * @param {number} srcBits
+ * @return {number}
+ */
+ es3fFboTestUtil.calculateU8ConversionError = function(srcBits) {
+ if (srcBits > 0) {
+ /** @const @type {number} */ var clampedBits = deMath.clamp(srcBits, 0, 8);
+ /** @const @type {number} */ var srcMaxValue = Math.max((1 << clampedBits) - 1, 1);
+ /** @const @type {number} */ var error = Math.floor(Math.ceil(255.0 * 2.0 / srcMaxValue));
+
+ return deMath.clamp(error, 0, 255);
+ } else
+ return 1;
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFloatStateQueryTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFloatStateQueryTests.js
new file mode 100644
index 0000000000..6b5431061e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFloatStateQueryTests.js
@@ -0,0 +1,431 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fFloatStateQueryTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('functional.gles3.es3fApiCase');
+goog.require('modules.shared.glsStateQuery');
+
+goog.scope(function() {
+ var es3fFloatStateQueryTests = functional.gles3.es3fFloatStateQueryTests;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var deRandom = framework.delibs.debase.deRandom;
+ var deMath = framework.delibs.debase.deMath;
+ var es3fApiCase = functional.gles3.es3fApiCase;
+ var glsStateQuery = modules.shared.glsStateQuery;
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fFloatStateQueryTests.DepthRangeCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fFloatStateQueryTests.DepthRangeCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fFloatStateQueryTests.DepthRangeCase.prototype.constructor = es3fFloatStateQueryTests.DepthRangeCase;
+
+ es3fFloatStateQueryTests.DepthRangeCase.prototype.test = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0xabcdef);
+
+ this.check(glsStateQuery.verify(gl.DEPTH_RANGE, new Float32Array([0.0, 1.0])));
+
+ /** @type {Array<Float32Array>} */ var fixedTests = [
+ new Float32Array([0.5, 1.0]),
+ new Float32Array([0.0, 0.5]),
+ new Float32Array([0.0, 0.0]),
+ new Float32Array([1.0, 1.0])
+ ];
+
+ for (var ndx = 0; ndx < fixedTests.length; ++ndx) {
+ gl.depthRange(fixedTests[ndx][0], fixedTests[ndx][1]);
+ this.check(glsStateQuery.verify(gl.DEPTH_RANGE, fixedTests[ndx]));
+ }
+
+ /** @type {number} */ var numIterations = 120;
+ for (var i = 0; i < numIterations; ++i) {
+ // [dag] sorting to keep zNear < zFar
+ /** @type {Array<number>} */ var values = [rnd.getFloat(0, 1), rnd.getFloat(0, 1)].sort();
+ /** @type {Float32Array} */ var depth = new Float32Array(values);
+ gl.depthRange(depth[0], depth[1]);
+ this.check(glsStateQuery.verify(gl.DEPTH_RANGE, depth));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fFloatStateQueryTests.LineWidthCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fFloatStateQueryTests.LineWidthCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fFloatStateQueryTests.LineWidthCase.prototype.constructor = es3fFloatStateQueryTests.LineWidthCase;
+
+ es3fFloatStateQueryTests.LineWidthCase.prototype.test = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0xabcdef);
+
+ this.check(glsStateQuery.verify(gl.LINE_WIDTH, 1.0));
+
+ /** @type {Float32Array} */ var range = /** @type {Float32Array} */ (gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE));
+
+ /** @type {number} */ var numIterations = 120;
+ for (var i = 0; i < numIterations; ++i) {
+ /** @type {number} */ var reference = rnd.getFloat(range[0], range[1]);
+
+ gl.lineWidth(reference);
+ this.check(glsStateQuery.verify(gl.LINE_WIDTH, reference));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fFloatStateQueryTests.PolygonOffsetFactorCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fFloatStateQueryTests.PolygonOffsetFactorCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fFloatStateQueryTests.PolygonOffsetFactorCase.prototype.constructor = es3fFloatStateQueryTests.PolygonOffsetFactorCase;
+
+ es3fFloatStateQueryTests.PolygonOffsetFactorCase.prototype.test = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0xabcdef);
+
+ this.check(glsStateQuery.verify(gl.POLYGON_OFFSET_FACTOR, 0.0));
+
+ /** @type {Array<number>} */ var fixedTests = [0.0, 0.5, -0.5, 1.5];
+
+ for (var ndx = 0; ndx < fixedTests.length; ++ndx) {
+ gl.polygonOffset(fixedTests[ndx], 0);
+ this.check(glsStateQuery.verify(gl.POLYGON_OFFSET_FACTOR, fixedTests[ndx]));
+ }
+
+ /** @type {number} */ var numIterations = 120;
+ for (var i = 0; i < numIterations; ++i) {
+ /** @type {number} */ var reference = rnd.getFloat(-64000, 64000);
+
+ gl.polygonOffset(reference, 0);
+ this.check(glsStateQuery.verify(gl.POLYGON_OFFSET_FACTOR, reference));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fFloatStateQueryTests.PolygonOffsetUnitsCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fFloatStateQueryTests.PolygonOffsetUnitsCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fFloatStateQueryTests.PolygonOffsetUnitsCase.prototype.constructor = es3fFloatStateQueryTests.PolygonOffsetUnitsCase;
+
+ es3fFloatStateQueryTests.PolygonOffsetUnitsCase.prototype.test = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0xabcdef);
+
+ this.check(glsStateQuery.verify(gl.POLYGON_OFFSET_UNITS, 0.0));
+
+ /** @type {Array<number>} */ var fixedTests = [0.0, 0.5, -0.5, 1.5];
+
+ for (var ndx = 0; ndx < fixedTests.length; ++ndx) {
+ gl.polygonOffset(0, fixedTests[ndx]);
+ this.check(glsStateQuery.verify(gl.POLYGON_OFFSET_UNITS, fixedTests[ndx]));
+ }
+
+ /** @type {number} */ var numIterations = 120;
+ for (var i = 0; i < numIterations; ++i) {
+ /** @type {number} */ var reference = rnd.getFloat(-64000, 64000);
+
+ gl.polygonOffset(0, reference);
+ this.check(glsStateQuery.verify(gl.POLYGON_OFFSET_UNITS, reference));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fFloatStateQueryTests.SampleCoverageCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fFloatStateQueryTests.SampleCoverageCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fFloatStateQueryTests.SampleCoverageCase.prototype.constructor = es3fFloatStateQueryTests.SampleCoverageCase;
+
+ es3fFloatStateQueryTests.SampleCoverageCase.prototype.test = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0xabcdef);
+
+ this.check(glsStateQuery.verify(gl.SAMPLE_COVERAGE_VALUE, 1.0));
+
+ /** @type {Array<number>} */ var fixedTests = [0.0, 0.5, 0.45, 0.55];
+
+ for (var ndx = 0; ndx < fixedTests.length; ++ndx) {
+ gl.sampleCoverage(fixedTests[ndx], false);
+ this.check(glsStateQuery.verify(gl.SAMPLE_COVERAGE_VALUE, fixedTests[ndx]));
+ }
+
+ /** @type {Array<number>} */ var clampTests = [-1.0, -1.5, 1.45, 3.55];
+
+ for (var ndx = 0; ndx < clampTests.length; ++ndx) {
+ gl.sampleCoverage(clampTests[ndx], false);
+ this.check(glsStateQuery.verify(gl.SAMPLE_COVERAGE_VALUE, deMath.clamp(clampTests[ndx], 0.0, 1.0)));
+ }
+
+ /** @type {number} */ var numIterations = 120;
+ for (var i = 0; i < numIterations; ++i) {
+ /** @type {number} */ var reference = rnd.getFloat(0, 1);
+ /** @type {boolean} */ var invert = rnd.getBool() ? true : false;
+
+ gl.sampleCoverage(reference, invert);
+ this.check(glsStateQuery.verify(gl.SAMPLE_COVERAGE_VALUE, reference));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fFloatStateQueryTests.BlendColorCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fFloatStateQueryTests.BlendColorCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fFloatStateQueryTests.BlendColorCase.prototype.constructor = es3fFloatStateQueryTests.BlendColorCase;
+
+ es3fFloatStateQueryTests.BlendColorCase.prototype.test = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0xabcdef);
+
+ this.check(glsStateQuery.verify(gl.BLEND_COLOR, new Float32Array([0, 0, 0, 0])));
+
+ /** @type {Array<Float32Array>} */ var fixedTests = [
+ new Float32Array([0.5, 1.0, 0.5, 1.0]),
+ new Float32Array([0.0, 0.5, 0.0, 0.5]),
+ new Float32Array([0.0, 0.0, 0.0, 0.0]),
+ new Float32Array([1.0, 1.0, 1.0, 1.0])
+ ];
+ for (var ndx = 0; ndx < fixedTests.length; ++ndx) {
+ gl.blendColor(fixedTests[ndx][0], fixedTests[ndx][1], fixedTests[ndx][2], fixedTests[ndx][3]);
+ this.check(glsStateQuery.verify(gl.BLEND_COLOR, fixedTests[ndx]));
+ }
+
+ /** @type {number} */ var numIterations = 120;
+ for (var i = 0; i < numIterations; ++i) {
+ /** @type {number} */ var r = rnd.getFloat(0, 1);
+ /** @type {number} */ var g = rnd.getFloat(0, 1);
+ /** @type {number} */ var b = rnd.getFloat(0, 1);
+ /** @type {number} */ var a = rnd.getFloat(0, 1);
+
+ gl.blendColor(r, g, b, a);
+ this.check(glsStateQuery.verify(gl.BLEND_COLOR, new Float32Array([r, g, b, a])));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fFloatStateQueryTests.ColorClearCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fFloatStateQueryTests.ColorClearCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fFloatStateQueryTests.ColorClearCase.prototype.constructor = es3fFloatStateQueryTests.ColorClearCase;
+
+ es3fFloatStateQueryTests.ColorClearCase.prototype.test = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0xabcdef);
+
+ // [dag] In the C++ dEQP code, initial color clear value check is temorarily removed. (until the framework does not alter it)
+ this.check(glsStateQuery.verify(gl.COLOR_CLEAR_VALUE, new Float32Array([0, 0, 0, 0])));
+
+ /** @type {Array<Float32Array>} */ var fixedTests = [
+ new Float32Array([0.5, 1.0, 0.5, 1.0]),
+ new Float32Array([0.0, 0.5, 0.0, 0.5]),
+ new Float32Array([0.0, 0.0, 0.0, 0.0]),
+ new Float32Array([1.0, 1.0, 1.0, 1.0])
+ ];
+ for (var ndx = 0; ndx < fixedTests.length; ++ndx) {
+ gl.clearColor(fixedTests[ndx][0], fixedTests[ndx][1], fixedTests[ndx][2], fixedTests[ndx][3]);
+ this.check(glsStateQuery.verify(gl.COLOR_CLEAR_VALUE, fixedTests[ndx]));
+ }
+
+ /** @type {number} */ var numIterations = 120;
+ for (var i = 0; i < numIterations; ++i) {
+ /** @type {number} */ var r = rnd.getFloat(0, 1);
+ /** @type {number} */ var g = rnd.getFloat(0, 1);
+ /** @type {number} */ var b = rnd.getFloat(0, 1);
+ /** @type {number} */ var a = rnd.getFloat(0, 1);
+
+ gl.clearColor(r, g, b, a);
+ this.check(glsStateQuery.verify(gl.COLOR_CLEAR_VALUE, new Float32Array([r, g, b, a])));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fFloatStateQueryTests.DepthClearCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fFloatStateQueryTests.DepthClearCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fFloatStateQueryTests.DepthClearCase.prototype.constructor = es3fFloatStateQueryTests.DepthClearCase;
+
+ es3fFloatStateQueryTests.DepthClearCase.prototype.test = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0xabcdef);
+
+ this.check(glsStateQuery.verify(gl.DEPTH_CLEAR_VALUE, 1));
+
+ /** @type {number} */ var numIterations = 120;
+ for (var i = 0; i < numIterations; ++i) {
+ /** @type {number} */ var ref = rnd.getFloat(0, 1);
+
+ gl.clearDepth(ref);
+ this.check(glsStateQuery.verify(gl.DEPTH_CLEAR_VALUE, ref));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fFloatStateQueryTests.MaxTextureLODBiasCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fFloatStateQueryTests.MaxTextureLODBiasCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fFloatStateQueryTests.MaxTextureLODBiasCase.prototype.constructor = es3fFloatStateQueryTests.MaxTextureLODBiasCase;
+
+ es3fFloatStateQueryTests.MaxTextureLODBiasCase.prototype.test = function() {
+ this.check(glsStateQuery.verifyGreaterOrEqual(gl.MAX_TEXTURE_LOD_BIAS, 2.0));
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fFloatStateQueryTests.AliasedPointSizeRangeCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fFloatStateQueryTests.AliasedPointSizeRangeCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fFloatStateQueryTests.AliasedPointSizeRangeCase.prototype.constructor = es3fFloatStateQueryTests.AliasedPointSizeRangeCase;
+
+ es3fFloatStateQueryTests.AliasedPointSizeRangeCase.prototype.test = function() {
+ var pointSizeRange = /** @type {Float32Array} */ (gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE));
+ /** @type {Float32Array} */ var reference = new Float32Array([1, 1]);
+ this.check(pointSizeRange[0] <= reference[0] && pointSizeRange[1] >= reference[1]);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fFloatStateQueryTests.AliasedLineWidthRangeCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fFloatStateQueryTests.AliasedLineWidthRangeCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fFloatStateQueryTests.AliasedLineWidthRangeCase.prototype.constructor = es3fFloatStateQueryTests.AliasedLineWidthRangeCase;
+
+ es3fFloatStateQueryTests.AliasedLineWidthRangeCase.prototype.test = function() {
+ var lineWidthRange = /** @type {Float32Array} */ (gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE));
+ /** @type {Float32Array} */ var reference = new Float32Array([1, 1]);
+ this.check(lineWidthRange[0] <= reference[0] && lineWidthRange[1] >= reference[1]);
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fFloatStateQueryTests.FloatStateQueryTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'floats', 'Float Values');
+ };
+
+ es3fFloatStateQueryTests.FloatStateQueryTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fFloatStateQueryTests.FloatStateQueryTests.prototype.constructor = es3fFloatStateQueryTests.FloatStateQueryTests;
+
+ es3fFloatStateQueryTests.FloatStateQueryTests.prototype.init = function() {
+ this.addChild(new es3fFloatStateQueryTests.DepthRangeCase('depth_range', 'DEPTH_RANGE'));
+ this.addChild(new es3fFloatStateQueryTests.LineWidthCase('line_width', 'LINE_WIDTH'));
+ this.addChild(new es3fFloatStateQueryTests.PolygonOffsetFactorCase('polygon_offset_factor', 'POLYGON_OFFSET_FACTOR'));
+ this.addChild(new es3fFloatStateQueryTests.PolygonOffsetUnitsCase('polygon_offset_units', 'POLYGON_OFFSET_UNITS'));
+ this.addChild(new es3fFloatStateQueryTests.SampleCoverageCase('sample_coverage_value', 'SAMPLE_COVERAGE_VALUE'));
+ this.addChild(new es3fFloatStateQueryTests.BlendColorCase('blend_color', 'BLEND_COLOR'));
+ this.addChild(new es3fFloatStateQueryTests.ColorClearCase('color_clear_value', 'COLOR_CLEAR_VALUE'));
+ this.addChild(new es3fFloatStateQueryTests.DepthClearCase('depth_clear_value', 'DEPTH_CLEAR_VALUE'));
+ this.addChild(new es3fFloatStateQueryTests.MaxTextureLODBiasCase('max_texture_lod_bias', 'MAX_TEXTURE_LOD_BIAS'));
+ this.addChild(new es3fFloatStateQueryTests.AliasedPointSizeRangeCase('aliased_point_size_range', 'ALIASED_POINT_SIZE_RANGE'));
+ this.addChild(new es3fFloatStateQueryTests.AliasedLineWidthRangeCase('aliased_line_width_range', 'ALIASED_LINE_WIDTH_RANGE'));
+
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fFloatStateQueryTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fFloatStateQueryTests.FloatStateQueryTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fFloatStateQueryTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFragDepthTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFragDepthTests.js
new file mode 100644
index 0000000000..8a892a0926
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFragDepthTests.js
@@ -0,0 +1,593 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fFragDepthTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluDrawUtil');
+goog.require('modules.shared.glsShaderRenderCase');
+
+goog.scope(function() {
+ var es3fFragDepthTests = functional.gles3.es3fFragDepthTests;
+ var deMath = framework.delibs.debase.deMath;
+ var deRandom = framework.delibs.debase.deRandom;
+ var deString = framework.delibs.debase.deString;
+ var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var gluDrawUtil = framework.opengl.gluDrawUtil;
+ var tcuImageCompare = framework.common.tcuImageCompare;
+ var tcuRGBA = framework.common.tcuRGBA;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuTestCase = framework.common.tcuTestCase;
+ /** @typedef {function(Array<number>):number} */ es3fFragDepthTests.EvalFragDepthFunc;
+
+ /** @const {string} */ es3fFragDepthTests.s_vertexShaderSrc = '' +
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in highp vec2 a_coord;\n' +
+ 'out highp vec2 v_coord;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ ' v_coord = a_coord;\n' +
+ '}\n';
+
+ /** @const {string} */ es3fFragDepthTests.s_defaultFragmentShaderSrc = '' +
+ '#version 300 es\n' +
+ 'uniform highp vec4 u_color;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = u_color;\n' +
+ '}\n';
+
+ /**
+ * @param {number} func
+ * @param {*} a
+ * @param {*} b
+ * @return {boolean}
+ */
+ es3fFragDepthTests.compare = function(func, a, b) {
+ switch (func) {
+ case gl.NEVER: return false;
+ case gl.ALWAYS: return true;
+ case gl.LESS: return a < b;
+ case gl.LEQUAL: return a <= b;
+ case gl.EQUAL: return a === b;
+ case gl.NOTEQUAL: return a !== b;
+ case gl.GEQUAL: return a >= b;
+ case gl.GREATER: return a > b;
+ }
+ bufferedLogToConsole('Compare function not supported.');
+ return false;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * @param {string} fragSrc
+ * @param {?es3fFragDepthTests.EvalFragDepthFunc} evalFunc
+ * @param {number} compareFunc
+ */
+ es3fFragDepthTests.FragDepthCompareCase = function(name, desc, fragSrc, evalFunc, compareFunc) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ /** @type {string} */ this.m_fragSrc = fragSrc;
+ /** @type {?es3fFragDepthTests.EvalFragDepthFunc} */ this.m_evalFunc = evalFunc;
+ /** @type {number} */ this.m_compareFunc = compareFunc;
+ };
+
+ es3fFragDepthTests.FragDepthCompareCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fFragDepthTests.FragDepthCompareCase.prototype.constructor = es3fFragDepthTests.FragDepthCompareCase;
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fFragDepthTests.FragDepthCompareCase.prototype.iterate = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name));
+ /** @type {number} */ var viewportW = Math.min(128, gl.drawingBufferWidth);
+ /** @type {number} */ var viewportH = Math.min(128, gl.drawingBufferHeight);
+ /** @type {number} */ var viewportX = rnd.getInt(0, gl.drawingBufferWidth - viewportW);
+ /** @type {number} */ var viewportY = rnd.getInt(0, gl.drawingBufferHeight - viewportH);
+ /** @type {tcuSurface.Surface} */ var renderedFrame = new tcuSurface.Surface(viewportW, viewportH);
+ /** @type {tcuSurface.Surface} */ var referenceFrame = new tcuSurface.Surface(viewportW, viewportH);
+ /** @type {number} */ var constDepth = 0.1;
+ var depthBits = /** @type {number} */ (gl.getParameter(gl.DEPTH_BITS));
+
+ /** @type {number} */ var xf;
+ /** @type {number} */ var d;
+ /** @type {boolean} */ var dpass;
+
+ if (depthBits == 0)
+ throw new Error('Depth buffer is required');
+
+ gl.depthMask(true);
+ gl.viewport(viewportX, viewportY, viewportW, viewportH);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ gl.enable(gl.DEPTH_TEST);
+
+ /** @type {Array<number>} */ var quadIndices = [0, 1, 2, 2, 1, 3];
+
+ // Fill viewport with 2 quads - one with constant depth and another with d = [-1..1]
+ /** @type {gluShaderProgram.ShaderProgram} */
+ var basicQuadProgram = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(es3fFragDepthTests.s_vertexShaderSrc, es3fFragDepthTests.s_defaultFragmentShaderSrc));
+
+ if (!basicQuadProgram.isOk()) {
+ bufferedLogToConsole(basicQuadProgram.getProgramInfo().infoLog);
+ throw new Error('Compile failed');
+ }
+
+ /** @type {Array<number>} */ var constDepthCoord = [
+ -1.0, -1.0, constDepth, 1.0,
+ -1.0, 1.0, constDepth, 1.0,
+ 0.0, -1.0, constDepth, 1.0,
+ 0.0, 1.0, constDepth, 1.0
+ ];
+
+ /** @type {Array<number>} */ var varyingDepthCoord = [
+ 0.0, -1.0, 1.0, 1.0,
+ 0.0, 1.0, 0.0, 1.0,
+ 1.0, -1.0, 0.0, 1.0,
+ 1.0, 1.0, -1.0, 1.0
+ ];
+
+ gl.useProgram(basicQuadProgram.getProgram());
+ gl.uniform4f(gl.getUniformLocation(basicQuadProgram.getProgram(), 'u_color'), 0.0, 0.0, 1.0, 1.0);
+ gl.depthFunc(gl.ALWAYS);
+
+ /** @type {gluDrawUtil.VertexArrayBinding} */ var posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, constDepthCoord);
+ gluDrawUtil.draw(gl, basicQuadProgram.getProgram(), [posBinding], gluDrawUtil.triangles(quadIndices));
+
+ posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, varyingDepthCoord);
+ gluDrawUtil.draw(gl, basicQuadProgram.getProgram(), [posBinding], gluDrawUtil.triangles(quadIndices));
+
+ // Render with depth test.
+ /** @type {gluShaderProgram.ShaderProgram} */
+ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(es3fFragDepthTests.s_vertexShaderSrc, this.m_fragSrc));
+ bufferedLogToConsole(program.getProgramInfo().infoLog);
+
+ if (!program.isOk())
+ throw new Error('Compile failed');
+
+ /** @type {Array<number>} */ var coord = [
+ 0.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 0.0,
+ 1.0, 1.0
+ ];
+
+ /** @type {Array<number>} */ var position = [
+ -1.0, -1.0, 1.0, 1.0,
+ -1.0, 1.0, 0.0, 1.0,
+ 1.0, -1.0, 0.0, 1.0,
+ 1.0, 1.0, -1.0, 1.0
+ ];
+
+ gl.useProgram(program.getProgram());
+ gl.depthFunc(this.m_compareFunc);
+ gl.uniform4f(gl.getUniformLocation(program.getProgram(), 'u_color'), 0.0, 1.0, 0.0, 1.0);
+
+ // Setup default helper uniforms.
+ glsShaderRenderCase.setupDefaultUniforms(program.getProgram());
+
+ /** @type {Array<gluDrawUtil.VertexArrayBinding>} */ var vertexArrays = [
+ gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, position),
+ gluDrawUtil.newFloatVertexArrayBinding('a_coord', 2, 4, 0, coord)
+ ];
+
+ gluDrawUtil.draw(gl, program.getProgram(), vertexArrays, gluDrawUtil.triangles(quadIndices));
+
+ renderedFrame.readViewport(gl, [viewportX, viewportY, viewportW, viewportH]);
+
+ // Render reference.
+ for (var y = 0; y < referenceFrame.getHeight(); y++) {
+ /** @type {number} */ var yf = (y + 0.5) / referenceFrame.getHeight();
+ /** @type {number} */ var half = deMath.clamp(Math.floor(referenceFrame.getWidth() * 0.5 + 0.5), 0, referenceFrame.getWidth());
+
+ // Fill left half - comparison to constant 0.5
+ for (var x = 0; x < half; x++) {
+ xf = (x + 0.5) / referenceFrame.getWidth();
+ d = this.m_evalFunc([xf, yf]);
+ dpass = es3fFragDepthTests.compare(this.m_compareFunc, d, constDepth * 0.5 + 0.5);
+
+ referenceFrame.setPixel(x, y, dpass ? tcuRGBA.RGBA.green.toIVec() : tcuRGBA.RGBA.blue.toIVec());
+ }
+
+ // Fill right half - comparison to interpolated depth
+ for (var x = half; x < referenceFrame.getWidth(); x++) {
+ xf = (x + 0.5) / referenceFrame.getWidth();
+ /** @type {number} */ var xh = (x - half + 0.5) / (referenceFrame.getWidth() - half);
+ /** @type {number} */ var rd = 1.0 - (xh + yf) * 0.5;
+ d = this.m_evalFunc([xf, yf]);
+ dpass = es3fFragDepthTests.compare(this.m_compareFunc, d, rd);
+
+ referenceFrame.setPixel(x, y, dpass ? tcuRGBA.RGBA.green.toIVec() : tcuRGBA.RGBA.blue.toIVec());
+ }
+ }
+
+ /** @type {boolean} */ var isOk = tcuImageCompare.fuzzyCompare('Result', 'Image comparison result', referenceFrame.getAccess(), renderedFrame.getAccess(), 0.05);
+
+ if (!isOk)
+ testFailedOptions('Fail', false);
+ else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * @param {string} fragSrc
+ * @param {es3fFragDepthTests.EvalFragDepthFunc} evalFunc
+ */
+ es3fFragDepthTests.FragDepthWriteCase = function(name, desc, fragSrc, evalFunc) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ /** @type {string} */ this.m_fragSrc = fragSrc;
+ /** @type {es3fFragDepthTests.EvalFragDepthFunc} */ this.m_evalFunc = evalFunc;
+ };
+
+ es3fFragDepthTests.FragDepthWriteCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fFragDepthTests.FragDepthWriteCase.prototype.constructor = es3fFragDepthTests.FragDepthWriteCase;
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fFragDepthTests.FragDepthWriteCase.prototype.iterate = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name));
+ /** @type {number} */ var viewportW = Math.min(128, gl.drawingBufferWidth);
+ /** @type {number} */ var viewportH = Math.min(128, gl.drawingBufferHeight);
+ /** @type {number} */ var viewportX = rnd.getInt(0, gl.drawingBufferWidth - viewportW);
+ /** @type {number} */ var viewportY = rnd.getInt(0, gl.drawingBufferHeight - viewportH);
+ /** @type {tcuSurface.Surface} */ var renderedFrame = new tcuSurface.Surface(viewportW, viewportH);
+ /** @type {tcuSurface.Surface} */ var referenceFrame = new tcuSurface.Surface(viewportW, viewportH);
+ /** @type {number} */ var numDepthSteps = 16;
+ /** @type {number} */ var depthStep = 1.0 / (numDepthSteps - 1);
+ var depthBits = /** @type {number} */ (gl.getParameter(gl.DEPTH_BITS));
+
+ if (depthBits === 0)
+ throw new Error('Depth buffer is required');
+
+ gl.depthMask(true);
+ gl.viewport(viewportX, viewportY, viewportW, viewportH);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ gl.enable(gl.DEPTH_TEST);
+ gl.depthFunc(gl.LESS);
+
+ /** @type {Array<number>} */ var quadIndices = [0, 1, 2, 2, 1, 3];
+
+ // Render with given shader.
+ /** @type {gluShaderProgram.ShaderProgram} */
+ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(es3fFragDepthTests.s_vertexShaderSrc, this.m_fragSrc));
+ bufferedLogToConsole(program.getProgramInfo().infoLog);
+
+ if (!program.isOk())
+ throw new Error('Compile failed');
+
+ /** @type {Array<number>} */ var coord = [
+ 0.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 0.0,
+ 1.0, 1.0
+ ];
+
+ /** @type {Array<number>} */ var position = [
+ -1.0, -1.0, +1.0, 1.0,
+ -1.0, 1.0, 0.0, 1.0,
+ 1.0, -1.0, 0.0, 1.0,
+ 1.0, 1.0, -1.0, 1.0
+ ];
+
+ gl.useProgram(program.getProgram());
+ gl.uniform4f(gl.getUniformLocation(program.getProgram(), 'u_color'), 0.0, 1.0, 0.0, 1.0);
+
+ // Setup default helper uniforms.
+ glsShaderRenderCase.setupDefaultUniforms(program.getProgram());
+
+ /** @type {Array<gluDrawUtil.VertexArrayBinding>} */ var vertexArrays = [
+ gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, position),
+ gluDrawUtil.newFloatVertexArrayBinding('a_coord', 2, 4, 0, coord)
+ ];
+ gluDrawUtil.draw(gl, program.getProgram(), vertexArrays, gluDrawUtil.triangles(quadIndices));
+
+ // Visualize by rendering full-screen quads with increasing depth and color.
+ program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(es3fFragDepthTests.s_vertexShaderSrc, es3fFragDepthTests.s_defaultFragmentShaderSrc));
+
+ if (!program.isOk()) {
+ bufferedLogToConsole(program.getProgramInfo().infoLog);
+ throw new Error('Compile failed');
+ }
+
+ /** @type {WebGLUniformLocation} */ var colorLoc = gl.getUniformLocation(program.getProgram(), 'u_color');
+
+ gl.useProgram(program.getProgram());
+ gl.depthMask(false);
+
+ for (var stepNdx = 0; stepNdx < numDepthSteps; stepNdx++) {
+ /** @type {number} */ var f = stepNdx * depthStep;
+ /** @type {number} */ var depth = f * 2.0 - 1.0;
+ /** @type {Array<number>} */ var color = [f, f, f, 1.0];
+
+ position = [
+ -1.0, -1.0, depth, 1.0,
+ -1.0, 1.0, depth, 1.0,
+ 1.0, -1.0, depth, 1.0,
+ 1.0, 1.0, depth, 1.0
+ ];
+
+ /** @type {gluDrawUtil.VertexArrayBinding} */
+ var posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, position);
+
+ gl.uniform4fv(colorLoc, color);
+ gluDrawUtil.draw(gl, program.getProgram(), [posBinding], gluDrawUtil.triangles(quadIndices));
+ }
+
+ renderedFrame.readViewport(gl, [viewportX, viewportY, viewportW, viewportH]);
+
+ // Render reference.
+ for (var y = 0; y < referenceFrame.getHeight(); y++)
+ for (var x = 0; x < referenceFrame.getWidth(); x++) {
+ /** @type {number} */ var xf = (x + 0.5) / referenceFrame.getWidth();
+ /** @type {number} */ var yf = (y + 0.5) / referenceFrame.getHeight();
+ /** @type {number} */ var d = this.m_evalFunc([xf, yf]);
+ /** @type {number} */ var step = Math.floor(d / depthStep);
+ /** @type {number} */ var col = deMath.clamp(Math.floor(step * depthStep * 255.0), 0, 255);
+
+ referenceFrame.setPixel(x, y, [col, col, col, 0xff]);
+ }
+
+ /** @type {boolean} */ var isOk = tcuImageCompare.fuzzyCompare('Result', 'Image comparison result', referenceFrame.getAccess(), renderedFrame.getAccess(), 0.05);
+
+ if (!isOk)
+ testFailedOptions('Fail', false);
+ else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fFragDepthTests.FragDepthTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'fragdepth', 'gl_FragDepth tests');
+ };
+
+ es3fFragDepthTests.FragDepthTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fFragDepthTests.FragDepthTests.prototype.constructor = es3fFragDepthTests.FragDepthTests;
+
+ /**
+ * @param {Array<number>} coord
+ * @return {number}
+ */
+ es3fFragDepthTests.evalConstDepth = function(coord) {
+ return 0.5;
+ };
+
+ /**
+ * @param {Array<number>} coord
+ * @return {number}
+ */
+ es3fFragDepthTests.evalDynamicDepth = function(coord) {
+ return (coord[0] + coord[1]) * 0.5;
+ };
+
+ /**
+ * @param {Array<number>} coord
+ * @return {number}
+ */
+ es3fFragDepthTests.evalNoWrite = function(coord) {
+ return 1.0 - (coord[0] + coord[1]) * 0.5;
+ };
+
+ /**
+ * @param {Array<number>} coord
+ * @return {number}
+ */
+ es3fFragDepthTests.evalDynamicConditionalDepth = function(coord) {
+ /** @type {number} */ var d = (coord[0] + coord[1]) * 0.5;
+ if (coord[1] < 0.5)
+ return d;
+ else
+ return 1.0 - d;
+ };
+
+ es3fFragDepthTests.FragDepthTests.prototype.init = function() {
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {string} desc
+ * @param {es3fFragDepthTests.EvalFragDepthFunc} evalFunc
+ * @param {string} fragSrc
+ */
+ var Case = function(name, desc, evalFunc, fragSrc) {
+ /** @type {string} */ this.name = name;
+ /** @type {string} */ this.desc = desc;
+ /** @type {es3fFragDepthTests.EvalFragDepthFunc} */ this.evalFunc = evalFunc;
+ /** @type {string} */ this.fragSrc = fragSrc;
+ };
+
+ /** @type {Array<Case>} */ var cases = [
+ new Case('no_write', 'No gl_FragDepth write', es3fFragDepthTests.evalNoWrite,
+ '#version 300 es\n' +
+ 'uniform highp vec4 u_color;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = u_color;\n' +
+ '}\n'
+ ),
+ new Case('const', 'Const depth write', es3fFragDepthTests.evalConstDepth,
+ '#version 300 es\n' +
+ 'uniform highp vec4 u_color;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = u_color;\n' +
+ ' gl_FragDepth = 0.5;\n' +
+ '}\n'
+ ),
+ new Case('uniform', 'Uniform depth write', es3fFragDepthTests.evalConstDepth,
+ '#version 300 es\n' +
+ 'uniform highp vec4 u_color;\n' +
+ 'uniform highp float uf_half;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = u_color;\n' +
+ ' gl_FragDepth = uf_half;\n' +
+ '}\n'
+ ),
+ new Case('dynamic', 'Dynamic depth write', es3fFragDepthTests.evalDynamicDepth,
+ '#version 300 es\n' +
+ 'uniform highp vec4 u_color;\n' +
+ 'in highp vec2 v_coord;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = u_color;\n' +
+ ' gl_FragDepth = (v_coord.x+v_coord.y)*0.5;\n' +
+ '}\n'
+ ),
+ new Case('fragcoord_z', 'gl_FragDepth write from gl_FragCoord.z', es3fFragDepthTests.evalNoWrite,
+ '#version 300 es\n' +
+ 'uniform highp vec4 u_color;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = u_color;\n' +
+ ' gl_FragDepth = gl_FragCoord.z;\n' +
+ '}\n'
+ ),
+ new Case('uniform_conditional_write', 'Uniform conditional write', es3fFragDepthTests.evalDynamicDepth,
+ '#version 300 es\n' +
+ 'uniform highp vec4 u_color;\n' +
+ 'uniform bool ub_true;\n' +
+ 'in highp vec2 v_coord;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = u_color;\n' +
+ ' if (ub_true)\n' +
+ ' gl_FragDepth = (v_coord.x+v_coord.y)*0.5;\n' +
+ '}\n'
+ ),
+ new Case('dynamic_conditional_write', 'Uniform conditional write', es3fFragDepthTests.evalDynamicConditionalDepth,
+ '#version 300 es\n' +
+ 'uniform highp vec4 u_color;\n' +
+ 'uniform bool ub_true;\n' +
+ 'in highp vec2 v_coord;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = u_color;\n' +
+ ' mediump float d = (v_coord.x+v_coord.y)*0.5f;\n' +
+ ' if (v_coord.y < 0.5)\n' +
+ ' gl_FragDepth = d;\n' +
+ ' else\n' +
+ ' gl_FragDepth = 1.0 - d;\n' +
+ '}\n'
+ ),
+ new Case('uniform_loop_write', 'Uniform loop write', es3fFragDepthTests.evalConstDepth,
+ '#version 300 es\n' +
+ 'uniform highp vec4 u_color;\n' +
+ 'uniform int ui_two;\n' +
+ 'uniform highp float uf_fourth;\n' +
+ 'in highp vec2 v_coord;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = u_color;\n' +
+ ' gl_FragDepth = 0.0;\n' +
+ ' for (int i = 0; i < ui_two; i++)\n' +
+ ' gl_FragDepth += uf_fourth;\n' +
+ '}\n'
+ ),
+ new Case('write_in_function', 'Uniform loop write', es3fFragDepthTests.evalDynamicDepth,
+ '#version 300 es\n' +
+ 'uniform highp vec4 u_color;\n' +
+ 'uniform highp float uf_half;\n' +
+ 'in highp vec2 v_coord;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void myfunc (highp vec2 coord)\n' +
+ '{\n' +
+ ' gl_FragDepth = (coord.x+coord.y)*0.5;\n' +
+ '}\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = u_color;\n' +
+ ' myfunc(v_coord);\n' +
+ '}\n'
+ )
+ ];
+
+ var testGroup = tcuTestCase.runner.testCases;
+
+ // .write
+ /** @type {tcuTestCase.DeqpTest} */ var writeGroup = tcuTestCase.newTest('write', 'gl_FragDepth write tests');
+ testGroup.addChild(writeGroup);
+ for (var ndx = 0; ndx < cases.length; ndx++)
+ writeGroup.addChild(new es3fFragDepthTests.FragDepthWriteCase(cases[ndx].name, cases[ndx].desc, cases[ndx].fragSrc, cases[ndx].evalFunc));
+
+ // .compare
+ /** @type {tcuTestCase.DeqpTest} */ var compareGroup = tcuTestCase.newTest('compare', 'gl_FragDepth used with depth comparison');
+ testGroup.addChild(compareGroup);
+ for (var ndx = 0; ndx < cases.length; ndx++)
+ compareGroup.addChild(new es3fFragDepthTests.FragDepthCompareCase(cases[ndx].name, cases[ndx].desc, cases[ndx].fragSrc, cases[ndx].evalFunc, gl.LESS));
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fFragDepthTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fFragDepthTests.FragDepthTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fFragDepthTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFragmentOutputTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFragmentOutputTests.js
new file mode 100644
index 0000000000..b27eee7a6e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFragmentOutputTests.js
@@ -0,0 +1,1398 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fFragmentOutputTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('functional.gles3.es3fFboTestUtil');
+
+goog.scope(function() {
+
+var es3fFragmentOutputTests = functional.gles3.es3fFragmentOutputTests;
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
+var gluShaderUtil = framework.opengl.gluShaderUtil;
+var deRandom = framework.delibs.debase.deRandom;
+var tcuTestCase = framework.common.tcuTestCase;
+var gluTextureUtil = framework.opengl.gluTextureUtil;
+var tcuTexture = framework.common.tcuTexture;
+var tcuTextureUtil = framework.common.tcuTextureUtil;
+var deMath = framework.delibs.debase.deMath;
+var tcuImageCompare = framework.common.tcuImageCompare;
+
+ /** @type {WebGL2RenderingContext} */ var gl;
+
+ var DE_ASSERT = function(x) {
+ if (!x)
+ throw new Error('Assert failed');
+ };
+
+ /**
+ * es3fFragmentOutputTests.BufferSpec. Constructs the es3fFragmentOutputTests.BufferSpec object
+ * @constructor
+ * @param {WebGLRenderingContextBase.GLenum} format_
+ * @param {number} width_
+ * @param {number} height_
+ * @param {number} samples_
+ */
+ es3fFragmentOutputTests.BufferSpec = function(format_, width_, height_, samples_) {
+ this.format = format_;
+ this.width = width_;
+ this.height = height_;
+ this.samples = samples_;
+ };
+
+ /**
+ * es3fFragmentOutputTests.FragmentOutput. Constructs the es3fFragmentOutputTests.FragmentOutput object
+ * @constructor
+ * @param {gluShaderUtil.DataType} type_
+ * @param {gluShaderUtil.precision} precision_
+ * @param {number} location_
+ * @param {number=} arrayLength_
+ */
+ es3fFragmentOutputTests.FragmentOutput = function(type_, precision_, location_, arrayLength_) {
+ this.type = type_;
+ this.precision = precision_;
+ this.location = location_;
+ this.arrayLength = arrayLength_ || 0;
+ };
+
+ /**
+ * es3fFragmentOutputTests.FragmentOutputCase. Constructs the es3fFragmentOutputTests.FragmentOutputCase object
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ * @param {Array<es3fFragmentOutputTests.BufferSpec>} fboSpec
+ * @param {Array<es3fFragmentOutputTests.FragmentOutput>} outputs
+ * @return {Object} The currently modified object
+ */
+ es3fFragmentOutputTests.FragmentOutputCase = function(name, description, fboSpec, outputs) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ /** @type {Array<es3fFragmentOutputTests.BufferSpec>} */ this.m_fboSpec = fboSpec;
+ /** @type {Array<es3fFragmentOutputTests.FragmentOutput>} */ this.m_outputs = outputs;
+ /** @type {gluShaderProgram.ShaderProgram} */ this.m_program = null;
+ /** @type {WebGLFramebuffer} */ this.m_framebuffer = null;
+
+ /** @type {WebGLRenderbuffer} */ this.m_renderbuffer = null;
+ };
+
+ es3fFragmentOutputTests.FragmentOutputCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fFragmentOutputTests.FragmentOutputCase.prototype.constructor = es3fFragmentOutputTests.FragmentOutputCase;
+
+ /**
+ * es3fFragmentOutputTests.createProgram. Returns a ShaderProgram object
+ * @param {Array<es3fFragmentOutputTests.FragmentOutput>} outputs
+ * @return {gluShaderProgram.ShaderProgram} program
+ */
+ es3fFragmentOutputTests.createProgram = function(outputs) {
+
+ var vtx = '';
+ var frag = '';
+
+ vtx = '#version 300 es\n' + 'in highp vec4 a_position;\n';
+ frag = '#version 300 es\n';
+
+ /** @type {es3fFragmentOutputTests.FragmentOutput} */ var output = null;
+ /** @type {boolean} */ var isArray = false;
+ // Input-output declarations.
+ for (var outNdx = 0; outNdx < outputs.length; outNdx++) {
+ output = outputs[outNdx];
+ isArray = output.arrayLength > 0;
+ /** @type {string} */ var typeName = gluShaderUtil.getDataTypeName(output.type);
+ /** @type {string} */ var precName = gluShaderUtil.getPrecisionName(output.precision);
+ /** @type {boolean} */ var isFloat = gluShaderUtil.isDataTypeFloatOrVec(output.type);
+ /** @type {string} */ var interp = isFloat ? 'smooth' : 'flat';
+
+ if (isArray) {
+ for (var elemNdx = 0; elemNdx < output.arrayLength; elemNdx++) {
+ vtx += 'in ' + precName + ' ' + typeName + ' in' + outNdx + '_' + elemNdx + ';\n' +
+ interp + ' out ' + precName + ' ' + typeName + ' var' + outNdx + '_' + elemNdx + ';\n';
+ frag += interp + ' in ' + precName + ' ' + typeName + ' var' + outNdx + '_' + elemNdx + ';\n';
+ }
+ frag += 'layout(location = ' + output.location + ') out ' + precName + ' ' + typeName + ' out' + outNdx + '[' + output.arrayLength + '];\n';
+ } else {
+ vtx += 'in ' + precName + ' ' + typeName + ' in' + outNdx + ';\n' +
+ interp + ' out ' + precName + ' ' + typeName + ' var' + outNdx + ';\n';
+ frag += interp + ' in ' + precName + ' ' + typeName + ' var' + outNdx + ';\n' +
+ 'layout(location = ' + output.location + ') out ' + precName + ' ' + typeName + ' out' + outNdx + ';\n';
+ }
+ }
+
+ vtx += '\nvoid main()\n{\n';
+ frag += '\nvoid main()\n{\n';
+
+ vtx += ' gl_Position = a_position;\n';
+
+ // Copy body
+ for (var outNdx = 0; outNdx < outputs.length; outNdx++) {
+ output = outputs[outNdx];
+ isArray = output.arrayLength > 0;
+
+ if (isArray) {
+ for (var elemNdx = 0; elemNdx < output.arrayLength; elemNdx++) {
+ vtx += '\tvar' + outNdx + '_' + elemNdx + ' = in' + outNdx + '_' + elemNdx + ';\n';
+ frag += '\tout' + outNdx + '[' + elemNdx + '] = var' + outNdx + '_' + elemNdx + ';\n';
+ }
+ } else {
+ vtx += '\tvar' + outNdx + ' = in' + outNdx + ';\n';
+ frag += '\tout' + outNdx + ' = var' + outNdx + ';\n';
+ }
+ }
+
+ vtx += '}\n';
+ frag += '}\n';
+
+ /** @type {gluShaderProgram.ShaderProgram} */
+ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vtx, frag));
+ return program;
+ };
+
+ es3fFragmentOutputTests.FragmentOutputCase.prototype.init = function() {
+ // Check that all attachments are supported
+ for (var iter = 0; iter < this.m_fboSpec.length; ++iter) {
+ if (!gluTextureUtil.isSizedFormatColorRenderable(this.m_fboSpec[iter].format))
+ throw new Error('Unsupported attachment format');
+ }
+
+ DE_ASSERT(!this.m_program);
+ this.m_program = es3fFragmentOutputTests.createProgram(this.m_outputs);
+
+ // log << *m_program;
+ if (!this.m_program.isOk())
+ throw new Error('Compile failed. Program no created');
+
+ /*
+ // Print render target info to log.
+ log << TestLog::Section("Framebuffer", "Framebuffer configuration");
+
+ for (int ndx = 0; ndx < (int)m_fboSpec.size(); ndx++)
+ log << TestLog::Message << "COLOR_ATTACHMENT" << ndx << ": "
+ << glu::getPixelFormatStr(m_fboSpec[ndx].format) << ", "
+ << m_fboSpec[ndx].width << "x" << m_fboSpec[ndx].height << ", "
+ << m_fboSpec[ndx].samples << " samples"
+ << TestLog::EndMessage;
+
+ log << TestLog::EndSection;*/
+
+ // Create framebuffer.
+ this.m_framebuffer = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.m_framebuffer);
+
+ for (var bufNdx = 0; bufNdx < /* m_renderbuffers.size() */ this.m_fboSpec.length; bufNdx++) {
+ this.m_renderbuffer = gl.createRenderbuffer();
+ /** @type {es3fFragmentOutputTests.BufferSpec} */ var bufSpec = this.m_fboSpec[bufNdx];
+ /** @type {number} */ var attachment = gl.COLOR_ATTACHMENT0 + bufNdx;
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, this.m_renderbuffer);
+
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, bufSpec.samples, bufSpec.format, bufSpec.width, bufSpec.height);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, this.m_renderbuffer);
+ }
+ /** @type {number} */ var fboStatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ if (fboStatus == gl.FRAMEBUFFER_UNSUPPORTED)
+ throw new Error('Framebuffer not supported');
+ else if (fboStatus != gl.FRAMEBUFFER_COMPLETE)
+ throw new Error('Incomplete framebuffer');
+ // throw tcu::TestError((string("Incomplete framebuffer: ") + glu::getFramebufferStatusStr(fboStatus), "", __FILE__, __LINE__);
+
+ // gl.bindRenderbuffer(gl.RENDERBUFFER, null); // TODO: maybe needed?
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ };
+
+ es3fFragmentOutputTests.FragmentOutputCase.prototype.deinit = function() {
+ // TODO: implement?
+ };
+
+ /**
+ * es3fFragmentOutputTests.getMinSize.
+ * @param {Array<es3fFragmentOutputTests.BufferSpec>} fboSpec
+ * @return {Array<number>} minSize
+ */
+ es3fFragmentOutputTests.getMinSize = function(fboSpec) {
+ /** @type {Array<number>} */ var minSize = [0x7fffffff, 0x7fffffff];
+ for (var i = 0; i < fboSpec.length; i++) {
+ minSize[0] = Math.min(minSize[0], fboSpec[i].width);
+ minSize[1] = Math.min(minSize[1], fboSpec[i].height);
+ }
+ return minSize;
+ };
+
+ /**
+ * es3fFragmentOutputTests.getNumInputVectors. Returns the length of the array of all the outputs (es3fFragmentOutputTests.FragmentOutput object)
+ * @param {Array<es3fFragmentOutputTests.FragmentOutput>} outputs
+ * @return {number} numVecs
+ */
+ es3fFragmentOutputTests.getNumInputVectors = function(outputs) {
+ /** @type {number} */ var numVecs = 0;
+ for (var i = 0; i < outputs.length; i++)
+ numVecs += (outputs[i].arrayLength > 0 ? outputs[i].arrayLength : 1);
+ return numVecs;
+ };
+
+ /**
+ * es3fFragmentOutputTests.getFloatRange
+ * @param {gluShaderUtil.precision} precision
+ * @return {Array<number>} Vec2
+ */
+ es3fFragmentOutputTests.getFloatRange = function(precision) {
+ /** @type {Array<Array<number>>} */
+ var ranges = // Vec2
+ [
+ [-2.0, 2.0],
+ [-16000.0, 16000.0],
+ [-1e35, 1e35]
+ ];
+ // DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(ranges) == glu::PRECISION_LAST);
+ // DE_ASSERT(de::inBounds<int>(precision, 0, DE_LENGTH_OF_ARRAY(ranges)));
+ return ranges[precision];
+ };
+
+ /**
+ * es3fFragmentOutputTests.getIntRange
+ * @param {gluShaderUtil.precision} precision
+ * @return {Array<number>} IVec2
+ */
+ es3fFragmentOutputTests.getIntRange = function(precision) {
+ /** @type {Array<Array<number>>} */
+ var ranges = // IVec2
+ [
+ [-(1 << 7), (1 << 7) - 1],
+ [-(1 << 15), (1 << 15) - 1],
+ [-0x80000000, 0x7fffffff]
+ ];
+ // DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(ranges) == glu::PRECISION_LAST);
+ // DE_ASSERT(de::inBounds<int>(precision, 0, DE_LENGTH_OF_ARRAY(ranges)));
+ return ranges[precision];
+ };
+
+ /**
+ * es3fFragmentOutputTests.getUintRange
+ * @param {gluShaderUtil.precision} precision
+ * @return {Array<number>} UVec2
+ */
+ es3fFragmentOutputTests.getUintRange = function(precision) {
+ /** @type {Array<Array<number>>} */
+ var ranges = // UVec2
+ [
+ [0, (1 << 8) - 1],
+ [0, (1 << 16) - 1],
+ [0, 0xffffffff]
+ ];
+ // DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(ranges) == glu::PRECISION_LAST);
+ // DE_ASSERT(de::inBounds<int>(precision, 0, DE_LENGTH_OF_ARRAY(ranges)));
+ return ranges[precision];
+
+ };
+
+ /**
+ * es3fFragmentOutputTests.readVec4
+ * @param {Array<number>} ptr
+ * @param {number} index
+ * @param {number} numComponents
+ * @return {Array<number>} Vec4
+ */
+ es3fFragmentOutputTests.readVec4 = function(ptr, index, numComponents) {
+ DE_ASSERT(numComponents >= 1);
+ return [
+ ptr[index + 0],
+ numComponents >= 2 ? ptr[index + 1] : 0.0,
+ numComponents >= 3 ? ptr[index + 2] : 0.0,
+ numComponents >= 4 ? ptr[index + 3] : 0.0
+ ];
+ };
+
+ /**
+ * es3fFragmentOutputTests.readIVec4
+ * @param {Array<number>} ptr
+ * @param {number} numComponents
+ * @return {Array<number>} IVec4
+ */
+ es3fFragmentOutputTests.readIVec4 = function(ptr, index, numComponents) {
+ DE_ASSERT(numComponents >= 1);
+ return [
+ ptr[index + 0],
+ numComponents >= 2 ? ptr[index + 1] : 0,
+ numComponents >= 3 ? ptr[index + 2] : 0,
+ numComponents >= 4 ? ptr[index + 3] : 0
+ ];
+ };
+
+ /**
+ * es3fFragmentOutputTests.renderFloatReference
+ * @param {tcuTexture.PixelBufferAccess} dst
+ * @param {number} gridWidth
+ * @param {number} gridHeight
+ * @param {number} numComponents
+ * @param {Array<number>} vertices
+ */
+ es3fFragmentOutputTests.renderFloatReference = function(dst, gridWidth, gridHeight, numComponents, vertices) {
+
+ /** @type {boolean} */ var isSRGB = dst.getFormat().order == tcuTexture.ChannelOrder.sRGB || dst.getFormat().order == tcuTexture.ChannelOrder.sRGBA;
+ /** @type {number} */ var cellW = dst.getWidth() / (gridWidth - 1);
+ /** @type {number} */ var cellH = dst.getHeight() / (gridHeight - 1);
+
+ for (var y = 0; y < dst.getHeight(); y++) {
+ for (var x = 0; x < dst.getWidth(); x++) {
+ /** @type {number} */ var cellX = deMath.clamp(Math.floor(x / cellW), 0, gridWidth - 2);
+ /** @type {number} */ var cellY = deMath.clamp(Math.floor(y / cellH), 0, gridHeight - 2);
+ /** @type {number} */ var xf = (x - cellX * cellW + 0.5) / cellW;
+ /** @type {number} */ var yf = (y - cellY * cellH + 0.5) / cellH;
+
+ /** @type {Array<number>} */ var v00 = es3fFragmentOutputTests.readVec4(vertices, ((cellY + 0) * gridWidth + cellX + 0) * numComponents, numComponents); // Vec4
+ /** @type {Array<number>} */ var v01 = es3fFragmentOutputTests.readVec4(vertices, ((cellY + 1) * gridWidth + cellX + 0) * numComponents, numComponents); // Vec4
+ /** @type {Array<number>} */ var v10 = es3fFragmentOutputTests.readVec4(vertices, ((cellY + 0) * gridWidth + cellX + 1) * numComponents, numComponents); // Vec4
+ /** @type {Array<number>} */ var v11 = es3fFragmentOutputTests.readVec4(vertices, ((cellY + 1) * gridWidth + cellX + 1) * numComponents, numComponents); // Vec4
+
+ /** @type {boolean} */ var tri = xf + yf >= 1.0;
+ /** @type {Array<number>} */ var v0 = tri ? v11 : v00; // Vec4&
+ /** @type {Array<number>} */ var v1 = tri ? v01 : v10; // Vec4&
+ /** @type {Array<number>} */ var v2 = tri ? v10 : v01; // Vec4&
+ /** @type {number} */ var s = tri ? 1.0 - xf : xf;
+ /** @type {number} */ var t = tri ? 1.0 - yf : yf;
+ /** @type {Array<number>} */ var color = deMath.add(v0, deMath.add(deMath.multiply((deMath.subtract(v1, v0)), [s, s, s, s]), deMath.multiply((deMath.subtract(v2, v0)), [t, t, t, t]))); // Vec4
+
+ dst.setPixel(isSRGB ? tcuTextureUtil.linearToSRGB(color) : color, x, y);
+ }
+ }
+ };
+
+ /**
+ * es3fFragmentOutputTests.renderIntReference
+ * @param {tcuTexture.PixelBufferAccess} dst
+ * @param {number} gridWidth
+ * @param {number} gridHeight
+ * @param {number} numComponents
+ * @param {Array<number>} vertices
+ */
+ es3fFragmentOutputTests.renderIntReference = function(dst, gridWidth, gridHeight, numComponents, vertices) {
+
+ /** @type {number} */ var cellW = dst.getWidth() / (gridWidth - 1);
+ /** @type {number} */ var cellH = dst.getHeight() / (gridHeight - 1);
+
+ for (var y = 0; y < dst.getHeight(); y++) {
+ for (var x = 0; x < dst.getWidth(); x++) {
+ /** @type {number} */ var cellX = deMath.clamp(Math.floor(x / cellW), 0, gridWidth - 2);
+ /** @type {number} */ var cellY = deMath.clamp(Math.floor(y / cellH), 0, gridHeight - 2);
+ /** @type {Array<number>} */ var c = es3fFragmentOutputTests.readIVec4(vertices, (cellY * gridWidth + cellX + 1) * numComponents, numComponents); // IVec4
+
+ dst.setPixelInt(c, x, y);
+ }
+ }
+ };
+
+ /**
+ * es3fFragmentOutputTests.s_swizzles
+ * @return {Array<Array<number>>}
+ */
+ es3fFragmentOutputTests.s_swizzles = function() {
+ var mat_swizzles = [
+ [0, 1, 2, 3],
+ [1, 2, 3, 0],
+ [2, 3, 0, 1],
+ [3, 0, 1, 2],
+ [3, 2, 1, 0],
+ [2, 1, 0, 3],
+ [1, 0, 3, 2],
+ [0, 3, 2, 1]
+ ];
+
+ return mat_swizzles;
+ };
+
+ /**
+ * es3fFragmentOutputTests.swizzleVec. Returns an Array from a position contained in the Array es3fFragmentOutputTests.s_swizzles []
+ * @param {Array<number>} vec
+ * @param {number} swzNdx
+ * @return {Array<number>} Swizzled array
+ */
+ es3fFragmentOutputTests.swizzleVec = function(vec, swzNdx) {
+ /** @type {Array<number>} */ var swz = es3fFragmentOutputTests.s_swizzles()[swzNdx % es3fFragmentOutputTests.s_swizzles().length];
+
+ return deMath.swizzle(vec, swz);
+ };
+
+ /**
+ * es3fFragmentOutputTests.AttachmentData struct class
+ * @constructor
+ * @return {Object}
+ */
+ es3fFragmentOutputTests.AttachmentData = function() {
+ return {
+ /** @type {tcuTexture.TextureFormat} */ format: null, //!< Actual format of attachment.
+ /** @type {tcuTexture.TextureFormat} */ referenceFormat: null, //!< Used for reference rendering.
+ /** @type {tcuTexture.TextureFormat} */ readFormat: null,
+ /** @type {number} */ numWrittenChannels: 0,
+ /** @type {gluShaderUtil.precision} */ outPrecision: gluShaderUtil.precision.PRECISION_LOWP,
+ /** @type {ArrayBuffer} */ renderedData: null,
+ /** @type {ArrayBuffer} */ referenceData: null
+ };
+ };
+
+ es3fFragmentOutputTests.FragmentOutputCase.prototype.iterate = function() {
+ // Compute grid size & index list.
+ /** @type {number} */ var minCellSize = 8;
+ /** @type {Array<number>} */ var minBufSize = es3fFragmentOutputTests.getMinSize(this.m_fboSpec); // IVec2
+ /** @type {number} */ var gridWidth = deMath.clamp(Math.floor(minBufSize[0] / minCellSize), 1, 255) + 1;
+ /** @type {number} */ var gridHeight = deMath.clamp(Math.floor(minBufSize[1] / minCellSize), 1, 255) + 1;
+ /** @type {number} */ var numVertices = gridWidth * gridHeight;
+ /** @type {number} */ var numQuads = (gridWidth - 1) * (gridHeight - 1);
+ /** @type {number} */ var numIndices = numQuads * 6;
+
+ /** @type {number} */ var numInputVecs = es3fFragmentOutputTests.getNumInputVectors(this.m_outputs);
+ /** @type {Array<Array<number>>} */ var inputs = []; // originally vector<vector<deUint32>
+
+ for (var inputNdx = 0; inputNdx < numInputVecs; inputNdx++)
+ inputs[inputNdx] = []; // inputs.length = numInputVecs;
+
+ /** @type {Array<number>} */ var positions = []; // originally vector<float>
+ /** @type {Array<number>} */ var indices = []; // originally vector<deUint16>
+
+ /** @type {number} */ var readAlignment = 4;
+ /** @type {number} */ var viewportW = minBufSize[0];
+ /** @type {number} */ var viewportH = minBufSize[1];
+ /** @type {number} */ var numAttachments = this.m_fboSpec.length;
+
+ /** @type {Array<number>} */ var drawBuffers = []; // originally vector<deUint32>
+ /** @type {Array<es3fFragmentOutputTests.AttachmentData>} */ var attachments = [];
+ /** @type {number} */ var attachmentW;
+ /** @type {number} */ var attachmentH;
+
+ // Initialize attachment data.
+ for (var ndx = 0; ndx < numAttachments; ndx++) {
+ /** @type {tcuTexture.TextureFormat} */ var texFmt = gluTextureUtil.mapGLInternalFormat(this.m_fboSpec[ndx].format);
+ /** @type {tcuTexture.TextureChannelClass} */ var chnClass = tcuTexture.getTextureChannelClass(texFmt.type);
+ /** @type {boolean} */ var isFixedPoint = (chnClass == tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT ||
+ chnClass == tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT);
+
+ // \note Fixed-point formats use float reference to enable more accurate result verification.
+ /** @type {tcuTexture.TextureFormat} */ var refFmt = isFixedPoint ? new tcuTexture.TextureFormat(texFmt.order, tcuTexture.ChannelType.FLOAT) : texFmt;
+ /** @type {tcuTexture.TextureFormat} */ var readFmt = es3fFboTestUtil.getFramebufferReadFormat(texFmt);
+ attachmentW = this.m_fboSpec[ndx].width;
+ attachmentH = this.m_fboSpec[ndx].height;
+
+ drawBuffers[ndx] = gl.COLOR_ATTACHMENT0 + ndx;
+ attachments[ndx] = new es3fFragmentOutputTests.AttachmentData();
+ attachments[ndx].format = texFmt;
+ attachments[ndx].readFormat = readFmt;
+ attachments[ndx].referenceFormat = refFmt;
+ attachments[ndx].renderedData = new ArrayBuffer(readFmt.getPixelSize() * attachmentW * attachmentH);
+ attachments[ndx].referenceData = new ArrayBuffer(refFmt.getPixelSize() * attachmentW * attachmentH);
+ }
+
+ // Initialize indices.
+ for (var quadNdx = 0; quadNdx < numQuads; quadNdx++) {
+ /** @type {number} */ var quadY = Math.floor(quadNdx / (gridWidth - 1));
+ /** @type {number} */ var quadX = quadNdx - quadY * (gridWidth - 1);
+
+ indices[quadNdx * 6 + 0] = quadX + quadY * gridWidth;
+ indices[quadNdx * 6 + 1] = quadX + (quadY + 1) * gridWidth;
+ indices[quadNdx * 6 + 2] = quadX + quadY * gridWidth + 1;
+ indices[quadNdx * 6 + 3] = indices[quadNdx * 6 + 1];
+ indices[quadNdx * 6 + 4] = quadX + (quadY + 1) * gridWidth + 1;
+ indices[quadNdx * 6 + 5] = indices[quadNdx * 6 + 2];
+ }
+
+ /** @type {number} */ var xf = 0;
+ /** @type {number} */ var yf = 0;
+ for (var y = 0; y < gridHeight; y++) {
+ for (var x = 0; x < gridWidth; x++) {
+ xf = x / (gridWidth - 1);
+ yf = y / (gridHeight - 1);
+
+ positions[(y * gridWidth + x) * 4 + 0] = 2.0 * xf - 1.0;
+ positions[(y * gridWidth + x) * 4 + 1] = 2.0 * yf - 1.0;
+ positions[(y * gridWidth + x) * 4 + 2] = 0.0;
+ positions[(y * gridWidth + x) * 4 + 3] = 1.0;
+ }
+ }
+ /** @type {es3fFragmentOutputTests.FragmentOutput} */ var output;
+ /** @type {boolean} */ var isArray;
+ /** @type {boolean} */ var isFloat;
+ /** @type {boolean} */ var isInt;
+ /** @type {boolean} */ var isUint;
+ /** @type {number} */ var numVecs;
+ /** @type {number} */ var numScalars;
+
+ var curInVec = 0;
+ for (var outputNdx = 0; outputNdx < this.m_outputs.length; outputNdx++) {
+ output = this.m_outputs[outputNdx];
+ isFloat = gluShaderUtil.isDataTypeFloatOrVec(output.type);
+ isInt = gluShaderUtil.isDataTypeIntOrIVec(output.type);
+ isUint = gluShaderUtil.isDataTypeUintOrUVec(output.type);
+ numVecs = output.arrayLength > 0 ? output.arrayLength : 1;
+ numScalars = gluShaderUtil.getDataTypeScalarSize(output.type);
+
+ for (var vecNdx = 0; vecNdx < numVecs; vecNdx++) {
+ inputs[curInVec].length = numVertices * numScalars;
+
+ // Record how many outputs are written in attachment.
+ DE_ASSERT(output.location + vecNdx < attachments.length);
+ attachments[output.location + vecNdx].numWrittenChannels = numScalars;
+ attachments[output.location + vecNdx].outPrecision = output.precision;
+
+ /** @type {Array<number>} */ var range = null;
+ /** @type {Array<number>} */ var minVal = null;
+ /** @type {Array<number>} */ var maxVal = null;
+ /** @type {Array<number>} */ var fmtBits = null;
+ /** @type {Array<number>} */ var fmtMaxVal = [];
+ /** @type {Array<number>} */ var rangeDiv = null;
+ /** @type {Array<number>} */ var step = [];
+ /** @type {number} */ var ix = 0;
+ /** @type {number} */ var iy = 0;
+ /** @type {Array<number>} */ var c = null;
+ /** @type {number} */ var pos = 0;
+ if (isFloat) {
+ range = es3fFragmentOutputTests.getFloatRange(output.precision); // Vec2
+ minVal = [range[0], range[0], range[0], range[0]]; // Vec4
+ maxVal = [range[1], range[1], range[1], range[1]]; // Vec4
+
+ if (deMath.deInBounds32(output.location + vecNdx, 0, attachments.length)) {
+ // \note Floating-point precision conversion is not well-defined. For that reason we must
+ // limit value range to intersection of both data type and render target value ranges.
+ /** @type {tcuTextureUtil.TextureFormatInfo} */ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(attachments[output.location + vecNdx].format);
+ minVal = deMath.max(minVal, fmtInfo.valueMin);
+ maxVal = deMath.min(maxVal, fmtInfo.valueMax);
+ }
+
+ bufferedLogToConsole('out ' + curInVec + ' value range: ' + minVal + ' -> ' + maxVal);
+
+ for (var y = 0; y < gridHeight; y++) {
+ for (var x = 0; x < gridWidth; x++) {
+ xf = x / (gridWidth - 1);
+ yf = y / (gridHeight - 1);
+ /** @type {number} */ var f0 = (xf + yf) * 0.5;
+ /** @type {number} */ var f1 = 0.5 + (xf - yf) * 0.5;
+
+ /** @type {Array<number>} */ var f = es3fFragmentOutputTests.swizzleVec([f0, f1, 1.0 - f0, 1.0 - f1], curInVec); // Vec4
+ c = deMath.add(minVal, deMath.multiply(deMath.subtract(maxVal, minVal), f)); // Vec4
+
+ pos = (y * gridWidth + x) * numScalars;
+
+ for (var ndx = 0; ndx < numScalars; ndx++)
+ inputs[curInVec][pos + ndx] = c[ndx];
+ }
+ }
+ } else if (isInt) {
+ range = es3fFragmentOutputTests.getIntRange(output.precision); // IVec2
+ minVal = [range[0], range[0], range[0], range[0]]; // IVec4
+ maxVal = [range[1], range[1], range[1], range[1]]; // IVec4
+
+ if (deMath.deInBounds32(output.location + vecNdx, 0, attachments.length)) {
+ // Limit to range of output format as conversion mode is not specified.
+ fmtBits = tcuTextureUtil.getTextureFormatBitDepth(attachments[output.location + vecNdx].format); // IVec4
+ /** @type {Array<boolean>} */ var isZero = deMath.lessThanEqual(fmtBits, [0, 0, 0, 0]); // BVec4, array of booleans, size = 4
+
+ /** @type {Array<number>} */ var fmtMinVal = []; // IVec4
+
+ for (var i = 0; i < 4; i++) {
+
+ // const IVec4 fmtMinVal = (-(tcu::Vector<deInt64, 4>(1) << (fmtBits - 1 ).cast<deInt64>())).asInt();
+ fmtMinVal[i] = -1 * Math.pow(2, fmtBits[i] - 1); // TODO: check implementation, original above
+ // const IVec4 fmtMaxVal = ((tcu::Vector<deInt64, 4>(1) << (fmtBits - 1 ).cast<deInt64>()) - deInt64(1)).asInt();
+ fmtMaxVal[i] = Math.pow(2, fmtBits[i] - 1) - 1; // TODO: check implementation, original above
+ }
+
+ minVal = tcuTextureUtil.select(minVal, deMath.max(minVal, fmtMinVal), isZero);
+ maxVal = tcuTextureUtil.select(maxVal, deMath.min(maxVal, fmtMaxVal), isZero);
+ }
+
+ bufferedLogToConsole('out ' + curInVec + ' value range: ' + minVal + ' -> ' + maxVal);
+
+ rangeDiv = es3fFragmentOutputTests.swizzleVec([gridWidth - 1, gridHeight - 1, gridWidth - 1, gridHeight - 1], curInVec); // IVec4
+ for (var i = 0; i < 4; i++) {
+ // const IVec4 step = ((maxVal.cast<deInt64>() - minVal.cast<deInt64>()) / (rangeDiv.cast<deInt64>())).asInt();
+ step[i] = Math.floor((maxVal[i] - minVal[i]) / rangeDiv[i]); // TODO: check with the above line of code
+ }
+
+ for (var y = 0; y < gridHeight; y++) {
+ for (var x = 0; x < gridWidth; x++) {
+ ix = gridWidth - x - 1;
+ iy = gridHeight - y - 1;
+ c = deMath.add(minVal, deMath.multiply(step, es3fFragmentOutputTests.swizzleVec([x, y, ix, iy], curInVec))); // IVec4
+
+ pos = (y * gridWidth + x) * numScalars;
+
+ for (var ndx = 0; ndx < numScalars; ndx++)
+ inputs[curInVec][pos + ndx] = c[ndx];
+ }
+ }
+ } else if (isUint) {
+ range = es3fFragmentOutputTests.getUintRange(output.precision); // UVec2
+ maxVal = [range[1], range[1], range[1], range[1]]; // UVec4
+
+ if (deMath.deInBounds32(output.location + vecNdx, 0, attachments.length)) {
+ // Limit to range of output format as conversion mode is not specified.
+ fmtBits = tcuTextureUtil.getTextureFormatBitDepth(attachments[output.location + vecNdx].format); // IVec4
+
+ for (var i = 0; i < 4; i++) {
+ fmtMaxVal[i] = Math.pow(2, fmtBits[i]) - 1;
+ }
+
+ maxVal = deMath.min(maxVal, fmtMaxVal);
+ }
+
+ bufferedLogToConsole('out ' + curInVec + ' value range: ' + minVal + ' -> ' + maxVal);
+
+ rangeDiv = es3fFragmentOutputTests.swizzleVec([gridWidth - 1, gridHeight - 1, gridWidth - 1, gridHeight - 1], curInVec); // IVec4
+
+ for (var stepPos = 0; stepPos < maxVal.length; stepPos++) {
+ step[stepPos] = Math.floor(maxVal[stepPos] / rangeDiv[stepPos]);
+ }
+
+ DE_ASSERT(range[0] == 0);
+
+ for (var y = 0; y < gridHeight; y++) {
+ for (var x = 0; x < gridWidth; x++) {
+ ix = gridWidth - x - 1;
+ iy = gridHeight - y - 1;
+ c = deMath.multiply(step, es3fFragmentOutputTests.swizzleVec([x, y, ix, iy], curInVec)); // UVec4
+ pos = (y * gridWidth + x) * numScalars;
+
+ DE_ASSERT(deMath.boolAll(deMath.lessThanEqual(c, maxVal))); // TODO: sometimes crashes here, condition not asserted
+
+ for (var ndx = 0; ndx < numScalars; ndx++)
+ inputs[curInVec][pos + ndx] = c[ndx];
+ }
+ }
+ } else
+ DE_ASSERT(false);
+
+ curInVec += 1;
+ }
+ }
+
+ // Render using gl.
+ gl.useProgram(this.m_program.getProgram());
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.m_framebuffer);
+ gl.viewport(0, 0, viewportW, viewportH);
+ gl.drawBuffers(drawBuffers);
+ gl.disable(gl.DITHER); // Dithering causes issues with unorm formats. Those issues could be worked around in threshold, but it makes validation less accurate.
+
+ /** @type {WebGLBuffer} */ var buffer = null;
+ /** @type {string} */ var name;
+ curInVec = 0;
+ for (var outputNdx = 0; outputNdx < this.m_outputs.length; outputNdx++) {
+ output = this.m_outputs[outputNdx];
+ isArray = output.arrayLength > 0;
+ isFloat = gluShaderUtil.isDataTypeFloatOrVec(output.type);
+ isInt = gluShaderUtil.isDataTypeIntOrIVec(output.type);
+ isUint = gluShaderUtil.isDataTypeUintOrUVec(output.type);
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(output.type);
+ /** @type {number} */ var glScalarType = isFloat ? /* gluShaderUtil.DataType.FLOAT */ gl.FLOAT :
+ isInt ? /* gluShaderUtil.DataType.INT */ gl.INT :
+ isUint ? /* gluShaderUtil.DataType.UINT */ gl.UNSIGNED_INT : /* gluShaderUtil.DataType.INVALID */ gl.NONE;
+ numVecs = isArray ? output.arrayLength : 1;
+
+ for (var vecNdx = 0; vecNdx < numVecs; vecNdx++) {
+ name = 'in' + outputNdx + (isArray ? '_' + vecNdx : '');
+ /** @type {number} */ var loc = gl.getAttribLocation(this.m_program.getProgram(), name);
+
+ if (loc >= 0) {
+ buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+
+ gl.enableVertexAttribArray(loc);
+ if (isFloat) {
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(inputs[curInVec]), gl.STATIC_DRAW);
+ // KHRONOS WebGL 1.0 specification:
+ // void vertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLintptr offset);
+ gl.vertexAttribPointer(loc, scalarSize, glScalarType, false, 0, 0); // offset = 0
+ } else {
+ gl.bufferData(gl.ARRAY_BUFFER, new Int32Array(inputs[curInVec]), gl.STATIC_DRAW);
+ // KHRONOS WebGL 2.0 specification:
+ // void vertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset)
+ gl.vertexAttribIPointer(loc, scalarSize, glScalarType, 0, 0); // offset = 0
+ }
+ } else
+ bufferedLogToConsole('Warning: No location for attribute "' + name + '" found.');
+
+ curInVec += 1;
+ }
+ }
+
+ /** @type {number} */ var posLoc = gl.getAttribLocation(this.m_program.getProgram(), 'a_position');
+ // TCU_CHECK(posLoc >= 0);
+ buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
+
+ gl.enableVertexAttribArray(posLoc);
+ gl.vertexAttribPointer(posLoc, 4, gl.FLOAT, false, 0, 0); // offset = 0
+
+ /** @type {WebGLBuffer} */ var indexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexObject);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
+
+ gl.drawElements(gl.TRIANGLES, numIndices, gl.UNSIGNED_SHORT, 0); // offset = 0
+
+ // Render reference images.
+
+ var curInNdx = 0;
+ for (var outputNdx = 0; outputNdx < this.m_outputs.length; outputNdx++) {
+ output = this.m_outputs[outputNdx];
+ isArray = output.arrayLength > 0;
+ isFloat = gluShaderUtil.isDataTypeFloatOrVec(output.type);
+ isInt = gluShaderUtil.isDataTypeIntOrIVec(output.type);
+ isUint = gluShaderUtil.isDataTypeUintOrUVec(output.type);
+ scalarSize = gluShaderUtil.getDataTypeScalarSize(output.type);
+ numVecs = isArray ? output.arrayLength : 1;
+
+ for (var vecNdx = 0; vecNdx < numVecs; vecNdx++) {
+ /** @type {number} */ var location = output.location + vecNdx;
+ /** @type {Array<number>} */ var inputData = inputs[curInNdx];
+
+ DE_ASSERT(deMath.deInBounds32(location, 0, this.m_fboSpec.length));
+
+ /** @type {number} */ var bufW = this.m_fboSpec[location].width;
+ /** @type {number} */ var bufH = this.m_fboSpec[location].height;
+ /** @type {Object} */ var descriptor = {
+ format: attachments[location].referenceFormat,
+ width: bufW,
+ height: bufH,
+ depth: 1,
+ data: attachments[location].referenceData // ArrayBuffer
+ };
+ /** @type {tcuTexture.PixelBufferAccess} */ var buf = new tcuTexture.PixelBufferAccess(descriptor);
+ /** @type {tcuTexture.PixelBufferAccess} */ var viewportBuf = tcuTextureUtil.getSubregion(buf, 0, 0, 0, viewportW, viewportH, 1);
+
+ if (isInt || isUint)
+ es3fFragmentOutputTests.renderIntReference(viewportBuf, gridWidth, gridHeight, scalarSize, inputData);
+ else if (isFloat)
+ es3fFragmentOutputTests.renderFloatReference(viewportBuf, gridWidth, gridHeight, scalarSize, inputData);
+ else
+ DE_ASSERT(false);
+
+ curInNdx += 1;
+ }
+ }
+
+ // Compare all images.
+ /** @type {boolean} */ var allLevelsOk = true;
+ for (var attachNdx = 0; attachNdx < numAttachments; attachNdx++) {
+ attachmentW = this.m_fboSpec[attachNdx].width;
+ attachmentH = this.m_fboSpec[attachNdx].height;
+ /** @type {number} */ var numValidChannels = attachments[attachNdx].numWrittenChannels;
+ /** @type {Array<boolean>} */ var cmpMask = [numValidChannels >= 1, numValidChannels >= 2, numValidChannels >= 3, numValidChannels >= 4];
+ /** @type {gluShaderUtil.precision} */ var outPrecision = attachments[attachNdx].outPrecision;
+ /** @type {tcuTexture.TextureFormat} */ var format = attachments[attachNdx].format;
+ /** @type {Object} */
+ var renderedDescriptor = {
+ format: attachments[attachNdx].readFormat,
+ width: attachmentW,
+ height: attachmentH,
+ depth: 1,
+ rowPitch: deMath.deAlign32(attachments[attachNdx].readFormat.getPixelSize() * attachmentW, readAlignment),
+ slicePitch: 0,
+ data: attachments[attachNdx].renderedData // ArrayBuffer
+ };
+ /** @type {tcuTexture.PixelBufferAccess} */ var rendered = new tcuTexture.PixelBufferAccess(renderedDescriptor);
+ /** @type {gluTextureUtil.TransferFormat} */ var transferFmt = gluTextureUtil.getTransferFormat(attachments[attachNdx].readFormat);
+ gl.readBuffer(gl.COLOR_ATTACHMENT0 + attachNdx);
+ gl.readPixels(0, 0, attachmentW, attachmentH, transferFmt.format, transferFmt.dataType, rendered.getDataPtr());
+
+ /** @type {Object} */
+ var referenceDescriptor = {
+ format: attachments[attachNdx].referenceFormat,
+ width: attachmentW,
+ height: attachmentH,
+ depth: 1,
+ data: attachments[attachNdx].referenceData // ArrayBuffer
+ };
+ /** @type {tcuTexture.ConstPixelBufferAccess} */ var reference = new tcuTexture.ConstPixelBufferAccess(referenceDescriptor);
+ /** @type {tcuTexture.TextureChannelClass} */ var texClass = tcuTexture.getTextureChannelClass(format.type);
+ /** @type {boolean} */ var isOk = true;
+ name = 'Attachment ' + attachNdx;
+ /** @type {string} */ var desc = 'Color attachment ' + attachNdx;
+ /** @type {Array<number>} */ var threshold;
+
+ bufferedLogToConsole('Attachment ' + attachNdx + ': ' + numValidChannels + ' channels have defined values and used for comparison');
+
+ switch (texClass) {
+ case tcuTexture.TextureChannelClass.FLOATING_POINT: {
+ /** @type {Array<number>} */ var formatThreshold = []; // UVec4 //!< Threshold computed based on format.
+ formatThreshold.length = 4;
+ /** @type {number} */ var precThreshold = 0; // deUint32 //!< Threshold computed based on output type precision
+ /** @type {Array<number>} */ var finalThreshold = []; // UVec4
+ finalThreshold.length = 4;
+
+ switch (format.type) {
+ case tcuTexture.ChannelType.FLOAT:
+ formatThreshold = [4, 4, 4, 4]; // UVec4
+ break;
+ case tcuTexture.ChannelType.HALF_FLOAT:
+ formatThreshold = [(1 << 13) + 4, (1 << 13) + 4, (1 << 13) + 4, (1 << 13) + 4]; // UVec4
+ break;
+ case tcuTexture.ChannelType.UNSIGNED_INT_11F_11F_10F_REV:
+ formatThreshold = [(1 << 17) + 4, (1 << 17) + 4, (1 << 18) + 4, 4]; // UVec4
+ break;
+ default:
+ DE_ASSERT(false);
+ break;
+ }
+
+ switch (outPrecision) {
+ case gluShaderUtil.precision.PRECISION_LOWP:
+ precThreshold = (1 << 21);
+ break;
+ case gluShaderUtil.precision.PRECISION_MEDIUMP:
+ precThreshold = (1 << 13);
+ break;
+ case gluShaderUtil.precision.PRECISION_HIGHP:
+ precThreshold = 0;
+ break;
+ default:
+ DE_ASSERT(false);
+ }
+
+ finalThreshold = tcuTextureUtil.select(
+ deMath.max(formatThreshold, [precThreshold, precThreshold, precThreshold, precThreshold]),
+ [0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff], // C++ version: UVec4(~0u) bitwise not, all bits in the integer will be flipped
+ cmpMask);
+
+ isOk = tcuImageCompare.floatUlpThresholdCompare(name, desc, reference, rendered, finalThreshold /*, tcu::COMPARE_LOG_RESULT*/);
+ break;
+ }
+
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT: {
+ // \note glReadPixels() allows only 8 bits to be read. This means that RGB10_A2 will loose some
+ // bits in the process and it must be taken into account when computing threshold.
+ /** @type {Array<number>} */ var bits = deMath.min([8, 8, 8, 8], tcuTextureUtil.getTextureFormatBitDepth(format)); // IVec4
+
+ /** @type {Array<number>} */ var baseThreshold = []; // Vec4
+ baseThreshold.length = 4;
+ for (var inc = 0; inc < baseThreshold.length; inc++) {
+ // TODO: check the operation below: baseThreshold = 1.0f / ((IVec4(1) << bits)-1).asFloat();
+ baseThreshold[inc] = 1.0 / ((1 << bits[inc]) - 1);
+ }
+
+ threshold = tcuTextureUtil.select(baseThreshold, [2.0, 2.0, 2.0, 2.0], cmpMask); // Vec4
+
+ isOk = tcuImageCompare.floatThresholdCompare(name, desc, reference, rendered, threshold/*, tcu::COMPARE_LOG_RESULT*/);
+ break;
+ }
+
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER: {
+ // The C++ dEQP code uses ~0u but ~0 is -1 in Javascript
+ var UINT_MAX = Math.pow(2.0, 32.0) - 1;
+ threshold = tcuTextureUtil.select(
+ [0, 0, 0, 0],
+ [UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX],
+ cmpMask
+ ); // UVec4
+ isOk = tcuImageCompare.intThresholdCompare(name, desc, reference, rendered, threshold/*, tcu::COMPARE_LOG_RESULT*/);
+ break;
+ }
+
+ default:
+ testFailedOptions('Unsupported comparison', true);
+ break;
+ }
+
+ if (!isOk)
+ allLevelsOk = false;
+ }
+
+ if (numAttachments > 1) {
+ if (allLevelsOk)
+ testPassed('Image comparison passed for ' + numAttachments + ' attachments');
+ else
+ testFailed('Image comparison failed for some of ' + numAttachments + ' attachments');
+ } else {
+ if (allLevelsOk)
+ testPassed('Image comparison passed');
+ else
+ testFailed('Image comparison failed');
+ }
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * es3fFragmentOutputTests.createRandomCase. Constructs the es3fFragmentOutputTests.createRandomCase, child class of es3fFragmentOutputTests.FragmentOutputCase
+ * @constructor
+ * @param {number} minRenderTargets
+ * @param {number} maxRenderTargets
+ * @param {number} seed
+ * @return {es3fFragmentOutputTests.FragmentOutputCase} The currently modified object
+ */
+ es3fFragmentOutputTests.createRandomCase = function(minRenderTargets, maxRenderTargets, seed, colorBufferFloatSupported) {
+
+ /** @type {Array<gluShaderUtil.DataType>} */
+ var outputTypes = [
+ gluShaderUtil.DataType.FLOAT,
+ gluShaderUtil.DataType.FLOAT_VEC2,
+ gluShaderUtil.DataType.FLOAT_VEC3,
+ gluShaderUtil.DataType.FLOAT_VEC4,
+ gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT_VEC2,
+ gluShaderUtil.DataType.INT_VEC3,
+ gluShaderUtil.DataType.INT_VEC4,
+ gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT_VEC2,
+ gluShaderUtil.DataType.UINT_VEC3,
+ gluShaderUtil.DataType.UINT_VEC4
+ ];
+
+ /** @type {Array<gluShaderUtil.precision>} */
+ var precisions = [
+ gluShaderUtil.precision.PRECISION_LOWP,
+ gluShaderUtil.precision.PRECISION_MEDIUMP,
+ gluShaderUtil.precision.PRECISION_HIGHP
+ ];
+
+ /** @type {Array<WebGLRenderingContextBase.GLenum>} */
+ var floatFormats = [
+ gl.RGBA32F,
+ gl.RGBA16F,
+ gl.R11F_G11F_B10F,
+ gl.RG32F,
+ gl.RG16F,
+ gl.R32F,
+ gl.R16F,
+ gl.RGBA8,
+ gl.SRGB8_ALPHA8,
+ gl.RGB10_A2,
+ gl.RGBA4,
+ gl.RGB5_A1,
+ gl.RGB8,
+ gl.RGB565,
+ gl.RG8,
+ gl.R8
+ ];
+
+ /** @type {Array<WebGLRenderingContextBase.GLenum>} */
+ var colorBufferFloatFormats = [
+ gl.RGBA32F,
+ gl.RGBA16F,
+ gl.R11F_G11F_B10F,
+ gl.RG32F,
+ gl.RG16F,
+ gl.R32F,
+ gl.R16F
+ ];
+
+
+ /** @type {Array<WebGLRenderingContextBase.GLenum>} */
+ var intFormats = [
+ gl.RGBA32I,
+ gl.RGBA16I,
+ gl.RGBA8I,
+ gl.RG32I,
+ gl.RG16I,
+ gl.RG8I,
+ gl.R32I,
+ gl.R16I,
+ gl.R8I
+ ];
+
+ /** @type {Array<WebGLRenderingContextBase.GLenum>} */
+ var uintFormats = [
+ gl.RGBA32UI,
+ gl.RGBA16UI,
+ gl.RGBA8UI,
+ gl.RGB10_A2UI,
+ gl.RG32UI,
+ gl.RG16UI,
+ gl.RG8UI,
+ gl.R32UI,
+ gl.R16UI,
+ gl.R8UI
+ ];
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(seed);
+ /** @type {Array<es3fFragmentOutputTests.FragmentOutput>} */ var outputs = [];
+ /** @type {Array<es3fFragmentOutputTests.BufferSpec>} */ var targets = [];
+ /** @type {Array<gluShaderUtil.DataType>} */ var outTypes = [];
+
+ /** @type {number} */ var numTargets = rnd.getInt(minRenderTargets, maxRenderTargets);
+ /** @type {number} */ var width = 128; // \todo [2012-04-10 pyry] Separate randomized sizes per target?
+ /** @type {number} */ var height = 64;
+ /** @type {number} */ var samples = 0;
+
+ // Compute outputs.
+ /** @type {number} */ var curLoc = 0;
+ while (curLoc < numTargets) {
+ /** @type {boolean} */ var useArray = rnd.getFloat() < 0.3;
+ /** @type {number} */ var maxArrayLen = numTargets - curLoc;
+ /** @type {number} */ var arrayLen = useArray ? rnd.getInt(1, maxArrayLen) : 0;
+ /** @type {Array<gluShaderUtil.DataType>} */ var basicTypeArray = rnd.choose(outputTypes, undefined, 1);
+ /** @type {gluShaderUtil.DataType} */ var basicType = basicTypeArray[0];
+ /** @type {Array<gluShaderUtil.precision>} */ var precisionArray = rnd.choose(precisions, undefined, 1);
+ /** @type {gluShaderUtil.precision} */ var precision = precisionArray[0];
+ /** @type {number} */ var numLocations = useArray ? arrayLen : 1;
+
+ outputs.push(new es3fFragmentOutputTests.FragmentOutput(basicType, precision, curLoc, arrayLen));
+
+ for (var ndx = 0; ndx < numLocations; ndx++)
+ outTypes.push(basicType);
+
+ curLoc += numLocations;
+ }
+ DE_ASSERT(curLoc == numTargets);
+ DE_ASSERT(outTypes.length == numTargets);
+
+ // Compute buffers.
+ while (targets.length < numTargets) {
+ /** @type {gluShaderUtil.DataType} */ var outType = outTypes[targets.length];
+ /** @type {boolean} */ var isFloat = gluShaderUtil.isDataTypeFloatOrVec(outType);
+ /** @type {boolean} */ var isInt = gluShaderUtil.isDataTypeIntOrIVec(outType);
+ /** @type {boolean} */ var isUint = gluShaderUtil.isDataTypeUintOrUVec(outType);
+ /** @type {Array} */ var formatArray = [];
+ /** @type {number} */ var format = 0;
+
+ if (isFloat) {
+ formatArray = rnd.choose(floatFormats, undefined, 1);
+ format = formatArray[0];
+ if (colorBufferFloatFormats.indexOf(format) >= 0 && !colorBufferFloatSupported)
+ return null;
+ } else if (isInt) {
+ formatArray = rnd.choose(intFormats, undefined, 1);
+ format = formatArray[0];
+ } else if (isUint) {
+ formatArray = rnd.choose(uintFormats, undefined, 1);
+ format = formatArray[0];
+ } else
+ DE_ASSERT(false);
+
+ targets.push(new es3fFragmentOutputTests.BufferSpec(format, width, height, samples));
+ }
+
+ return new es3fFragmentOutputTests.FragmentOutputCase(seed.toString(), '', targets, outputs);
+
+ };
+
+ es3fFragmentOutputTests.init = function(gl) {
+ var state = tcuTestCase.runner;
+ state.testCases = tcuTestCase.newTest('fragment_outputs', 'Top level');
+ /** @const @type {tcuTestCase.DeqpTest} */ var testGroup = state.testCases;
+
+ /** @type {Array<WebGLRenderingContextBase.GLenum>} */
+ var requiredFloatFormats = [
+ gl.RGBA32F,
+ gl.RGBA16F,
+ gl.R11F_G11F_B10F,
+ gl.RG32F,
+ gl.RG16F,
+ gl.R32F,
+ gl.R16F
+ ];
+
+ /** @type {Array<WebGLRenderingContextBase.GLenum>} */
+ var requiredFixedFormats = [
+ gl.RGBA8,
+ gl.SRGB8_ALPHA8,
+ gl.RGB10_A2,
+ gl.RGBA4,
+ gl.RGB5_A1,
+ gl.RGB8,
+ gl.RGB565,
+ gl.RG8,
+ gl.R8
+ ];
+
+ /** @type {Array<WebGLRenderingContextBase.GLenum>} */
+ var requiredIntFormats = [
+ gl.RGBA32I,
+ gl.RGBA16I,
+ gl.RGBA8I,
+ gl.RG32I,
+ gl.RG16I,
+ gl.RG8I,
+ gl.R32I,
+ gl.R16I,
+ gl.R8I
+ ];
+
+ /** @type {Array<WebGLRenderingContextBase.GLenum>} */
+ var requiredUintFormats = [
+ gl.RGBA32UI,
+ gl.RGBA16UI,
+ gl.RGBA8UI,
+ gl.RGB10_A2UI,
+ gl.RG32UI,
+ gl.RG16UI,
+ gl.RG8UI,
+ gl.R32UI,
+ gl.R16UI,
+ gl.R8UI
+ ];
+
+ /** @type {Array<gluShaderUtil.precision>} */
+ var precisions = [
+
+ gluShaderUtil.precision.PRECISION_LOWP,
+ gluShaderUtil.precision.PRECISION_MEDIUMP,
+ gluShaderUtil.precision.PRECISION_HIGHP
+
+ ];
+
+ // .basic.
+
+ /** @const @type {number} */ var width = 64;
+ /** @const @type {number} */ var height = 64;
+ /** @const @type {number} */ var samples = 0;
+ /** @type {Array<es3fFragmentOutputTests.BufferSpec>} */ var fboSpec = null;
+ /** @type {gluShaderUtil.precision} */ var prec;
+ /** @type {string} */ var precName;
+
+ // .float
+ if (gl.getExtension('EXT_color_buffer_float')) {
+ /** @type {tcuTestCase.DeqpTest} */ var floatGroup = tcuTestCase.newTest('basic.float', 'Floating-point output tests');
+ testGroup.addChild(floatGroup);
+
+ for (var fmtNdx = 0; fmtNdx < requiredFloatFormats.length; fmtNdx++) {
+ var format = requiredFloatFormats[fmtNdx];
+ var fmtName = es3fFboTestUtil.getFormatName(format);
+ fboSpec = [];
+
+ fboSpec.push(new es3fFragmentOutputTests.BufferSpec(format, width, height, samples));
+
+ for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
+ prec = precisions[precNdx];
+ precName = gluShaderUtil.getPrecisionName(prec);
+
+ // NOTE: Eliminated original OutputVec and toVec(), as it only returned an element of the outputs array in OutputVec
+ floatGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_float', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT, prec, 0)]));
+ floatGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_vec2', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT_VEC2, prec, 0)]));
+ floatGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_vec3', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT_VEC3, prec, 0)]));
+ floatGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_vec4', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT_VEC4, prec, 0)]));
+ }
+ }
+ }
+
+ // .fixed
+ /** @type {tcuTestCase.DeqpTest} */ var fixedGroup = tcuTestCase.newTest('basic.fixed', 'Fixed-point output tests');
+ testGroup.addChild(fixedGroup);
+ for (var fmtNdx = 0; fmtNdx < requiredFixedFormats.length; fmtNdx++) {
+ var format = requiredFixedFormats[fmtNdx];
+ var fmtName = es3fFboTestUtil.getFormatName(format);
+ fboSpec = [];
+
+ fboSpec.push(new es3fFragmentOutputTests.BufferSpec(format, width, height, samples));
+
+ for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
+ prec = precisions[precNdx];
+ precName = gluShaderUtil.getPrecisionName(prec);
+
+ fixedGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_float', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT, prec, 0)]));
+ fixedGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_vec2', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT_VEC2, prec, 0)]));
+ fixedGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_vec3', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT_VEC3, prec, 0)]));
+ fixedGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_vec4', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT_VEC4, prec, 0)]));
+ }
+ }
+
+ // .int
+ /** @type {tcuTestCase.DeqpTest} */ var intGroup = tcuTestCase.newTest('basic.int', 'Integer output tests');
+ testGroup.addChild(intGroup);
+ for (var fmtNdx = 0; fmtNdx < requiredIntFormats.length; fmtNdx++) {
+ var format = requiredIntFormats[fmtNdx];
+ var fmtName = es3fFboTestUtil.getFormatName(format);
+ fboSpec = [];
+
+ fboSpec.push(new es3fFragmentOutputTests.BufferSpec(format, width, height, samples));
+
+ for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
+ prec = precisions[precNdx];
+ precName = gluShaderUtil.getPrecisionName(prec);
+
+ intGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_int', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.INT, prec, 0)]));
+ intGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_ivec2', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.INT_VEC2, prec, 0)]));
+ intGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_ivec3', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.INT_VEC3, prec, 0)]));
+ intGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_ivec4', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.INT_VEC4, prec, 0)]));
+ }
+ }
+
+ // .uint
+ /** @type {tcuTestCase.DeqpTest} */ var uintGroup = tcuTestCase.newTest('basic.uint', 'Usigned integer output tests');
+ testGroup.addChild(uintGroup);
+ for (var fmtNdx = 0; fmtNdx < requiredUintFormats.length; fmtNdx++) {
+ var format = requiredUintFormats[fmtNdx];
+ var fmtName = es3fFboTestUtil.getFormatName(format);
+ fboSpec = [];
+
+ fboSpec.push(new es3fFragmentOutputTests.BufferSpec(format, width, height, samples));
+
+ for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
+ prec = precisions[precNdx];
+ precName = gluShaderUtil.getPrecisionName(prec);
+
+ uintGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_uint', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.UINT, prec, 0)]));
+ uintGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_uvec2', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.UINT_VEC2, prec, 0)]));
+ uintGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_uvec3', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.UINT_VEC3, prec, 0)]));
+ uintGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_uvec4', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.UINT_VEC4, prec, 0)]));
+
+ }
+ }
+
+ // .array
+
+ /** @type {number} */ var numTargets = 3;
+
+ // .float
+ if (gl.getExtension('EXT_color_buffer_float')) {
+ /** @type {tcuTestCase.DeqpTest} */ var arrayFloatGroup = tcuTestCase.newTest('array.float', 'Floating-point output tests');
+ testGroup.addChild(arrayFloatGroup);
+ for (var fmtNdx = 0; fmtNdx < requiredFloatFormats.length; fmtNdx++) {
+ var format = requiredFloatFormats[fmtNdx];
+ var fmtName = es3fFboTestUtil.getFormatName(format);
+ fboSpec = [];
+
+ for (var ndx = 0; ndx < numTargets; ndx++)
+ fboSpec.push(new es3fFragmentOutputTests.BufferSpec(format, width, height, samples));
+
+ for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
+ prec = precisions[precNdx];
+ precName = gluShaderUtil.getPrecisionName(prec);
+
+ arrayFloatGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_float', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT, prec, 0, numTargets)]));
+ arrayFloatGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_vec2', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT_VEC2, prec, 0, numTargets)]));
+ arrayFloatGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_vec3', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT_VEC3, prec, 0, numTargets)]));
+ arrayFloatGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_vec4', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT_VEC4, prec, 0, numTargets)]));
+ }
+ }
+ }
+
+ // .fixed
+ /** @type {tcuTestCase.DeqpTest} */ var arrayFixedGroup = tcuTestCase.newTest('array.fixed', 'Fixed-point output tests');
+ testGroup.addChild(arrayFixedGroup);
+ for (var fmtNdx = 0; fmtNdx < requiredFixedFormats.length; fmtNdx++) {
+ var format = requiredFixedFormats[fmtNdx];
+ var fmtName = es3fFboTestUtil.getFormatName(format);
+ fboSpec = [];
+
+ for (var ndx = 0; ndx < numTargets; ndx++)
+ fboSpec.push(new es3fFragmentOutputTests.BufferSpec(format, width, height, samples));
+
+ for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
+ prec = precisions[precNdx];
+ precName = gluShaderUtil.getPrecisionName(prec);
+
+ arrayFixedGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_float', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT, prec, 0, numTargets)]));
+ arrayFixedGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_vec2', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT_VEC2, prec, 0, numTargets)]));
+ arrayFixedGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_vec3', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT_VEC3, prec, 0, numTargets)]));
+ arrayFixedGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_vec4', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.FLOAT_VEC4, prec, 0, numTargets)]));
+ }
+ }
+
+ // .int
+ /** @type {tcuTestCase.DeqpTest} */ var arrayIntGroup = tcuTestCase.newTest('array.int', 'Integer output tests');
+ testGroup.addChild(arrayIntGroup);
+ for (var fmtNdx = 0; fmtNdx < requiredIntFormats.length; fmtNdx++) {
+ var format = requiredIntFormats[fmtNdx];
+ var fmtName = es3fFboTestUtil.getFormatName(format);
+ fboSpec = [];
+
+ for (var ndx = 0; ndx < numTargets; ndx++)
+ fboSpec.push(new es3fFragmentOutputTests.BufferSpec(format, width, height, samples));
+
+ for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
+ prec = precisions[precNdx];
+ precName = gluShaderUtil.getPrecisionName(prec);
+
+ arrayIntGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_int', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.INT, prec, 0, numTargets)]));
+ arrayIntGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_ivec2', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.INT_VEC2, prec, 0, numTargets)]));
+ arrayIntGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_ivec3', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.INT_VEC3, prec, 0, numTargets)]));
+ arrayIntGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_ivec4', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.INT_VEC4, prec, 0, numTargets)]));
+ }
+ }
+
+ // .uint
+ /** @type {tcuTestCase.DeqpTest} */ var arrayUintGroup = tcuTestCase.newTest('array.uint', 'Usigned integer output tests');
+ testGroup.addChild(arrayUintGroup);
+ for (var fmtNdx = 0; fmtNdx < requiredUintFormats.length; fmtNdx++) {
+ var format = requiredUintFormats[fmtNdx];
+ var fmtName = es3fFboTestUtil.getFormatName(format);
+ fboSpec = [];
+
+ for (var ndx = 0; ndx < numTargets; ndx++)
+ fboSpec.push(new es3fFragmentOutputTests.BufferSpec(format, width, height, samples));
+
+ for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
+ prec = precisions[precNdx];
+ precName = gluShaderUtil.getPrecisionName(prec);
+
+ arrayUintGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_uint', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.UINT, prec, 0, numTargets)]));
+ arrayUintGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_uvec2', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.UINT_VEC2, prec, 0, numTargets)]));
+ arrayUintGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_uvec3', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.UINT_VEC3, prec, 0, numTargets)]));
+ arrayUintGroup.addChild(new es3fFragmentOutputTests.FragmentOutputCase(fmtName + '_' + precName + '_uvec4', '', fboSpec, [new es3fFragmentOutputTests.FragmentOutput(gluShaderUtil.DataType.UINT_VEC4, prec, 0, numTargets)]));
+ }
+ }
+
+ // .random
+
+ /** @type {Array<tcuTestCase.DeqpTest>} */ var randomGroup = [];
+ var numRandomGroups = 3;
+ for (var ii = 0; ii < numRandomGroups; ++ii) {
+ randomGroup[ii] = tcuTestCase.newTest('random', 'Random fragment output cases');
+ testGroup.addChild(randomGroup[ii]);
+ }
+
+ /** @type {boolean} */ var colorBufferFloatSupported = (gl.getExtension('EXT_color_buffer_float') != null);
+ for (var seed = 0; seed < 100; seed++) {
+ var test = es3fFragmentOutputTests.createRandomCase(2, 4, seed, colorBufferFloatSupported);
+ if (test !== null) {
+ randomGroup[seed % numRandomGroups].addChild(test);
+ }
+ }
+
+ };
+
+ /**
+ * Create and execute the test cases
+ */
+ es3fFragmentOutputTests.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var testName = 'fragment_output';
+ var testDescription = 'Fragment Output Tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.testCases = tcuTestCase.newTest(testName, testDescription, null);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ es3fFragmentOutputTests.init(gl);
+ if (range)
+ state.setRange(range);
+ tcuTestCase.runTestCases();
+ } catch (err) {
+ testFailedOptions('Failed to es3fFragmentOutputTests.run tests', false);
+ bufferedLogToConsole(err);
+ tcuTestCase.runner.terminate();
+ }
+
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFramebufferBlitTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFramebufferBlitTests.js
new file mode 100644
index 0000000000..ffc6a0c68c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fFramebufferBlitTests.js
@@ -0,0 +1,1261 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+'use strict';
+goog.provide('functional.gles3.es3fFramebufferBlitTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('framework.opengl.simplereference.sglrGLContext');
+goog.require('framework.opengl.simplereference.sglrReferenceContext');
+goog.require('framework.referencerenderer.rrUtil');
+goog.require('functional.gles3.es3fFboTestCase');
+goog.require('functional.gles3.es3fFboTestUtil');
+
+goog.scope(function() {
+
+ var es3fFramebufferBlitTests = functional.gles3.es3fFramebufferBlitTests;
+ var es3fFboTestCase = functional.gles3.es3fFboTestCase;
+ var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuRGBA = framework.common.tcuRGBA;
+ var tcuImageCompare = framework.common.tcuImageCompare;
+ var tcuTexture = framework.common.tcuTexture;
+ var tcuTextureUtil = framework.common.tcuTextureUtil;
+ var deMath = framework.delibs.debase.deMath;
+ var gluTextureUtil = framework.opengl.gluTextureUtil;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var rrUtil = framework.referencerenderer.rrUtil;
+ var sglrReferenceContext = framework.opengl.simplereference.sglrReferenceContext;
+ var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
+
+ var DE_ASSERT = function(x) {
+ if (!x)
+ throw new Error('Assert failed');
+ };
+
+ /** @type {WebGL2RenderingContext} */ var gl;
+ /**
+ * es3fFramebufferBlitTests.BlitRectCase class, inherits from FboTestCase
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} filter deUint32
+ * @param {Array<number>} srcSize
+ * @param {Array<number>} srcRect
+ * @param {Array<number>} dstSize
+ * @param {Array<number>} dstRect
+ * @param {number=} cellSize
+ */
+ es3fFramebufferBlitTests.BlitRectCase = function(name, desc, filter, srcSize, srcRect, dstSize, dstRect, cellSize) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ /** @const {number} */ this.m_filter = filter;
+ /** @const {Array<number>} */ this.m_srcSize = srcSize;
+ /** @const {Array<number>} */ this.m_srcRect = srcRect;
+ /** @const {Array<number>} */ this.m_dstSize = dstSize;
+ /** @const {Array<number>} */ this.m_dstRect = dstRect;
+ /** @const {number} */ this.m_cellSize = cellSize === undefined ? 8 : cellSize;
+ /** @const {Array<number>} */ this.m_gridCellColorA = [0.2, 0.7, 0.1, 1.0];
+ /** @const {Array<number>} */ this.m_gridCellColorB = [0.7, 0.1, 0.5, 0.8];
+ };
+
+ es3fFramebufferBlitTests.BlitRectCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
+ es3fFramebufferBlitTests.BlitRectCase.prototype.constructor = es3fFramebufferBlitTests.BlitRectCase;
+
+ /**
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFramebufferBlitTests.BlitRectCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ /** @type {number} */ var colorFormat = gl.RGBA8;
+
+ /** @type {es3fFboTestUtil.GradientShader} */
+ var gradShader = new es3fFboTestUtil.GradientShader(
+ gluShaderUtil.DataType.FLOAT_VEC4);
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D],
+ gluShaderUtil.DataType.FLOAT_VEC4);
+
+ var gradShaderID = ctx.createProgram(gradShader);
+ var texShaderID = ctx.createProgram(texShader);
+
+ var srcFbo;
+ var dstFbo;
+ var srcRbo;
+ var dstRbo;
+
+ // Setup shaders
+ gradShader.setGradient(ctx, gradShaderID, [0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]);
+ texShader.setUniforms(ctx, texShaderID);
+
+ // Create framebuffers.
+
+ /** @type {Array<number>} */ var size;
+
+ // source framebuffers
+ srcFbo = ctx.createFramebuffer();
+ srcRbo = ctx.createRenderbuffer();
+ size = this.m_srcSize;
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, srcRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, size[0], size[1]);
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, srcRbo);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ // destination framebuffers
+ dstFbo = ctx.createFramebuffer();
+ dstRbo = ctx.createRenderbuffer();
+ size = this.m_dstSize;
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, dstRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, size[0], size[1]);
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, dstRbo);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ // Fill destination with gradient.
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
+ ctx.viewport(0, 0, this.m_dstSize[0], this.m_dstSize[1]);
+
+ rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ // Fill source with grid pattern.
+ /** @const {number} */ var format = gl.RGBA;
+ /** @const {number} */ var dataType = gl.UNSIGNED_BYTE;
+ /** @const {number} */ var texW = this.m_srcSize[0];
+ /** @const {number} */ var texH = this.m_srcSize[1];
+ var gridTex;
+ /** @type {tcuTexture.TextureLevel} */ var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), texW, texH, 1);
+
+ tcuTextureUtil.fillWithGrid(data.getAccess(), this.m_cellSize, this.m_gridCellColorA, this.m_gridCellColorB);
+
+ gridTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, gridTex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo);
+ ctx.viewport(0, 0, this.m_srcSize[0], this.m_srcSize[1]);
+
+ rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ // Perform copy.
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, srcFbo);
+ ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dstFbo);
+ ctx.blitFramebuffer(this.m_srcRect[0], this.m_srcRect[1], this.m_srcRect[2], this.m_srcRect[3],
+ this.m_dstRect[0], this.m_dstRect[1], this.m_dstRect[2], this.m_dstRect[3],
+ gl.COLOR_BUFFER_BIT, this.m_filter);
+
+ // Read back results.
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, dstFbo);
+
+ this.readPixelsUsingFormat(dst, 0, 0, this.m_dstSize[0], this.m_dstSize[1],
+ gluTextureUtil.mapGLInternalFormat(colorFormat),
+ [1.0, 1.0, 1.0, 1.0],
+ [0.0, 0.0, 0.0, 0.0]);
+ };
+
+ /**
+ * @param {tcuSurface.Surface} reference
+ * @param {tcuSurface.Surface} result
+ * @return {boolean}
+ */
+ es3fFramebufferBlitTests.BlitRectCase.prototype.compare = function(reference, result) {
+ // Use pixel-threshold compare for rect cases since 1px off will mean failure.
+ var threshold = [7, 7, 7, 7];
+ return tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', reference, result, threshold);
+ };
+
+ /**
+ * es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase class
+ * @constructor
+ * @extends {es3fFramebufferBlitTests.BlitRectCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {Array<number>} srcSize
+ * @param {Array<number>} srcRect
+ * @param {Array<number>} dstSize
+ * @param {Array<number>} dstRect
+ */
+ es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase = function(name, desc, srcSize, srcRect, dstSize, dstRect) {
+ es3fFramebufferBlitTests.BlitRectCase.call(this, name, desc, gl.NEAREST, srcSize, srcRect, dstSize, dstRect, 1);
+ };
+
+ es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase.prototype = Object.create(es3fFramebufferBlitTests.BlitRectCase.prototype);
+ es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase.prototype.constructor = es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase;
+
+ /**
+ * @param {tcuSurface.Surface} reference
+ * @param {tcuSurface.Surface} result
+ * @return {boolean}
+ */
+ es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase.prototype.compare = function(reference, result) {
+ assertMsgOptions(result.getWidth() == reference.getWidth() && result.getHeight() == reference.getHeight(),
+ 'Reference and result images have different dimensions', false, true);
+
+ // Image origin must be visible (for baseColor)
+ DE_ASSERT(Math.min(this.m_dstRect[0], this.m_dstRect[2]) >= 0);
+ DE_ASSERT(Math.min(this.m_dstRect[1], this.m_dstRect[3]) >= 0);
+ /** @const {tcuRGBA.RGBA} */ var cellColorA = tcuRGBA.newRGBAFromVec(this.m_gridCellColorA);
+ /** @const {tcuRGBA.RGBA} */ var cellColorB = tcuRGBA.newRGBAFromVec(this.m_gridCellColorB);
+ // TODO: implement
+ // const tcu::RGBA threshold = this.m_context.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(7,7,7,7);
+ /** @type {tcuRGBA.RGBA} */ var threshold = tcuRGBA.newRGBAComponents(7, 7, 7, 7);
+ /** @const {Array<number>} */ //IVec4.xyzw
+ var destinationArea = [
+ deMath.clamp(Math.min(this.m_dstRect[0], this.m_dstRect[2]), 0, result.getWidth()),
+ deMath.clamp(Math.min(this.m_dstRect[1], this.m_dstRect[3]), 0, result.getHeight()),
+ deMath.clamp(Math.max(this.m_dstRect[0], this.m_dstRect[2]), 0, result.getWidth()),
+ deMath.clamp(Math.max(this.m_dstRect[1], this.m_dstRect[3]), 0, result.getHeight())];
+
+ /** @const {tcuRGBA.RGBA} */ var baseColor = new tcuRGBA.RGBA(result.getPixel(destinationArea[0], destinationArea[1]));
+
+ /** @const {boolean} */ var signConfig = tcuRGBA.compareThreshold(baseColor, cellColorA, threshold);
+
+ /** @type {boolean} */ var error = false;
+ /** @type {tcuSurface.Surface} */ var errorMask = new tcuSurface.Surface(result.getWidth(), result.getHeight());
+ /** @type {Array<boolean>} */ var horisontalSign = [];
+ /** @type {Array<boolean>} */ var verticalSign = [];
+
+ errorMask.getAccess().clear([0.0, 1.0, 0.0, 1.0]);
+
+ // Checking only area in our destination rect
+
+ // m_testCtx.getLog()
+ // << tcu::TestLog::Message
+ // << 'Verifying consistency of NEAREST filtering. Verifying rect ' << m_dstRect << '.\n'
+ // << 'Rounding direction of the NEAREST filter at the horisontal texel edge (x = n + 0.5) should not depend on the y-coordinate.\n'
+ // << 'Rounding direction of the NEAREST filter at the vertical texel edge (y = n + 0.5) should not depend on the x-coordinate.\n'
+ // << 'Blitting a grid (with uniform sized cells) should result in a grid (with non-uniform sized cells).'
+ // << tcu::TestLog::EndMessage;
+
+ // Verify that destination only contains valid colors
+
+ /** @type {tcuRGBA.RGBA} */ var color;
+
+ for (var dy = 0; dy < destinationArea[3] - destinationArea[1]; ++dy) {
+ for (var dx = 0; dx < destinationArea[2] - destinationArea[0]; ++dx) {
+ color = new tcuRGBA.RGBA(result.getPixel(destinationArea[0] + dx, destinationArea[1] + dy));
+
+ /** @const {boolean} */
+ var isValidColor =
+ tcuRGBA.compareThreshold(color, cellColorA, threshold) ||
+ tcuRGBA.compareThreshold(color, cellColorB, threshold);
+
+ if (!isValidColor) {
+ errorMask.setPixel(destinationArea[0] + dx, destinationArea[1] + dy, tcuRGBA.RGBA.red.toVec());
+ error = true;
+ }
+ }
+ }
+
+ if (error) {
+ // m_testCtx.getLog()
+ // << tcu::TestLog::Message
+ // << 'Image verification failed, destination rect contains unexpected values. '
+ // << 'Expected either ' << cellColorA << ' or ' << cellColorB << '.'
+ // << tcu::TestLog::EndMessage
+ // << tcu::TestLog::ImageSet('Result', 'Image verification result')
+ // << tcu::TestLog::Image('Result', 'Result', result)
+ // << tcu::TestLog::Image('ErrorMask', 'Error mask', errorMask)
+ // << tcu::TestLog::EndImageSet;
+ return false;
+ }
+
+ // Detect result edges by reading the first row and first column of the blitted area.
+ // Blitting a grid should result in a grid-like image. ('sign changes' should be consistent)
+
+ for (var dx = 0; dx < destinationArea[2] - destinationArea[0]; ++dx) {
+ color = new tcuRGBA.RGBA(result.getPixel(destinationArea[0] + dx, destinationArea[1]));
+ if (tcuRGBA.compareThreshold(color, cellColorA, threshold))
+ horisontalSign[dx] = true;
+ else if (tcuRGBA.compareThreshold(color, cellColorB, threshold))
+ horisontalSign[dx] = false;
+ else
+ DE_ASSERT(false);
+ }
+ for (var dy = 0; dy < destinationArea[3] - destinationArea[1]; ++dy) {
+ color = new tcuRGBA.RGBA(result.getPixel(destinationArea[0], destinationArea[1] + dy));
+
+ if (tcuRGBA.compareThreshold(color, cellColorA, threshold))
+ verticalSign[dy] = true;
+ else if (tcuRGBA.compareThreshold(color, cellColorB, threshold))
+ verticalSign[dy] = false;
+ else
+ DE_ASSERT(false);
+ }
+
+ // Verify grid-like image
+
+ for (var dy = 0; dy < destinationArea[3] - destinationArea[1]; ++dy) {
+ for (var dx = 0; dx < destinationArea[2] - destinationArea[0]; ++dx) {
+ color = new tcuRGBA.RGBA(result.getPixel(destinationArea[0] + dx, destinationArea[1] + dy));
+ /** @const {boolean} */ var resultSign = tcuRGBA.compareThreshold(cellColorA, color, threshold);
+ /** @const {boolean} */ var correctSign = (horisontalSign[dx] == verticalSign[dy]) == signConfig;
+
+ if (resultSign != correctSign) {
+ errorMask.setPixel(destinationArea[0] + dx, destinationArea[1] + dy, tcuRGBA.RGBA.red.toVec());
+ error = true;
+ }
+ }
+ }
+ // Report result
+
+ // if (error)
+ // {
+ // m_testCtx.getLog()
+ // << tcu::TestLog::Message
+ // << 'Image verification failed, nearest filter is not consistent.'
+ // << tcu::TestLog::EndMessage
+ // << tcu::TestLog::ImageSet('Result', 'Image verification result')
+ // << tcu::TestLog::Image('Result', 'Result', result)
+ // << tcu::TestLog::Image('ErrorMask', 'Error mask', errorMask)
+ // << tcu::TestLog::EndImageSet;
+ // }
+ // else
+ // {
+ // m_testCtx.getLog()
+ // << tcu::TestLog::Message
+ // << 'Image verification passed.'
+ // << tcu::TestLog::EndMessage
+ // << tcu::TestLog::ImageSet('Result', 'Image verification result')
+ // << tcu::TestLog::Image('Result', 'Result', result)
+ // << tcu::TestLog::EndImageSet;
+ // }
+
+ return !error;
+ };
+
+ /**
+ * es3fFramebufferBlitTests.FramebufferBlitTests class, inherits from TestCase
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fFramebufferBlitTests.FramebufferBlitTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'blit', 'Framebuffer blit tests');
+ };
+
+ es3fFramebufferBlitTests.FramebufferBlitTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fFramebufferBlitTests.FramebufferBlitTests.prototype.constructor = es3fFramebufferBlitTests.FramebufferBlitTests;
+
+ es3fFramebufferBlitTests.FramebufferBlitTests.prototype.init = function() {
+ /** @const {Array<number>} */ var colorFormats = [
+ // RGBA formats
+ gl.RGBA32I,
+ gl.RGBA32UI,
+ gl.RGBA16I,
+ gl.RGBA16UI,
+ gl.RGBA8,
+ gl.RGBA8I,
+ gl.RGBA8UI,
+ gl.SRGB8_ALPHA8,
+ gl.RGB10_A2,
+ gl.RGB10_A2UI,
+ gl.RGBA4,
+ gl.RGB5_A1,
+
+ // RGB formats
+ gl.RGB8,
+ gl.RGB565,
+
+ // RG formats
+ gl.RG32I,
+ gl.RG32UI,
+ gl.RG16I,
+ gl.RG16UI,
+ gl.RG8,
+ gl.RG8I,
+ gl.RG8UI,
+
+ // R formats
+ gl.R32I,
+ gl.R32UI,
+ gl.R16I,
+ gl.R16UI,
+ gl.R8,
+ gl.R8I,
+ gl.R8UI,
+
+ // gl.EXT_color_buffer_float
+ gl.RGBA32F,
+ gl.RGBA16F,
+ gl.R11F_G11F_B10F,
+ gl.RG32F,
+ gl.RG16F,
+ gl.R32F,
+ gl.R16F
+ ];
+
+ /** @const {Array<number>} */ var depthStencilFormats = [
+ gl.DEPTH_COMPONENT32F,
+ gl.DEPTH_COMPONENT24,
+ gl.DEPTH_COMPONENT16,
+ gl.DEPTH32F_STENCIL8,
+ gl.DEPTH24_STENCIL8,
+ gl.STENCIL_INDEX8
+ ];
+
+ // .rect
+ /** @constructor
+ * @param {string} name
+ * @param {Array<number>} srcRect
+ * @param {Array<number>} dstRect
+ */
+ var CopyRect = function(name, srcRect, dstRect) {
+ /** @const {string} */ this.name = name;
+ /** @type {Array<number>} */ this.srcRect = srcRect;
+ /** @type {Array<number>} */ this.dstRect = dstRect;
+ };
+
+ /** @const {Array<CopyRect>} */ var copyRects = [
+ new CopyRect('basic', [10, 20, 65, 100], [45, 5, 100, 85]),
+ new CopyRect('scale', [10, 20, 65, 100], [25, 30, 125, 94]),
+ new CopyRect('out_of_bounds', [-10, -15, 100, 63], [50, 30, 136, 144])
+ ];
+
+ /** @const {Array<CopyRect>} */ var filterConsistencyRects = [
+
+ new CopyRect('mag', [20, 10, 74, 88], [10, 10, 91, 101]),
+ new CopyRect('min', [10, 20, 78, 100], [20, 20, 71, 80]),
+ new CopyRect('out_of_bounds_mag', [21, 10, 73, 82], [11, 43, 141, 151]),
+ new CopyRect('out_of_bounds_min', [11, 21, 77, 97], [80, 82, 135, 139])
+ ];
+
+ /** @constructor
+ * @param {?string} name
+ * @param {Array<number>} srcSwizzle
+ * @param {Array<number>} dstSwizzle
+ */
+ var Swizzle = function(name, srcSwizzle, dstSwizzle) {
+ /** @const {?string} */ this.name = name;
+ /** @type {Array<number>} */ this.srcSwizzle = srcSwizzle;
+ /** @type {Array<number>} */ this.dstSwizzle = dstSwizzle;
+ };
+
+ /** @const {Array<Swizzle>} */ var swizzles = [
+ new Swizzle(null, [0, 1, 2, 3], [0, 1, 2, 3]),
+ new Swizzle('reverse_src_x', [2, 1, 0, 3], [0, 1, 2, 3]),
+ new Swizzle('reverse_src_y', [0, 3, 2, 1], [0, 1, 2, 3]),
+ new Swizzle('reverse_dst_x', [0, 1, 2, 3], [2, 1, 0, 3]),
+ new Swizzle('reverse_dst_y', [0, 1, 2, 3], [0, 3, 2, 1]),
+ new Swizzle('reverse_src_dst_x', [2, 1, 0, 3], [2, 1, 0, 3]),
+ new Swizzle('reverse_src_dst_y', [0, 3, 2, 1], [0, 3, 2, 1])
+ ];
+
+ /** @const {Array<number>} */ var srcSize = [127, 119];
+ /** @const {Array<number>} */ var dstSize = [132, 128];
+
+ // Blit rectangle tests.
+ for (var rectNdx = 0; rectNdx < copyRects.length; rectNdx++) {
+ /** @type {tcuTestCase.DeqpTest} */ var rectGroup = tcuTestCase.newTest('rect', 'Blit rectangle tests');
+ this.addChild(rectGroup);
+
+ for (var swzNdx = 0; swzNdx < swizzles.length; swzNdx++) {
+ /** @type {string} */ var name = copyRects[rectNdx].name + (swizzles[swzNdx].name ? ('_' + swizzles[swzNdx].name) : '');
+ /** @type {Array<number>} */ var srcSwz = swizzles[swzNdx].srcSwizzle;
+ /** @type {Array<number>} */ var dstSwz = swizzles[swzNdx].dstSwizzle;
+ /** @type {Array<number>} */ var srcRect = deMath.swizzle(copyRects[rectNdx].srcRect, srcSwz);
+ /** @type {Array<number>} */ var dstRect = deMath.swizzle(copyRects[rectNdx].dstRect, dstSwz);
+
+ rectGroup.addChild(new es3fFramebufferBlitTests.BlitRectCase((name + '_nearest'), '', gl.NEAREST, srcSize, srcRect, dstSize, dstRect));
+ rectGroup.addChild(new es3fFramebufferBlitTests.BlitRectCase((name + '_linear'), '', gl.LINEAR, srcSize, srcRect, dstSize, dstRect));
+ }
+ }
+
+ // Nearest filter tests
+ for (var rectNdx = 0; rectNdx < filterConsistencyRects.length; rectNdx++) {
+ /** @type {tcuTestCase.DeqpTest} */ var rectGroup = tcuTestCase.newTest('rect', 'Blit rectangle tests');
+ this.addChild(rectGroup);
+ for (var swzNdx = 0; swzNdx < swizzles.length; swzNdx++) {
+ var name = 'nearest_consistency_' + filterConsistencyRects[rectNdx].name + (swizzles[swzNdx].name ? ('_' + swizzles[swzNdx].name) : '');
+ var srcSwz = swizzles[swzNdx].srcSwizzle;
+ var dstSwz = swizzles[swzNdx].dstSwizzle;
+ var srcRect = deMath.swizzle(filterConsistencyRects[rectNdx].srcRect, srcSwz);
+ var dstRect = deMath.swizzle(filterConsistencyRects[rectNdx].dstRect, dstSwz);
+
+ rectGroup.addChild(new es3fFramebufferBlitTests.BlitNearestFilterConsistencyCase(name, 'Test consistency of the nearest filter', srcSize, srcRect, dstSize, dstRect));
+ }
+ }
+
+ // .conversion
+ for (var srcFmtNdx = 0; srcFmtNdx < colorFormats.length; srcFmtNdx++) {
+ /** @type {tcuTestCase.DeqpTest} */ var conversionGroup = tcuTestCase.newTest('conversion', 'Color conversion tests');
+ this.addChild(conversionGroup);
+ for (var dstFmtNdx = 0; dstFmtNdx < colorFormats.length; dstFmtNdx++) {
+ /** @type {number} */ var srcFormat = colorFormats[srcFmtNdx];
+ /** @type {tcuTexture.TextureFormat} */ var srcTexFmt = gluTextureUtil.mapGLInternalFormat(srcFormat);
+ /** @type {tcuTexture.TextureChannelClass} */ var srcType = tcuTexture.getTextureChannelClass(srcTexFmt.type);
+ /** @type {number} */ var dstFormat = colorFormats[dstFmtNdx];
+ /** @type {tcuTexture.TextureFormat} */ var dstTexFmt = gluTextureUtil.mapGLInternalFormat(dstFormat);
+ /** @type {tcuTexture.TextureChannelClass} */ var dstType = tcuTexture.getTextureChannelClass(dstTexFmt.type);
+
+ if (((srcType == tcuTexture.TextureChannelClass.FLOATING_POINT || srcType == tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT) !=
+ (dstType == tcuTexture.TextureChannelClass.FLOATING_POINT || dstType == tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT)) ||
+ ((srcType == tcuTexture.TextureChannelClass.SIGNED_INTEGER) != (dstType == tcuTexture.TextureChannelClass.SIGNED_INTEGER)) ||
+ ((srcType == tcuTexture.TextureChannelClass.UNSIGNED_INTEGER) != (dstType == tcuTexture.TextureChannelClass.UNSIGNED_INTEGER)))
+ continue; // Conversion not supported.
+
+ var name = es3fFboTestUtil.getFormatName(srcFormat) + '_to_' + es3fFboTestUtil.getFormatName(dstFormat);
+
+ conversionGroup.addChild(new es3fFramebufferBlitTests.BlitColorConversionCase(name, '', srcFormat, dstFormat, [127, 113]));
+ }
+ }
+
+ // .depth_stencil
+ /** @type {tcuTestCase.DeqpTest} */ var depthStencilGroup = tcuTestCase.newTest('depth_stencil', 'Depth and stencil blits');
+ this.addChild(depthStencilGroup);
+
+ for (var fmtNdx = 0; fmtNdx < depthStencilFormats.length; fmtNdx++) {
+ /** @type {number} */ var format = depthStencilFormats[fmtNdx];
+ /** @type {tcuTexture.TextureFormat} */ var texFmt = gluTextureUtil.mapGLInternalFormat(format);
+ /** @type {string} */ var fmtName = es3fFboTestUtil.getFormatName(format);
+ /** @type {boolean} */ var depth = texFmt.order == tcuTexture.ChannelOrder.D || texFmt.order == tcuTexture.ChannelOrder.DS;
+ /** @type {boolean} */ var stencil = texFmt.order == tcuTexture.ChannelOrder.S || texFmt.order == tcuTexture.ChannelOrder.DS;
+ /** @type {number} */ var buffers = (depth ? gl.DEPTH_BUFFER_BIT : 0) | (stencil ? gl.STENCIL_BUFFER_BIT : 0);
+
+ depthStencilGroup.addChild(new es3fFramebufferBlitTests.BlitDepthStencilCase((fmtName + '_basic'), '', format, buffers, [128, 128], [0, 0, 128, 128], buffers, [128, 128], [0, 0, 128, 128], buffers));
+ depthStencilGroup.addChild(new es3fFramebufferBlitTests.BlitDepthStencilCase((fmtName + '_scale'), '', format, buffers, [127, 119], [10, 30, 100, 70], buffers, [111, 130], [20, 5, 80, 130], buffers));
+
+ if (depth && stencil) {
+ depthStencilGroup.addChild(new es3fFramebufferBlitTests.BlitDepthStencilCase((fmtName + '_depth_only'), '', format, buffers, [128, 128], [0, 0, 128, 128], buffers, [128, 128], [0, 0, 128, 128], gl.DEPTH_BUFFER_BIT));
+ depthStencilGroup.addChild(new es3fFramebufferBlitTests.BlitDepthStencilCase((fmtName + '_stencil_only'), '', format, buffers, [128, 128], [0, 0, 128, 128], buffers, [128, 128], [0, 0, 128, 128], gl.STENCIL_BUFFER_BIT));
+ }
+ }
+
+ // .default_framebuffer
+ /**
+ * @constructor
+ * @param {string} name
+ * @param {es3fFramebufferBlitTests.BlitArea} area
+ */
+ var Area = function(name, area) {
+ /** @type {string} name */ this.name = name;
+ /** @type {es3fFramebufferBlitTests.BlitArea} area */ this.area = area;
+ };
+
+ /** @type {Array<Area>} */ var areas = [
+ new Area('scale', es3fFramebufferBlitTests.BlitArea.AREA_SCALE),
+ new Area('out_of_bounds', es3fFramebufferBlitTests.BlitArea.AREA_OUT_OF_BOUNDS)
+ ];
+
+ var numDefaultFbSubGroups = 7;
+ /** @type {Array<tcuTestCase.DeqpTest>} */ var defaultFbGroup = [];
+ for (var ii = 0; ii < numDefaultFbSubGroups; ++ii) {
+ defaultFbGroup[ii] = tcuTestCase.newTest('default_framebuffer', 'Blits with default framebuffer');
+ this.addChild(defaultFbGroup[ii]);
+ }
+ for (var fmtNdx = 0; fmtNdx < colorFormats.length; fmtNdx++) {
+ var format = colorFormats[fmtNdx];
+ var texFmt = gluTextureUtil.mapGLInternalFormat(format);
+ var fmtClass = tcuTexture.getTextureChannelClass(texFmt.type);
+ var filter = gluTextureUtil.isGLInternalColorFormatFilterable(format) ? gl.LINEAR : gl.NEAREST;
+ var filterable = gluTextureUtil.isGLInternalColorFormatFilterable(format);
+
+ if (fmtClass != tcuTexture.TextureChannelClass.FLOATING_POINT &&
+ fmtClass != tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT &&
+ fmtClass != tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT)
+ continue; // Conversion not supported.
+
+ defaultFbGroup[fmtNdx % numDefaultFbSubGroups].addChild(new es3fFramebufferBlitTests.BlitDefaultFramebufferCase(es3fFboTestUtil.getFormatName(format), '', format, filter));
+
+ for (var areaNdx = 0; areaNdx < areas.length; areaNdx++) {
+ var name = areas[areaNdx].name;
+ var addLinear = filterable;
+ var addNearest = !addLinear || (areas[areaNdx].area != es3fFramebufferBlitTests.BlitArea.AREA_OUT_OF_BOUNDS); // No need to check out-of-bounds with different filtering
+
+ if (addNearest) {
+
+ defaultFbGroup[fmtNdx % numDefaultFbSubGroups].addChild(new es3fFramebufferBlitTests.DefaultFramebufferBlitCase((es3fFboTestUtil.getFormatName(format) + '_nearest_' + name + '_blit_from_default'), '', format, gl.NEAREST, es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET, areas[areaNdx].area));
+ defaultFbGroup[fmtNdx % numDefaultFbSubGroups].addChild(new es3fFramebufferBlitTests.DefaultFramebufferBlitCase((es3fFboTestUtil.getFormatName(format) + '_nearest_' + name + '_blit_to_default'), '', format, gl.NEAREST, es3fFramebufferBlitTests.BlitDirection.BLIT_TO_DEFAULT_FROM_TARGET, areas[areaNdx].area));
+ }
+
+ if (addLinear) {
+ defaultFbGroup[fmtNdx % numDefaultFbSubGroups].addChild(new es3fFramebufferBlitTests.DefaultFramebufferBlitCase((es3fFboTestUtil.getFormatName(format) + '_linear_' + name + '_blit_from_default'), '', format, gl.LINEAR, es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET, areas[areaNdx].area));
+ defaultFbGroup[fmtNdx % numDefaultFbSubGroups].addChild(new es3fFramebufferBlitTests.DefaultFramebufferBlitCase((es3fFboTestUtil.getFormatName(format) + '_linear_' + name + '_blit_to_default'), '', format, gl.LINEAR, es3fFramebufferBlitTests.BlitDirection.BLIT_TO_DEFAULT_FROM_TARGET, areas[areaNdx].area));
+ }
+ }
+ }
+ };
+
+ /**
+ * @param {?tcuTexture.ChannelOrder} order
+ * @return {Array<boolean>}
+ */
+ es3fFramebufferBlitTests.getChannelMask = function(order) {
+ switch (order) {
+ case tcuTexture.ChannelOrder.R: return [true, false, false, false];
+ case tcuTexture.ChannelOrder.RG: return [true, true, false, false];
+ case tcuTexture.ChannelOrder.RGB: return [true, true, true, false];
+ case tcuTexture.ChannelOrder.RGBA: return [true, true, true, true];
+ case tcuTexture.ChannelOrder.sRGB: return [true, true, true, false];
+ case tcuTexture.ChannelOrder.sRGBA: return [true, true, true, true];
+ default:
+ DE_ASSERT(false);
+ return [false, false, false, false];
+ }
+ };
+
+ /**
+ * es3fFramebufferBlitTests.BlitColorConversionCase class, inherits from FboTestCase
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} srcFormat
+ * @param {number} dstFormat
+ * @param {Array<number>} size
+ */
+ es3fFramebufferBlitTests.BlitColorConversionCase = function(name, desc, srcFormat, dstFormat, size) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ /** @type {number} */ this.m_srcFormat = srcFormat;
+ /** @type {number} */ this.m_dstFormat = dstFormat;
+ /** @type {Array<number>} */ this.m_size = size;
+ };
+
+ es3fFramebufferBlitTests.BlitColorConversionCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
+ es3fFramebufferBlitTests.BlitColorConversionCase.prototype.constructor = es3fFramebufferBlitTests.BlitColorConversionCase;
+
+ es3fFramebufferBlitTests.BlitColorConversionCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_srcFormat);
+ this.checkFormatSupport(this.m_dstFormat);
+ return true; // No exception thrown
+ };
+
+ /**
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFramebufferBlitTests.BlitColorConversionCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ /** @type {tcuTexture.TextureFormat} */ var srcFormat = gluTextureUtil.mapGLInternalFormat(this.m_srcFormat);
+ /** @type {tcuTexture.TextureFormat} */ var dstFormat = gluTextureUtil.mapGLInternalFormat(this.m_dstFormat);
+
+ /** @type {gluShaderUtil.DataType} */ var srcOutputType = es3fFboTestUtil.getFragmentOutputType(srcFormat);
+ /** @type {gluShaderUtil.DataType} */ var dstOutputType = es3fFboTestUtil.getFragmentOutputType(dstFormat);
+
+ // Compute ranges \note Doesn't handle case where src or dest is not subset of the another!
+ /** @type {tcuTextureUtil.TextureFormatInfo} */ var srcFmtRangeInfo = tcuTextureUtil.getTextureFormatInfo(srcFormat);
+ /** @type {tcuTextureUtil.TextureFormatInfo} */ var dstFmtRangeInfo = tcuTextureUtil.getTextureFormatInfo(dstFormat);
+
+ /** @type {Array<boolean>} */ var copyMask = deMath.logicalAndBool(es3fFramebufferBlitTests.getChannelMask(srcFormat.order), es3fFramebufferBlitTests.getChannelMask(dstFormat.order));
+ /** @type {Array<boolean>} */ var srcIsGreater = deMath.greaterThan(deMath.subtract(srcFmtRangeInfo.valueMax, srcFmtRangeInfo.valueMin), deMath.subtract(dstFmtRangeInfo.valueMax, dstFmtRangeInfo.valueMin));
+
+ /** @type {tcuTextureUtil.TextureFormatInfo} */ var srcRangeInfo = new tcuTextureUtil.TextureFormatInfo(
+ tcuTextureUtil.select(dstFmtRangeInfo.valueMin, srcFmtRangeInfo.valueMin, deMath.logicalAndBool(copyMask, srcIsGreater)),
+ tcuTextureUtil.select(dstFmtRangeInfo.valueMax, srcFmtRangeInfo.valueMax, deMath.logicalAndBool(copyMask, srcIsGreater)),
+ tcuTextureUtil.select(dstFmtRangeInfo.lookupScale, srcFmtRangeInfo.lookupScale, deMath.logicalAndBool(copyMask, srcIsGreater)),
+ tcuTextureUtil.select(dstFmtRangeInfo.lookupBias, srcFmtRangeInfo.lookupBias, deMath.logicalAndBool(copyMask, srcIsGreater)));
+ /** @type {tcuTextureUtil.TextureFormatInfo} */ var dstRangeInfo = new tcuTextureUtil.TextureFormatInfo(
+ tcuTextureUtil.select(dstFmtRangeInfo.valueMin, srcFmtRangeInfo.valueMin, deMath.logicalOrBool(deMath.logicalNotBool(copyMask), srcIsGreater)),
+ tcuTextureUtil.select(dstFmtRangeInfo.valueMax, srcFmtRangeInfo.valueMax, deMath.logicalOrBool(deMath.logicalNotBool(copyMask), srcIsGreater)),
+ tcuTextureUtil.select(dstFmtRangeInfo.lookupScale, srcFmtRangeInfo.lookupScale, deMath.logicalOrBool(deMath.logicalNotBool(copyMask), srcIsGreater)),
+ tcuTextureUtil.select(dstFmtRangeInfo.lookupBias, srcFmtRangeInfo.lookupBias, deMath.logicalOrBool(deMath.logicalNotBool(copyMask), srcIsGreater)));
+
+ // Shaders.
+ /** @type {es3fFboTestUtil.GradientShader} */
+ var gradientToSrcShader = new es3fFboTestUtil.GradientShader(srcOutputType);
+ /** @type {es3fFboTestUtil.GradientShader} */
+ var gradientToDstShader = new es3fFboTestUtil.GradientShader(dstOutputType);
+
+ var gradShaderSrcID = ctx.createProgram(gradientToSrcShader);
+ var gradShaderDstID = ctx.createProgram(gradientToDstShader);
+
+ var srcFbo;
+ var dstFbo;
+ var srcRbo;
+ var dstRbo;
+
+ // Create framebuffers.
+ // Source framebuffers
+ srcFbo = ctx.createFramebuffer();
+ srcRbo = ctx.createRenderbuffer();
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, srcRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_srcFormat, this.m_size[0], this.m_size[1]);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, srcRbo);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ // Destination framebuffers
+ dstFbo = ctx.createFramebuffer();
+ dstRbo = ctx.createRenderbuffer();
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, dstRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_dstFormat, this.m_size[0], this.m_size[1]);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, dstRbo);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ ctx.viewport(0, 0, this.m_size[0], this.m_size[1]);
+
+ // Render gradients.
+ for (var ndx = 0; ndx < 2; ndx++) {
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, ndx ? dstFbo : srcFbo);
+ if (ndx) {
+ gradientToDstShader.setGradient(ctx, gradShaderDstID, dstRangeInfo.valueMax, dstRangeInfo.valueMin);
+ rrUtil.drawQuad(ctx, gradShaderDstID, [-1, -1, 0], [1, 1, 0]);
+ } else {
+ gradientToSrcShader.setGradient(ctx, gradShaderSrcID, srcRangeInfo.valueMin, srcRangeInfo.valueMax);
+ rrUtil.drawQuad(ctx, gradShaderSrcID, [-1, -1, 0], [1, 1, 0]);
+ }
+ }
+
+ // Execute copy.
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, srcFbo);
+ ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dstFbo);
+ ctx.blitFramebuffer(0, 0, this.m_size[0], this.m_size[1], 0, 0, this.m_size[0], this.m_size[1], gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ this.checkError();
+
+ // Read results.
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, dstFbo);
+ this.readPixelsUsingFormat(dst, 0, 0, this.m_size[0], this.m_size[1], dstFormat, dstRangeInfo.lookupScale, dstRangeInfo.lookupBias);
+
+ };
+
+ /**
+ * @param {tcuSurface.Surface} reference
+ * @param {tcuSurface.Surface} result
+ */
+ es3fFramebufferBlitTests.BlitColorConversionCase.prototype.compare = function(reference, result) {
+ /** @const {tcuTexture.TextureFormat} */ var srcFormat = gluTextureUtil.mapGLInternalFormat(this.m_srcFormat);
+ /** @const {tcuTexture.TextureFormat} */ var dstFormat = gluTextureUtil.mapGLInternalFormat(this.m_dstFormat);
+ /** @const {boolean} */ var srcIsSRGB = (srcFormat.order == tcuTexture.ChannelOrder.sRGBA);
+ /** @const {boolean} */ var dstIsSRGB = (dstFormat.order == tcuTexture.ChannelOrder.sRGBA);
+ /** @type {tcuRGBA.RGBA} */ var threshold = new tcuRGBA.RGBA();
+
+ if (dstIsSRGB)
+ threshold = es3fFboTestUtil.getToSRGBConversionThreshold(srcFormat, dstFormat);
+ else {
+ /** @type {tcuRGBA.RGBA} */ var srcMaxDiff = es3fFboTestUtil.getThresholdFromTextureFormat(srcFormat);
+ /** @type {tcuRGBA.RGBA} */ var dstMaxDiff = es3fFboTestUtil.getThresholdFromTextureFormat(dstFormat);
+ if (srcIsSRGB)
+ srcMaxDiff = tcuRGBA.multiply(srcMaxDiff, 2);
+
+ threshold = tcuRGBA.max(srcMaxDiff, dstMaxDiff);
+ }
+
+ // m_testCtx.getLog() << tcu::TestLog::Message << 'threshold = ' << threshold << tcu::TestLog::EndMessage;
+ return tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', reference, result, threshold.toIVec());
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format deUint32
+ * @param {number} srcBuffers deUint32
+ * @param {Array<number>} srcSize IVec2
+ * @param {Array<number>} srcRect IVec4
+ * @param {number} dstBuffers deUint32
+ * @param {Array<number>} dstSize IVec2
+ * @param {Array<number>} dstRect IVec4
+ * @param {number} copyBuffers deUint32
+ */
+ es3fFramebufferBlitTests.BlitDepthStencilCase = function(name, desc, format, srcBuffers, srcSize, srcRect, dstBuffers, dstSize, dstRect, copyBuffers) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ /** @type {number} */ this.m_format = format;
+ /** @type {number} */ this.m_srcBuffers = srcBuffers;
+ /** @type {Array<number>} */ this.m_srcSize = srcSize;
+ /** @type {Array<number>} */ this.m_srcRect = srcRect;
+ /** @type {number} */ this.m_dstBuffers = dstBuffers;
+ /** @type {Array<number>} */ this.m_dstSize = dstSize;
+ /** @type {Array<number>} */ this.m_dstRect = dstRect;
+ /** @type {number} */ this.m_copyBuffers = copyBuffers;
+ };
+
+ es3fFramebufferBlitTests.BlitDepthStencilCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
+ es3fFramebufferBlitTests.BlitDepthStencilCase.prototype.constructor = es3fFramebufferBlitTests.BlitDepthStencilCase;
+
+ /**
+ * @protected
+ */
+ es3fFramebufferBlitTests.BlitDepthStencilCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_format);
+ return true; // No exception thrown
+ };
+
+ /**
+ * @protected
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFramebufferBlitTests.BlitDepthStencilCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ /** @const {number} */ var colorFormat = gl.RGBA8;
+ var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ var texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D] ,
+ gluShaderUtil.DataType.FLOAT_VEC4);
+ var flatShader = new es3fFboTestUtil.FlatColorShader(gluShaderUtil.DataType.FLOAT_VEC4);
+
+ var flatShaderID = ctx.createProgram(flatShader);
+ var texShaderID = ctx.createProgram(texShader);
+ var gradShaderID = ctx.createProgram(gradShader);
+
+ var srcFbo;
+ var dstFbo;
+ var srcColorRbo;
+ var dstColorRbo;
+ var srcDepthStencilRbo;
+ var dstDepthStencilRbo;
+
+ // setup shaders
+ gradShader.setGradient(ctx, gradShaderID, [0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]);
+ texShader.setUniforms(ctx, texShaderID);
+
+ // Create framebuffers
+ // Source framebuffers
+ srcFbo = ctx.createFramebuffer();
+ srcColorRbo = ctx.createRenderbuffer();
+ srcDepthStencilRbo = ctx.createRenderbuffer();
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, srcColorRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.m_srcSize[0], this.m_srcSize[1]);
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, srcDepthStencilRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_format, this.m_srcSize[0], this.m_srcSize[1]);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, srcColorRbo);
+
+ if (this.m_srcBuffers & gl.DEPTH_BUFFER_BIT)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, srcDepthStencilRbo);
+ if (this.m_srcBuffers & gl.STENCIL_BUFFER_BIT)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, srcDepthStencilRbo);
+
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ // Clear depth to 1 and stencil to 0.
+ ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0);
+
+ // Destination framebuffers
+ dstFbo = ctx.createFramebuffer();
+ dstColorRbo = ctx.createRenderbuffer();
+ dstDepthStencilRbo = ctx.createRenderbuffer();
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, dstColorRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, colorFormat, this.m_dstSize[0], this.m_dstSize[1]);
+
+ ctx.bindRenderbuffer(gl.RENDERBUFFER, dstDepthStencilRbo);
+ ctx.renderbufferStorage(gl.RENDERBUFFER, this.m_format, this.m_dstSize[0], this.m_dstSize[1]);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, dstColorRbo);
+
+ if (this.m_dstBuffers & gl.DEPTH_BUFFER_BIT)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, dstDepthStencilRbo);
+ if (this.m_dstBuffers & gl.STENCIL_BUFFER_BIT)
+ ctx.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, dstDepthStencilRbo);
+
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ // Clear depth to 1 and stencil to 0.
+ ctx.clearBufferfi(gl.DEPTH_STENCIL, 0, 1.0, 0);
+
+ // Fill source with gradient, depth = [-1..1], stencil = 7
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, srcFbo);
+ ctx.viewport(0, 0, this.m_srcSize[0], this.m_srcSize[1]);
+ ctx.enable(gl.DEPTH_TEST);
+ ctx.enable(gl.STENCIL_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
+ ctx.stencilFunc(gl.ALWAYS, 7, 0xff);
+
+ rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, -1], [1, 1, 1]);
+
+ // Fill destination with grid pattern, depth = 0 and stencil = 1
+ /** @const {number} */ var format = gl.RGBA;
+ /** @const {number} */ var dataType = gl.UNSIGNED_BYTE;
+ /** @const {number} */ var texW = this.m_srcSize[0];
+ /** @const {number} */ var texH = this.m_srcSize[1];
+ /** @type {WebGLTexture|sglrReferenceContext.TextureContainer} */ var gridTex = null;
+ /** @type {tcuTexture.TextureLevel} */ var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), texW, texH, 1);
+
+ tcuTextureUtil.fillWithGrid(data.getAccess(), 8, [0.2, 0.7, 0.1, 1.0], [0.7, 0.1, 0.5, 0.8]);
+
+ gridTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, gridTex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, format, texW, texH, 0, format, dataType, data.getAccess().getDataPtr());
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
+ ctx.viewport(0, 0, this.m_dstSize[0], this.m_dstSize[1]);
+ ctx.stencilFunc(gl.ALWAYS, 1, 0xff);
+
+ rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ // Perform copy.
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, srcFbo);
+ ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, dstFbo);
+ ctx.blitFramebuffer(this.m_srcRect[0], this.m_srcRect[1], this.m_srcRect[2], this.m_srcRect[3], this.m_dstRect[0], this.m_dstRect[1], this.m_dstRect[2], this.m_dstRect[3], this.m_copyBuffers, gl.NEAREST);
+
+ // Render blue color where depth < 0, decrement on depth failure.
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, dstFbo);
+ ctx.viewport(0, 0, this.m_dstSize[0], this.m_dstSize[1]);
+ ctx.stencilOp(gl.KEEP, gl.DECR, gl.KEEP);
+ ctx.stencilFunc(gl.ALWAYS, 0, 0xff);
+
+ flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 0.0, 1.0, 1.0]);
+
+ rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ if (this.m_dstBuffers & gl.STENCIL_BUFFER_BIT) {
+ // Render green color where stencil == 6.
+ ctx.disable(gl.DEPTH_TEST);
+ ctx.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
+ ctx.stencilFunc(gl.EQUAL, 6, 0xff);
+
+ flatShader.setColor(this.getCurrentContext(), flatShaderID, [0.0, 1.0, 0.0, 1.0]);
+
+ rrUtil.drawQuad(ctx, flatShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ }
+ this.readPixelsUsingFormat(dst, 0, 0, this.m_dstSize[0], this.m_dstSize[1], gluTextureUtil.mapGLInternalFormat(colorFormat), [1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]);
+
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fFboTestCase.FboTestCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} filter
+ */
+ es3fFramebufferBlitTests.BlitDefaultFramebufferCase = function(name, desc, format, filter) {
+ es3fFboTestCase.FboTestCase.call(this, name, desc);
+ /** @const {number} */ this.m_format = format;
+ /** @const {number} */ this.m_filter = filter;
+ };
+
+ es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype = Object.create(es3fFboTestCase.FboTestCase.prototype);
+ es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype.constructor = es3fFramebufferBlitTests.BlitDefaultFramebufferCase;
+
+ /**
+ * @protected
+ */
+ es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype.preCheck = function() {
+ this.checkFormatSupport(this.m_format);
+ return true; // No exception thrown
+ };
+
+ /**
+ * @protected
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype.render = function(dst) {
+ var ctx = this.getCurrentContext();
+ /** @type {tcuTexture.TextureFormat} */ var colorFormat = gluTextureUtil.mapGLInternalFormat(this.m_format);
+ /** @type {gluTextureUtil.TransferFormat} */ var transferFmt = gluTextureUtil.getTransferFormat(colorFormat);
+
+ /** @type {es3fFboTestUtil.GradientShader} */ var gradShader = new es3fFboTestUtil.GradientShader(gluShaderUtil.DataType.FLOAT_VEC4);
+ /** @type {es3fFboTestUtil.Texture2DShader} */ var texShader = new es3fFboTestUtil.Texture2DShader([gluTextureUtil.getSampler2DType(colorFormat)], gluShaderUtil.DataType.FLOAT_VEC4);
+
+ var gradShaderID = ctx.createProgram(gradShader);
+ var texShaderID = ctx.createProgram(texShader);
+ var fbo;
+ var tex;
+ /** @const {number} */ var texW = 128;
+ /** @const {number} */ var texH = 128;
+
+ // Setup shaders
+ gradShader.setGradient(ctx, gradShaderID, [0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0]);
+ texShader.setUniforms(ctx, texShaderID);
+
+ // FBO
+ fbo = ctx.createFramebuffer();
+ tex = ctx.createTexture();
+
+ ctx.bindTexture(gl.TEXTURE_2D, tex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.m_filter);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.m_filter);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_format, texW, texH, 0, transferFmt.format, transferFmt.dataType, null);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ // Render gradient to screen.
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ rrUtil.drawQuad(ctx, gradShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ // Blit gradient from screen to fbo.
+ ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo);
+ ctx.blitFramebuffer(0, 0, ctx.getWidth(), ctx.getHeight(), 0, 0, texW, texH, gl.COLOR_BUFFER_BIT, this.m_filter);
+
+ // Fill left half of viewport with quad that uses texture.
+ ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
+ ctx.clearBufferfv(gl.COLOR, 0, [1.0, 0.0, 0.0, 1.0]);
+
+ rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ // Blit fbo to right half.
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo);
+ ctx.blitFramebuffer(0, 0, texW, texH, Math.floor(ctx.getWidth() / 2), 0, ctx.getWidth(), ctx.getHeight(), gl.COLOR_BUFFER_BIT, this.m_filter);
+
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
+ this.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight());
+
+ };
+
+ /**
+ * @protected
+ * @param {tcuSurface.Surface} reference
+ * @param {tcuSurface.Surface} result
+ */
+ es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype.compare = function(reference, result) {
+ /** @const {tcuRGBA.RGBA} */
+ var threshold = tcuRGBA.max(es3fFboTestUtil.getFormatThreshold(this.m_format), tcuRGBA.newRGBAComponents(12, 12, 12, 12));
+
+ //m_testCtx.getLog() << TestLog::Message << 'Comparing images, threshold: ' << threshold << TestLog::EndMessage;
+
+ return tcuImageCompare.bilinearCompare('Result', 'Image comparison result', reference.getAccess(), result.getAccess(), threshold);
+ };
+
+ /** @enum */
+ es3fFramebufferBlitTests.BlitDirection = {
+ BLIT_DEFAULT_TO_TARGET: 0,
+ BLIT_TO_DEFAULT_FROM_TARGET: 1
+ };
+
+ /** @enum */
+ es3fFramebufferBlitTests.BlitArea = {
+ AREA_SCALE: 0,
+ AREA_OUT_OF_BOUNDS: 1
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fFramebufferBlitTests.BlitDefaultFramebufferCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} filter
+ * @param {es3fFramebufferBlitTests.BlitDirection} dir
+ * @param {es3fFramebufferBlitTests.BlitArea} area
+ */
+ es3fFramebufferBlitTests.DefaultFramebufferBlitCase = function(name, desc, format, filter, dir, area) {
+ es3fFramebufferBlitTests.BlitDefaultFramebufferCase.call(this, name, desc, format, filter);
+ /** @const {es3fFramebufferBlitTests.BlitDirection} */ this.m_blitDir = dir;
+ /** @const {es3fFramebufferBlitTests.BlitArea} */ this.m_blitArea = area;
+ /** @type {Array<number>} */ this.m_srcRect = [-1, -1, -1, -1];
+ /** @type {Array<number>} */ this.m_dstRect = [-1, -1, -1, -1];
+ /** @type {Array<number>} */ this.m_interestingArea = [-1, -1, -1, -1];
+ };
+
+ es3fFramebufferBlitTests.DefaultFramebufferBlitCase.prototype = Object.create(es3fFramebufferBlitTests.BlitDefaultFramebufferCase.prototype);
+ es3fFramebufferBlitTests.DefaultFramebufferBlitCase.prototype.constructor = es3fFramebufferBlitTests.DefaultFramebufferBlitCase;
+
+ es3fFramebufferBlitTests.DefaultFramebufferBlitCase.prototype.init = function() {
+ // requirements
+ /** @const {number} */ var minViewportSize = 128;
+ if (gl.drawingBufferWidth < minViewportSize ||
+ gl.drawingBufferHeight < minViewportSize)
+ throw new Error('Viewport size ' + minViewportSize + 'x' + minViewportSize + ' required');
+
+ // prevent viewport randoming
+ this.m_viewportWidth = gl.drawingBufferWidth;
+ this.m_viewportHeight = gl.drawingBufferHeight;
+
+ // set proper areas
+ if (this.m_blitArea == es3fFramebufferBlitTests.BlitArea.AREA_SCALE) {
+ this.m_srcRect = [10, 20, 65, 100];
+ this.m_dstRect = [25, 30, 125, 94];
+ this.m_interestingArea = [0, 0, 128, 128];
+ } else if (this.m_blitArea == es3fFramebufferBlitTests.BlitArea.AREA_OUT_OF_BOUNDS) {
+ /** @const {Array<number>} */
+ var ubound = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ?
+ ([128, 128]) :
+ ([gl.drawingBufferWidth, gl.drawingBufferHeight]);
+
+ this.m_srcRect = [-10, -15, 100, 63];
+ this.m_dstRect = deMath.add(deMath.swizzle(ubound, [0, 1, 0, 1]), [-75, -99, 8, 16]);
+ this.m_interestingArea = [ubound[0] - 128, ubound[1] - 128, ubound[0], ubound[1]];
+ }
+ };
+
+ /**
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fFramebufferBlitTests.DefaultFramebufferBlitCase.prototype.render = function(dst) {
+ /** @type {es3fFboTestCase.Context} */
+ var ctx = this.getCurrentContext();
+ // TOOD: implement
+ /** @type {tcuTexture.TextureFormat} */ var colorFormat = gluTextureUtil.mapGLInternalFormat(this.m_format);
+ /** @type {gluTextureUtil.TransferFormat} */ var transferFmt = gluTextureUtil.getTransferFormat(colorFormat);
+ /** @const {tcuTexture.TextureChannelClass} */
+ var targetClass = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ?
+ (tcuTexture.getTextureChannelClass(colorFormat.type)) :
+ (tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT);
+
+ var fbo;
+ var fboTex;
+ /** @const {number} */ var fboTexW = 128;
+ /** @const {number} */ var fboTexH = 128;
+ /** @const {number} */ var sourceWidth = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ? (ctx.getWidth()) : (fboTexW);
+ /** @const {number} */ var sourceHeight = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ? (ctx.getHeight()) : (fboTexH);
+ /** @const {number} */ var gridRenderWidth = Math.min(256, sourceWidth);
+ /** @const {number} */ var gridRenderHeight = Math.min(256, sourceHeight);
+
+ var targetFbo;
+ var sourceFbo;
+
+ // FBO
+ fbo = ctx.createFramebuffer();
+ fboTex = ctx.createTexture();
+
+ ctx.bindTexture(gl.TEXTURE_2D, fboTex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.m_filter);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.m_filter);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, this.m_format, fboTexW, fboTexH, 0, transferFmt.format, transferFmt.dataType, null);
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ ctx.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fboTex, 0);
+ this.checkError();
+ this.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ targetFbo = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ? (fbo) : (null);
+ sourceFbo = (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_DEFAULT_TO_TARGET) ? (null) : (fbo);
+
+ // Render grid to source framebuffer
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var texShader = new es3fFboTestUtil.Texture2DShader(
+ [gluShaderUtil.DataType.SAMPLER_2D],
+ gluShaderUtil.DataType.FLOAT_VEC4);
+ var texShaderID = this.getCurrentContext().createProgram(texShader);
+ /** @const {number} */ var internalFormat = gl.RGBA8;
+ /** @const {number} */ var format = gl.RGBA;
+ /** @const {number} */ var dataType = gl.UNSIGNED_BYTE;
+ /** @const {number} */ var gridTexW = 128;
+ /** @const {number} */ var gridTexH = 128;
+ /** @type {WebGLTexture|framework.opengl.simplereference.sglrReferenceContext.TextureContainer|null} */
+ var gridTex = null;
+ /** @type {tcuTexture.TextureLevel} */ var data = new tcuTexture.TextureLevel(gluTextureUtil.mapGLTransferFormat(format, dataType), gridTexW, gridTexH, 1);
+
+ tcuTextureUtil.fillWithGrid(data.getAccess(), 9, [0.9, 0.5, 0.1, 0.9], [0.2, 0.8, 0.2, 0.7]);
+
+ gridTex = ctx.createTexture();
+ ctx.bindTexture(gl.TEXTURE_2D, gridTex);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ ctx.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ ctx.texImage2D(gl.TEXTURE_2D, 0, internalFormat, gridTexW, gridTexH, 0, format, dataType, data.getAccess().getDataPtr());
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, sourceFbo);
+ ctx.viewport(0, 0, gridRenderWidth, gridRenderHeight);
+ ctx.clearBufferfv(gl.COLOR, 0, [1.0, 0.0, 0.0, 1.0]);
+
+ texShader.setUniforms(this.getCurrentContext(), texShaderID);
+
+ rrUtil.drawQuad(ctx, texShaderID, [-1, -1, 0], [1, 1, 0]);
+
+ ctx.useProgram(null);
+
+ // Blit source framebuffer to destination
+
+ ctx.bindFramebuffer(gl.READ_FRAMEBUFFER, sourceFbo);
+ ctx.bindFramebuffer(gl.DRAW_FRAMEBUFFER, targetFbo);
+ this.checkError();
+
+ if (targetClass == tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT ||
+ targetClass == tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT ||
+ targetClass == tcuTexture.TextureChannelClass.FLOATING_POINT)
+ ctx.clearBufferfv(gl.COLOR, 0, [1.0, 1.0, 0.0, 1.0]);
+ else if (targetClass == tcuTexture.TextureChannelClass.SIGNED_INTEGER)
+ ctx.clearBufferiv(gl.COLOR, 0, [0, 0, 0, 0]);
+ else if (targetClass == tcuTexture.TextureChannelClass.UNSIGNED_INTEGER)
+ ctx.clearBufferuiv(gl.COLOR, 0, [0, 0, 0, 0]);
+ else
+ DE_ASSERT(false);
+
+ ctx.blitFramebuffer(this.m_srcRect[0], this.m_srcRect[1], this.m_srcRect[2], this.m_srcRect[3], this.m_dstRect[0], this.m_dstRect[1], this.m_dstRect[2], this.m_dstRect[3], gl.COLOR_BUFFER_BIT, this.m_filter);
+ this.checkError();
+
+ // Read target
+
+ ctx.bindFramebuffer(gl.FRAMEBUFFER, targetFbo);
+
+ if (this.m_blitDir == es3fFramebufferBlitTests.BlitDirection.BLIT_TO_DEFAULT_FROM_TARGET)
+ this.readPixels(dst, this.m_interestingArea[0], this.m_interestingArea[1], this.m_interestingArea[2] - this.m_interestingArea[0], this.m_interestingArea[3] - this.m_interestingArea[1]);
+ else
+ this.readPixelsUsingFormat(dst, this.m_interestingArea[0], this.m_interestingArea[1], this.m_interestingArea[2] - this.m_interestingArea[0], this.m_interestingArea[3] - this.m_interestingArea[1], colorFormat, [1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0]);
+
+ this.checkError();
+ };
+
+ es3fFramebufferBlitTests.run = function(context, range) {
+ gl = context;
+ //Set up root Test
+ var state = tcuTestCase.runner;
+
+ var test = new es3fFramebufferBlitTests.FramebufferBlitTests();
+ var testName = test.fullName();
+ var testDescription = test.getDescription() || '';
+
+ state.testName = testName;
+ state.setRoot(test);
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ test.init();
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ bufferedLogToConsole(err);
+ testFailedOptions('Failed to es3fFramebufferBlitTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fIndexedStateQueryTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fIndexedStateQueryTests.js
new file mode 100644
index 0000000000..a18f6708b2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fIndexedStateQueryTests.js
@@ -0,0 +1,409 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fIndexedStateQueryTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('functional.gles3.es3fApiCase');
+
+goog.scope(function() {
+ var es3fIndexedStateQueryTests = functional.gles3.es3fIndexedStateQueryTests;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var es3fApiCase = functional.gles3.es3fApiCase;
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIndexedStateQueryTests.TransformFeedbackCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIndexedStateQueryTests.TransformFeedbackCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIndexedStateQueryTests.TransformFeedbackCase.prototype.constructor = es3fIndexedStateQueryTests.TransformFeedbackCase;
+
+ es3fIndexedStateQueryTests.TransformFeedbackCase.prototype.testTransformFeedback = function() {
+ throw new Error('This method should be overriden.');
+ };
+
+ es3fIndexedStateQueryTests.TransformFeedbackCase.prototype.test = function() {
+ /** @type {string} */ var transformFeedbackTestVertSource = '' +
+ '#version 300 es\n' +
+ 'out highp vec4 anotherOutput;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(0.0);\n' +
+ ' anotherOutput = vec4(0.0);\n' +
+ '}\n';
+ /** @type {string} */ var transformFeedbackTestFragSource = '' +
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ /** @type {WebGLShader} */ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ /** @type {WebGLShader} */ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, transformFeedbackTestVertSource);
+ gl.shaderSource(shaderFrag, transformFeedbackTestFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ /** @type {WebGLProgram} */ var shaderProg = gl.createProgram();
+ gl.attachShader(shaderProg, shaderVert);
+ gl.attachShader(shaderProg, shaderFrag);
+
+ /** @type {Array<string>} */ var transformFeedbackOutputs = ['gl_Position', 'anotherOutput'];
+
+ gl.transformFeedbackVaryings(shaderProg, transformFeedbackOutputs, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram(shaderProg);
+
+ /** @type {WebGLTransformFeedback} */ var transformFeedbackId = gl.createTransformFeedback();
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, transformFeedbackId);
+
+ this.testTransformFeedback();
+
+ // cleanup
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+
+ gl.deleteTransformFeedback(transformFeedbackId);
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(shaderProg);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fIndexedStateQueryTests.TransformFeedbackCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase = function(name, description) {
+ es3fIndexedStateQueryTests.TransformFeedbackCase.call(this, name, description);
+ };
+
+ es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase.prototype = Object.create(es3fIndexedStateQueryTests.TransformFeedbackCase.prototype);
+ es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase.prototype.constructor = es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase;
+
+ es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase.prototype.testTransformFeedback = function() {
+ /** @type {number} */ var feedbackPositionIndex = 0;
+ /** @type {number} */ var feedbackOutputIndex = 1;
+ /** @type {Array<number>} */ var feedbackIndex = [feedbackPositionIndex, feedbackOutputIndex];
+
+ // bind buffers
+
+ /** @type {Array<WebGLBuffer>} */ var feedbackBuffers = [];
+ for (var ndx = 0; ndx < 2; ndx++)
+ feedbackBuffers[ndx] = gl.createBuffer();
+
+ for (var ndx = 0; ndx < feedbackBuffers.length; ndx++) {
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[ndx]);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array(16), gl.DYNAMIC_READ);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackIndex[ndx], feedbackBuffers[ndx]);
+ }
+
+ // test TRANSFORM_FEEDBACK_BUFFER_BINDING
+ for (var ndx = 0; ndx < feedbackBuffers.length; ndx++) {
+ var boundBuffer = /** @type {WebGLBuffer} */ (gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, ndx));
+ this.check(boundBuffer === feedbackBuffers[ndx], 'buffers do not match');
+ }
+
+ // cleanup
+ for (var ndx = 0; ndx < feedbackBuffers.length; ndx++)
+ gl.deleteBuffer(feedbackBuffers[ndx]);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fIndexedStateQueryTests.TransformFeedbackCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase = function(name, description) {
+ es3fIndexedStateQueryTests.TransformFeedbackCase.call(this, name, description);
+ };
+
+ es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase.prototype = Object.create(es3fIndexedStateQueryTests.TransformFeedbackCase.prototype);
+ es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase.prototype.constructor = es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase;
+
+ es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase.prototype.testTransformFeedback = function() {
+ /** @type {number} */ var feedbackPositionIndex = 0;
+ /** @type {number} */ var feedbackOutputIndex = 1;
+
+ /** @type {number} */ var rangeBufferOffset = 4;
+ /** @type {number} */ var rangeBufferSize = 8;
+
+ // bind buffers
+
+ /** @type {Array<WebGLBuffer>} */ var feedbackBuffers = [];
+ for (var ndx = 0; ndx < 2; ndx++)
+ feedbackBuffers[ndx] = gl.createBuffer();
+
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[0]);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array(16), gl.DYNAMIC_READ);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackPositionIndex, feedbackBuffers[0]);
+
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackBuffers[1]);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array(16), gl.DYNAMIC_READ);
+ gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackOutputIndex, feedbackBuffers[1], rangeBufferOffset, rangeBufferSize);
+
+ /** @type {Array<{index: number, pname: number, value: number}>} */ var requirements = [
+ {index: feedbackPositionIndex, pname: gl.TRANSFORM_FEEDBACK_BUFFER_START, value: 0},
+ {index: feedbackPositionIndex, pname: gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, value: 0},
+ {index: feedbackOutputIndex, pname: gl.TRANSFORM_FEEDBACK_BUFFER_START, value: rangeBufferOffset},
+ {index: feedbackOutputIndex, pname: gl.TRANSFORM_FEEDBACK_BUFFER_SIZE, value: rangeBufferSize}
+ ];
+
+ for (var ndx = 0; ndx < requirements.length; ndx++) {
+ var state = /** @type {number} */ (gl.getIndexedParameter(requirements[ndx].pname, requirements[ndx].index));
+ this.check(state === requirements[ndx].value, 'got ' + state + '; expected ' + requirements[ndx].value);
+ }
+
+ // cleanup
+ for (var ndx = 0; ndx < feedbackBuffers.length; ndx++)
+ gl.deleteBuffer(feedbackBuffers[ndx]);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIndexedStateQueryTests.UniformBufferCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {?WebGLProgram} */ this.m_program = null;
+ };
+
+ es3fIndexedStateQueryTests.UniformBufferCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIndexedStateQueryTests.UniformBufferCase.prototype.constructor = es3fIndexedStateQueryTests.UniformBufferCase;
+
+ es3fIndexedStateQueryTests.UniformBufferCase.prototype.testUniformBuffers = function() {
+ throw new Error('This method should be overriden.');
+ };
+
+ es3fIndexedStateQueryTests.UniformBufferCase.prototype.test = function() {
+
+ /** @type {string} */ var testVertSource = '' +
+ '#version 300 es\n' +
+ 'uniform highp vec4 input1;\n' +
+ 'uniform highp vec4 input2;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = input1 + input2;\n' +
+ '}\n';
+ /** @type {string} */ var testFragSource = '' +
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ /** @type {WebGLShader} */ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ /** @type {WebGLShader} */ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, testVertSource);
+ gl.shaderSource(shaderFrag, testFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ this.m_program = gl.createProgram();
+ gl.attachShader(this.m_program, shaderVert);
+ gl.attachShader(this.m_program, shaderFrag);
+ gl.linkProgram(this.m_program);
+ gl.useProgram(this.m_program);
+
+ this.testUniformBuffers();
+
+ gl.useProgram(null);
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(this.m_program);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fIndexedStateQueryTests.UniformBufferCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIndexedStateQueryTests.UniformBufferBindingCase = function(name, description) {
+ es3fIndexedStateQueryTests.UniformBufferCase.call(this, name, description);
+ /** @type {?WebGLProgram} */ this.m_program = null;
+ };
+
+ es3fIndexedStateQueryTests.UniformBufferBindingCase.prototype = Object.create(es3fIndexedStateQueryTests.UniformBufferCase.prototype);
+ es3fIndexedStateQueryTests.UniformBufferBindingCase.prototype.constructor = es3fIndexedStateQueryTests.UniformBufferBindingCase;
+
+ es3fIndexedStateQueryTests.UniformBufferBindingCase.prototype.testUniformBuffers = function() {
+ /** @type {Array<string>} */ var uniformNames = ['input1', 'input2'];
+
+ /** @type {Array<number>} */ var uniformIndices = gl.getUniformIndices(this.m_program, uniformNames);
+
+ /** @type {Array<WebGLBuffer>} */ var buffers = [];
+ for (var ndx = 0; ndx < 2; ndx++)
+ buffers[ndx] = gl.createBuffer();
+
+ for (var ndx = 0; ndx < buffers.length; ++ndx) {
+ gl.bindBuffer(gl.UNIFORM_BUFFER, buffers[ndx]);
+ gl.bufferData(gl.UNIFORM_BUFFER, new Float32Array(32), gl.DYNAMIC_DRAW);
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, uniformIndices[ndx], buffers[ndx]);
+ }
+
+ /** @type {Array<WebGLBuffer>} */ var boundBuffer = [];
+ for (var ndx = 0; ndx < buffers.length; ndx++) {
+ boundBuffer[ndx] = /** @type {WebGLBuffer} */ (gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, uniformIndices[ndx]));
+ this.check(boundBuffer[ndx] === buffers[ndx], 'buffers do not match');
+ }
+
+ for (var ndx = 0; ndx < buffers.length; ndx++)
+ gl.deleteBuffer(buffers[ndx]);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fIndexedStateQueryTests.UniformBufferCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIndexedStateQueryTests.UniformBufferBufferCase = function(name, description) {
+ es3fIndexedStateQueryTests.UniformBufferCase.call(this, name, description);
+ /** @type {?WebGLProgram} */ this.m_program = null;
+ };
+
+ es3fIndexedStateQueryTests.UniformBufferBufferCase.prototype = Object.create(es3fIndexedStateQueryTests.UniformBufferCase.prototype);
+ es3fIndexedStateQueryTests.UniformBufferBufferCase.prototype.constructor = es3fIndexedStateQueryTests.UniformBufferBufferCase;
+
+ es3fIndexedStateQueryTests.UniformBufferBufferCase.prototype.testUniformBuffers = function() {
+ /** @type {Array<string>} */ var uniformNames = ['input1', 'input2'];
+
+ /** @type {Array<number>} */ var uniformIndices = gl.getUniformIndices(this.m_program, uniformNames);
+
+ /** @type {number} */ var alignment = this.getAlignment();
+ if (alignment === -1) // cannot continue without this
+ return;
+
+ bufferedLogToConsole('Alignment is ' + alignment);
+
+ /** @type {number} */ var rangeBufferOffset = alignment;
+ /** @type {number} */ var rangeBufferSize = alignment * 2;
+ /** @type {number} */ var rangeBufferTotalSize = rangeBufferOffset + rangeBufferSize + 8; // + 8 has no special meaning, just to make it != with the size of the range
+
+ /** @type {Array<WebGLBuffer>} */ var buffers = [];
+ for (var ndx = 0; ndx < 2; ndx++)
+ buffers[ndx] = gl.createBuffer();
+
+ gl.bindBuffer(gl.UNIFORM_BUFFER, buffers[0]);
+ gl.bufferData(gl.UNIFORM_BUFFER, new Float32Array(32), gl.DYNAMIC_DRAW);
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, uniformIndices[0], buffers[0]);
+
+ gl.bindBuffer(gl.UNIFORM_BUFFER, buffers[1]);
+ gl.bufferData(gl.UNIFORM_BUFFER, new Float32Array(32), gl.DYNAMIC_DRAW);
+ gl.bindBufferRange(gl.UNIFORM_BUFFER, uniformIndices[1], buffers[1], rangeBufferOffset, rangeBufferSize);
+
+ // test UNIFORM_BUFFER_START and UNIFORM_BUFFER_SIZE
+
+ /** @type {Array<{index: number, pname: number, value: number}>} */ var requirements = [
+ {index: uniformIndices[0], pname: gl.UNIFORM_BUFFER_START, value: 0},
+ {index: uniformIndices[0], pname: gl.UNIFORM_BUFFER_SIZE, value: 0},
+ {index: uniformIndices[1], pname: gl.UNIFORM_BUFFER_START, value: rangeBufferOffset},
+ {index: uniformIndices[1], pname: gl.UNIFORM_BUFFER_SIZE, value: rangeBufferSize}
+ ];
+
+ for (var ndx = 0; ndx < requirements.length; ndx++) {
+ var state = /** @type {number} */ (gl.getIndexedParameter(requirements[ndx].pname, requirements[ndx].index));
+
+ this.check(state === requirements[ndx].value, 'got ' + state + '; expected ' + requirements[ndx].value);
+ }
+
+ for (var ndx = 0; ndx < buffers.length; ndx++)
+ gl.deleteBuffer(buffers[ndx]);
+
+ };
+
+ /**
+ * @return {number}
+ */
+ es3fIndexedStateQueryTests.UniformBufferBufferCase.prototype.getAlignment = function() {
+ var state = /** @type {number} */ (gl.getParameter(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT));
+
+ if (state <= 256)
+ return state;
+
+ bufferedLogToConsole('ERROR: UNIFORM_BUFFER_OFFSET_ALIGNMENT has a maximum value of 256.');
+ testFailedOptions('invalid UNIFORM_BUFFER_OFFSET_ALIGNMENT value', false);
+
+ return -1;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fIndexedStateQueryTests.IndexedStateQueryTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'indexed', 'Indexed Integer Values');
+ };
+
+ es3fIndexedStateQueryTests.IndexedStateQueryTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fIndexedStateQueryTests.IndexedStateQueryTests.prototype.constructor = es3fIndexedStateQueryTests.IndexedStateQueryTests;
+
+ es3fIndexedStateQueryTests.IndexedStateQueryTests.prototype.init = function() {
+ // transform feedback
+ this.addChild(new es3fIndexedStateQueryTests.TransformFeedbackBufferBindingCase('transform_feedback_buffer_binding', 'TRANSFORM_FEEDBACK_BUFFER_BINDING'));
+ this.addChild(new es3fIndexedStateQueryTests.TransformFeedbackBufferBufferCase('transform_feedback_buffer_start_size', 'TRANSFORM_FEEDBACK_BUFFER_START and TRANSFORM_FEEDBACK_BUFFER_SIZE'));
+
+ // uniform buffers
+ this.addChild(new es3fIndexedStateQueryTests.UniformBufferBindingCase('uniform_buffer_binding', 'UNIFORM_BUFFER_BINDING'));
+ this.addChild(new es3fIndexedStateQueryTests.UniformBufferBufferCase('uniform_buffer_start_size', 'UNIFORM_BUFFER_START and UNIFORM_BUFFER_SIZE'));
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fIndexedStateQueryTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fIndexedStateQueryTests.IndexedStateQueryTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fIndexedStateQueryTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fInstancedRenderingTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fInstancedRenderingTests.js
new file mode 100644
index 0000000000..adc7e857ca
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fInstancedRenderingTests.js
@@ -0,0 +1,711 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fInstancedRenderingTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTextureUtil');
+
+goog.scope(function() {
+
+var es3fInstancedRenderingTests = functional.gles3.es3fInstancedRenderingTests;
+var gluShaderUtil = framework.opengl.gluShaderUtil;
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+var tcuTestCase = framework.common.tcuTestCase;
+var tcuSurface = framework.common.tcuSurface;
+var deString = framework.delibs.debase.deString;
+var deRandom = framework.delibs.debase.deRandom;
+var tcuImageCompare = framework.common.tcuImageCompare;
+var gluTextureUtil = framework.opengl.gluTextureUtil;
+var deMath = framework.delibs.debase.deMath;
+
+ /** @type {?WebGL2RenderingContext} */ var gl;
+
+ /** @const @type {number} */ es3fInstancedRenderingTests.MAX_RENDER_WIDTH = 128;
+ /** @const @type {number} */ es3fInstancedRenderingTests.MAX_RENDER_HEIGHT = 128;
+
+ /** @const @type {number} */ es3fInstancedRenderingTests.QUAD_GRID_SIZE = 127;
+
+ // Attribute divisors for the attributes defining the color's RGB components.
+ /** @const @type {number} */es3fInstancedRenderingTests.ATTRIB_DIVISOR_R = 3;
+ /** @const @type {number} */es3fInstancedRenderingTests.ATTRIB_DIVISOR_G = 2;
+ /** @const @type {number} */es3fInstancedRenderingTests.ATTRIB_DIVISOR_B = 1;
+
+ /** @const @type {number} */es3fInstancedRenderingTests.OFFSET_COMPONENTS = 3; // \note Affects whether a float or a vecN is used in shader, but only first component is non-zero.
+
+ // Scale and bias values when converting float to integer, when attribute is of integer type.
+ /** @const @type {number} */es3fInstancedRenderingTests.FLOAT_INT_SCALE = 100.0;
+ /** @const @type {number} */es3fInstancedRenderingTests.FLOAT_INT_BIAS = -50.0;
+ /** @const @type {number} */es3fInstancedRenderingTests.FLOAT_UINT_SCALE = 100.0;
+ /** @const @type {number} */es3fInstancedRenderingTests.FLOAT_UINT_BIAS = 0.0;
+
+ var DE_ASSERT = function(expression) {
+ if (!expression) throw new Error('Assert failed');
+ };
+
+ es3fInstancedRenderingTests.TCU_FAIL = function(message) {
+ throw new Error(message);
+ };
+
+ // es3fInstancedRenderingTests.InstancedRenderingCase
+
+ /**
+ * es3fInstancedRenderingTests.DrawFunction
+ * @enum {number}
+ */
+ es3fInstancedRenderingTests.DrawFunction = {
+ FUNCTION_DRAW_ARRAYS_INSTANCED: 0,
+ FUNCTION_DRAW_ELEMENTS_INSTANCED: 1
+ };
+
+ /**
+ * es3fInstancedRenderingTests.InstancingType
+ * @enum {number}
+ */
+ es3fInstancedRenderingTests.InstancingType = {
+ TYPE_INSTANCE_ID: 0,
+ TYPE_ATTRIB_DIVISOR: 1,
+ TYPE_MIXED: 2
+ };
+
+ /**
+ * es3fInstancedRenderingTests.InstancedRenderingCase class, inherits from TestCase class
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ * @param {es3fInstancedRenderingTests.DrawFunction} drawFunction
+ * @param {es3fInstancedRenderingTests.InstancingType} instancingType
+ * @param {gluShaderUtil.DataType} rgbAttrType
+ * @param {number} numInstances
+ */
+ es3fInstancedRenderingTests.InstancedRenderingCase = function(name, description, drawFunction, instancingType, rgbAttrType, numInstances) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ /** @type {es3fInstancedRenderingTests.DrawFunction} */ this.m_function = drawFunction;
+ /** @type {es3fInstancedRenderingTests.InstancingType} */ this.m_instancingType = instancingType;
+ /** @type {gluShaderUtil.DataType} */ this.m_rgbAttrType = rgbAttrType;
+ /** @type {number} */ this.m_numInstances = numInstances;
+ /** @type {gluShaderProgram.ShaderProgram} */ this.m_program = null;
+ /** @type {Array<number>} */ this.m_gridVertexPositions = [];
+ /** @type {Array<number>} */ this.m_gridIndices = [];
+ /** @type {Array<number>} */ this.m_instanceOffsets = [];
+ /** @type {Array<number>} */ this.m_instanceColorR = [];
+ /** @type {Array<number>} */ this.m_instanceColorG = [];
+ /** @type {Array<number>} */ this.m_instanceColorB = [];
+ };
+
+ es3fInstancedRenderingTests.InstancedRenderingCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fInstancedRenderingTests.InstancedRenderingCase.prototype.constructor = es3fInstancedRenderingTests.InstancedRenderingCase;
+
+ /**
+ * Helper function that does biasing and scaling when converting float to integer.
+ * @param {Array<number>} vec
+ * @param {number} val
+ */
+ es3fInstancedRenderingTests.InstancedRenderingCase.prototype.pushVarCompAttrib = function(vec, val) {
+ var isFloatCase = gluShaderUtil.isDataTypeFloatOrVec(this.m_rgbAttrType);
+ var isIntCase = gluShaderUtil.isDataTypeIntOrIVec(this.m_rgbAttrType);
+ var isUintCase = gluShaderUtil.isDataTypeUintOrUVec(this.m_rgbAttrType);
+ var isMatCase = gluShaderUtil.isDataTypeMatrix(this.m_rgbAttrType);
+ if (isFloatCase || isMatCase)
+ vec.push(val);
+ else if (isIntCase)
+ vec.push(val * es3fInstancedRenderingTests.FLOAT_INT_SCALE + es3fInstancedRenderingTests.FLOAT_INT_BIAS);
+ else if (isUintCase)
+ vec.push(val * es3fInstancedRenderingTests.FLOAT_UINT_SCALE + es3fInstancedRenderingTests.FLOAT_UINT_BIAS);
+ else
+ throw new Error('Invalid attribute type.');
+ };
+
+ es3fInstancedRenderingTests.InstancedRenderingCase.prototype.init = function() {
+ // Clear errors from previous tests
+ gl.getError();
+
+ /** @type {boolean} */ var isFloatCase = gluShaderUtil.isDataTypeFloatOrVec(this.m_rgbAttrType);
+ /** @type {boolean} */ var isIntCase = gluShaderUtil.isDataTypeIntOrIVec(this.m_rgbAttrType);
+ /** @type {boolean} */ var isUintCase = gluShaderUtil.isDataTypeUintOrUVec(this.m_rgbAttrType);
+ /** @type {boolean} */ var isMatCase = gluShaderUtil.isDataTypeMatrix(this.m_rgbAttrType);
+ /** @type {number} */ var typeSize = gluShaderUtil.getDataTypeScalarSize(this.m_rgbAttrType);
+ /** @type {boolean} */ var isScalarCase = typeSize == 1;
+ /** @type {string} */ var swizzleFirst = isScalarCase ? '' : '.x';
+ /** @type {string} */ var typeName = gluShaderUtil.getDataTypeName(this.m_rgbAttrType);
+
+ /** @type {string} */ var floatIntScaleStr = '(' + es3fInstancedRenderingTests.FLOAT_INT_SCALE.toFixed(3) + ')';
+ /** @type {string} */ var floatIntBiasStr = '(' + es3fInstancedRenderingTests.FLOAT_INT_BIAS.toFixed(3) + ')';
+ /** @type {string} */ var floatUintScaleStr = '(' + es3fInstancedRenderingTests.FLOAT_UINT_SCALE.toFixed(3) + ')';
+ /** @type {string} */ var floatUintBiasStr = '(' + es3fInstancedRenderingTests.FLOAT_UINT_BIAS.toFixed(3) + ')';
+
+ DE_ASSERT(isFloatCase || isIntCase || isUintCase || isMatCase);
+
+ // Generate shader.
+ // \note For case TYPE_MIXED, vertex position offset and color red component get their values from instance id, while green and blue get their values from instanced attributes.
+
+ /** @type {string} */ var numInstancesStr = this.m_numInstances.toString() + '.0';
+
+ /** @type {string} */ var instanceAttribs = '';
+ /** @type {string} */ var posExpression = '';
+ /** @type {string} */ var colorRExpression = '';
+ /** @type {string} */ var colorGExpression = '';
+ /** @type {string} */ var colorBExpression = '';
+
+ if (this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_INSTANCE_ID || this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_MIXED) {
+ posExpression = 'a_position + vec4(float(gl_InstanceID) * 2.0 / ' + numInstancesStr + ', 0.0, 0.0, 0.0)';
+ colorRExpression = 'float(gl_InstanceID)/' + numInstancesStr;
+
+ if (this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_INSTANCE_ID) {
+ colorGExpression = 'float(gl_InstanceID)*2.0/' + numInstancesStr;
+ colorBExpression = '1.0 - float(gl_InstanceID)/' + numInstancesStr;
+ }
+ }
+
+ if (this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_ATTRIB_DIVISOR || this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_MIXED) {
+ if (this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_ATTRIB_DIVISOR) {
+ posExpression = 'a_position + vec4(a_instanceOffset';
+
+ DE_ASSERT(es3fInstancedRenderingTests.OFFSET_COMPONENTS >= 1 && es3fInstancedRenderingTests.OFFSET_COMPONENTS <= 4);
+
+ for (var i = 0; i < 4 - es3fInstancedRenderingTests.OFFSET_COMPONENTS; i++)
+ posExpression += ', 0.0';
+ posExpression += ')';
+
+ if (isFloatCase)
+ colorRExpression = 'a_instanceR' + swizzleFirst;
+ else if (isIntCase)
+ colorRExpression = '(float(a_instanceR' + swizzleFirst + ') - ' + floatIntBiasStr + ') / ' + floatIntScaleStr;
+ else if (isUintCase)
+ colorRExpression = '(float(a_instanceR' + swizzleFirst + ') - ' + floatUintBiasStr + ') / ' + floatUintScaleStr;
+ else if (isMatCase)
+ colorRExpression = 'a_instanceR[0][0]';
+ else
+ DE_ASSERT(false);
+
+ instanceAttribs += 'in highp ' + (es3fInstancedRenderingTests.OFFSET_COMPONENTS == 1 ? 'float' : 'vec' + es3fInstancedRenderingTests.OFFSET_COMPONENTS.toString()) + ' a_instanceOffset;\n';
+ instanceAttribs += 'in mediump ' + typeName + ' a_instanceR;\n';
+ }
+
+ if (isFloatCase) {
+ colorGExpression = 'a_instanceG' + swizzleFirst;
+ colorBExpression = 'a_instanceB' + swizzleFirst;
+ } else if (isIntCase) {
+ colorGExpression = '(float(a_instanceG' + swizzleFirst + ') - ' + floatIntBiasStr + ') / ' + floatIntScaleStr;
+ colorBExpression = '(float(a_instanceB' + swizzleFirst + ') - ' + floatIntBiasStr + ') / ' + floatIntScaleStr;
+ } else if (isUintCase) {
+ colorGExpression = '(float(a_instanceG' + swizzleFirst + ') - ' + floatUintBiasStr + ') / ' + floatUintScaleStr;
+ colorBExpression = '(float(a_instanceB' + swizzleFirst + ') - ' + floatUintBiasStr + ') / ' + floatUintScaleStr;
+ } else if (isMatCase) {
+ colorGExpression = 'a_instanceG[0][0]';
+ colorBExpression = 'a_instanceB[0][0]';
+ } else
+ DE_ASSERT(false);
+
+ instanceAttribs += 'in mediump ' + typeName + ' a_instanceG;\n';
+ instanceAttribs += 'in mediump ' + typeName + ' a_instanceB;\n';
+ }
+
+ DE_ASSERT(!(posExpression.length == 0));
+ DE_ASSERT(!(colorRExpression.length == 0));
+ DE_ASSERT(!(colorGExpression.length == 0));
+ DE_ASSERT(!(colorBExpression.length == 0));
+
+ /** @type {string} */ var vertShaderSourceStr =
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ instanceAttribs +
+ 'out mediump vec4 v_color;\n' +
+ '\n' +
+ 'void main()\n' +
+ ' {\n' +
+ ' gl_Position = ' + posExpression + ';\n' +
+ ' v_color.r = ' + colorRExpression + ';\n' +
+ ' v_color.g = ' + colorGExpression + ';\n' +
+ ' v_color.b = ' + colorBExpression + ';\n' +
+ ' v_color.a = 1.0;\n' +
+ '}\n';
+
+ /** @type {string} */ var fragShaderSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'in mediump vec4 v_color;\n' +
+ '\n' +
+ 'void main()\n' +
+ ' {\n' +
+ ' o_color = v_color;\n' +
+ '}\n';
+
+ // Create shader program and log it.
+
+ DE_ASSERT(!this.m_program);
+ this.m_program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertShaderSourceStr, fragShaderSource));
+
+ //tcu::TestLog& log = this.m_testCtx.getLog();
+ //log << *m_program;
+ // TODO: bufferedLogToConsole?
+ //bufferedLogToConsole(this.m_program);
+
+ assertMsgOptions(this.m_program.isOk(), 'Failed to compile shader', false, true);
+
+ // Vertex shader attributes.
+
+ if (this.m_function == es3fInstancedRenderingTests.DrawFunction.FUNCTION_DRAW_ELEMENTS_INSTANCED) {
+ // Vertex positions. Positions form a vertical bar of width <screen width>/<number of instances>.
+
+ for (var y = 0; y < es3fInstancedRenderingTests.QUAD_GRID_SIZE + 1; y++)
+ for (var x = 0; x < es3fInstancedRenderingTests.QUAD_GRID_SIZE + 1; x++) {
+ /** @type {number} */ var fx = -1.0 + x / es3fInstancedRenderingTests.QUAD_GRID_SIZE * 2.0 / this.m_numInstances;
+ /** @type {number} */ var fy = -1.0 + y / es3fInstancedRenderingTests.QUAD_GRID_SIZE * 2.0;
+
+ this.m_gridVertexPositions.push(fx);
+ this.m_gridVertexPositions.push(fy);
+ }
+
+ // Indices.
+
+ for (var y = 0; y < es3fInstancedRenderingTests.QUAD_GRID_SIZE; y++)
+ for (var x = 0; x < es3fInstancedRenderingTests.QUAD_GRID_SIZE; x++) {
+ /** @type {number} */ var ndx00 = y * (es3fInstancedRenderingTests.QUAD_GRID_SIZE + 1) + x;
+ /** @type {number} */ var ndx10 = y * (es3fInstancedRenderingTests.QUAD_GRID_SIZE + 1) + x + 1;
+ /** @type {number} */ var ndx01 = (y + 1) * (es3fInstancedRenderingTests.QUAD_GRID_SIZE + 1) + x;
+ /** @type {number} */ var ndx11 = (y + 1) * (es3fInstancedRenderingTests.QUAD_GRID_SIZE + 1) + x + 1;
+
+ // Lower-left triangle of a quad.
+ this.m_gridIndices.push(ndx00);
+ this.m_gridIndices.push(ndx10);
+ this.m_gridIndices.push(ndx01);
+
+ // Upper-right triangle of a quad.
+ this.m_gridIndices.push(ndx11);
+ this.m_gridIndices.push(ndx01);
+ this.m_gridIndices.push(ndx10);
+ }
+ } else {
+ DE_ASSERT(this.m_function == es3fInstancedRenderingTests.DrawFunction.FUNCTION_DRAW_ARRAYS_INSTANCED);
+
+ // Vertex positions. Positions form a vertical bar of width <screen width>/<number of instances>.
+
+ for (var y = 0; y < es3fInstancedRenderingTests.QUAD_GRID_SIZE; y++)
+ for (var x = 0; x < es3fInstancedRenderingTests.QUAD_GRID_SIZE; x++) {
+ /** @type {number} */ var fx0 = -1.0 + (x + 0) / es3fInstancedRenderingTests.QUAD_GRID_SIZE * 2.0 / this.m_numInstances;
+ /** @type {number} */ var fx1 = -1.0 + (x + 1) / es3fInstancedRenderingTests.QUAD_GRID_SIZE * 2.0 / this.m_numInstances;
+ /** @type {number} */ var fy0 = -1.0 + (y + 0) / es3fInstancedRenderingTests.QUAD_GRID_SIZE * 2.0;
+ /** @type {number} */ var fy1 = -1.0 + (y + 1) / es3fInstancedRenderingTests.QUAD_GRID_SIZE * 2.0;
+
+ // Vertices of a quad's lower-left triangle: (fx0, fy0), (fx1, fy0) and (fx0, fy1)
+ this.m_gridVertexPositions.push(fx0);
+ this.m_gridVertexPositions.push(fy0);
+ this.m_gridVertexPositions.push(fx1);
+ this.m_gridVertexPositions.push(fy0);
+ this.m_gridVertexPositions.push(fx0);
+ this.m_gridVertexPositions.push(fy1);
+
+ // Vertices of a quad's upper-right triangle: (fx1, fy1), (fx0, fy1) and (fx1, fy0)
+ this.m_gridVertexPositions.push(fx1);
+ this.m_gridVertexPositions.push(fy1);
+ this.m_gridVertexPositions.push(fx0);
+ this.m_gridVertexPositions.push(fy1);
+ this.m_gridVertexPositions.push(fx1);
+ this.m_gridVertexPositions.push(fy0);
+ }
+ }
+
+ // Instanced attributes: position offset and color RGB components.
+
+ if (this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_ATTRIB_DIVISOR || this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_MIXED) {
+ if (this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_ATTRIB_DIVISOR) {
+ // Offsets are such that the vertical bars are drawn next to each other.
+ for (var i = 0; i < this.m_numInstances; i++) {
+ this.m_instanceOffsets.push(i * 2.0 / this.m_numInstances);
+
+ DE_ASSERT(es3fInstancedRenderingTests.OFFSET_COMPONENTS >= 1 && es3fInstancedRenderingTests.OFFSET_COMPONENTS <= 4);
+
+ for (var j = 0; j < es3fInstancedRenderingTests.OFFSET_COMPONENTS - 1; j++)
+ this.m_instanceOffsets.push(0.0);
+ }
+
+ /** @type {number} */ var rInstances = Math.floor(this.m_numInstances / es3fInstancedRenderingTests.ATTRIB_DIVISOR_R) + (this.m_numInstances % es3fInstancedRenderingTests.ATTRIB_DIVISOR_R == 0 ? 0 : 1);
+ for (var i = 0; i < rInstances; i++) {
+ this.pushVarCompAttrib(this.m_instanceColorR, i / rInstances);
+
+ for (var j = 0; j < typeSize - 1; j++)
+ this.pushVarCompAttrib(this.m_instanceColorR, 0.0);
+ }
+ }
+
+ /** @type {number} */ var gInstances = Math.floor(this.m_numInstances / es3fInstancedRenderingTests.ATTRIB_DIVISOR_G) + (this.m_numInstances % es3fInstancedRenderingTests.ATTRIB_DIVISOR_G == 0 ? 0 : 1);
+ for (var i = 0; i < gInstances; i++) {
+ this.pushVarCompAttrib(this.m_instanceColorG, i * 2.0 / gInstances);
+
+ for (var j = 0; j < typeSize - 1; j++)
+ this.pushVarCompAttrib(this.m_instanceColorG, 0.0);
+ }
+
+ /** @type {number} */ var bInstances = Math.floor(this.m_numInstances / es3fInstancedRenderingTests.ATTRIB_DIVISOR_B) + (this.m_numInstances % es3fInstancedRenderingTests.ATTRIB_DIVISOR_B == 0 ? 0 : 1);
+ for (var i = 0; i < bInstances; i++) {
+ this.pushVarCompAttrib(this.m_instanceColorB, 1.0 - i / bInstances);
+
+ for (var j = 0; j < typeSize - 1; j++)
+ this.pushVarCompAttrib(this.m_instanceColorB, 0.0);
+ }
+ }
+ };
+
+ es3fInstancedRenderingTests.InstancedRenderingCase.prototype.deinit = function() {
+ var numVertexAttribArrays = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ for (var idx = 0; idx < numVertexAttribArrays; idx++) {
+ gl.disableVertexAttribArray(idx);
+ gl.vertexAttribDivisor(idx, 0);
+ }
+ };
+
+ es3fInstancedRenderingTests.InstancedRenderingCase.prototype.iterate = function() {
+ /** @type {number} */ var width = Math.min(gl.drawingBufferWidth, es3fInstancedRenderingTests.MAX_RENDER_WIDTH);
+ /** @type {number} */ var height = Math.min(gl.drawingBufferHeight, es3fInstancedRenderingTests.MAX_RENDER_HEIGHT);
+
+ /** @type {number} */ var xOffsetMax = gl.drawingBufferWidth - width;
+ /** @type {number} */ var yOffsetMax = gl.drawingBufferHeight - height;
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name));
+
+ /** @type {number} */ var xOffset = rnd.getInt(0, xOffsetMax);
+ /** @type {number} */ var yOffset = rnd.getInt(0, yOffsetMax);
+
+ /** @type {tcuSurface.Surface} */ var referenceImg = new tcuSurface.Surface(width, height);
+ /** @type {tcuSurface.Surface} */ var resultImg = new tcuSurface.Surface(width, height);
+
+ // Draw result.
+
+ gl.viewport(xOffset, yOffset, width, height);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ this.setupAndRender();
+
+ var resImg = resultImg.getAccess();
+ var resImgTransferFormat = gluTextureUtil.getTransferFormat(resImg.getFormat());
+
+ gl.readPixels(xOffset, yOffset, resImg.m_width, resImg.m_height, resImgTransferFormat.format, resImgTransferFormat.dataType, resultImg.m_pixels);
+
+ // Compute reference.
+ this.computeReference(referenceImg);
+
+ // Compare.
+
+ // Passing referenceImg.getAccess() and resultImg.getAccess() instead of referenceImg and resultImg
+ /** @type {boolean} */ var testOk = tcuImageCompare.fuzzyCompare('ComparisonResult', 'Image comparison result', referenceImg.getAccess(), resultImg.getAccess(), 0.05 /*, gluShaderUtil.COMPARE_LOG_RESULT*/);
+
+ assertMsgOptions(testOk, '', true, false);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @param {Array<number>} attrPtr
+ * @param {number} location
+ * @param {number} divisor
+ */
+ es3fInstancedRenderingTests.InstancedRenderingCase.prototype.setupVarAttribPointer = function(attrPtr, location, divisor) {
+ /** @type {boolean} */ var isFloatCase = gluShaderUtil.isDataTypeFloatOrVec(this.m_rgbAttrType);
+ /** @type {boolean} */ var isIntCase = gluShaderUtil.isDataTypeIntOrIVec(this.m_rgbAttrType);
+ /** @type {boolean} */ var isUintCase = gluShaderUtil.isDataTypeUintOrUVec(this.m_rgbAttrType);
+ /** @type {boolean} */ var isMatCase = gluShaderUtil.isDataTypeMatrix(this.m_rgbAttrType);
+ /** @type {number} */ var typeSize = gluShaderUtil.getDataTypeScalarSize(this.m_rgbAttrType);
+ /** @type {number} */ var numSlots = isMatCase ? gluShaderUtil.getDataTypeMatrixNumColumns(this.m_rgbAttrType) : 1; // Matrix uses as many attribute slots as it has columns.
+
+ for (var slotNdx = 0; slotNdx < numSlots; slotNdx++) {
+ /** @type {number} */ var curLoc = location + slotNdx;
+
+ gl.enableVertexAttribArray(curLoc);
+ gl.vertexAttribDivisor(curLoc, divisor);
+ var curLocGlBuffer = gl.createBuffer();
+ if (isFloatCase) {
+ var bufferCurLoc = new Float32Array(attrPtr);
+ gl.bindBuffer(gl.ARRAY_BUFFER, curLocGlBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, bufferCurLoc, gl.STATIC_DRAW);
+
+ gl.vertexAttribPointer(curLoc, typeSize, gl.FLOAT, false, 0, 0);
+ } else if (isIntCase) {
+ var bufferCurLoc = new Int32Array(attrPtr);
+ gl.bindBuffer(gl.ARRAY_BUFFER, curLocGlBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, bufferCurLoc, gl.STATIC_DRAW);
+
+ gl.vertexAttribIPointer(curLoc, typeSize, gl.INT, 0, 0);
+ } else if (isUintCase) {
+ var bufferCurLoc = new Uint32Array(attrPtr);
+ gl.bindBuffer(gl.ARRAY_BUFFER, curLocGlBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, bufferCurLoc, gl.STATIC_DRAW);
+
+ gl.vertexAttribIPointer(curLoc, typeSize, gl.UNSIGNED_INT, 0, 0);
+ } else if (isMatCase) {
+ /** @type {number} */ var numRows = gluShaderUtil.getDataTypeMatrixNumRows(this.m_rgbAttrType);
+ /** @type {number} */ var numCols = gluShaderUtil.getDataTypeMatrixNumColumns(this.m_rgbAttrType);
+
+ var bufferCurLoc = new Float32Array(attrPtr);
+ gl.bindBuffer(gl.ARRAY_BUFFER, curLocGlBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, bufferCurLoc, gl.STATIC_DRAW);
+
+ gl.vertexAttribPointer(curLoc, numRows, gl.FLOAT, false, numCols * numRows * 4, 0);
+ } else
+ DE_ASSERT(false);
+ }
+ };
+
+ es3fInstancedRenderingTests.InstancedRenderingCase.prototype.setupAndRender = function() {
+ /** @type {WebGLProgram} */ var program = this.m_program.getProgram();
+
+ gl.useProgram(program);
+ // Setup attributes.
+
+ // Position attribute is non-instanced.
+ /** @type {number} */ var positionLoc = gl.getAttribLocation(program, 'a_position');
+ gl.enableVertexAttribArray(positionLoc);
+ var positionBuffer = gl.createBuffer();
+ var bufferGridVertexPosition = new Float32Array(this.m_gridVertexPositions);
+ gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, bufferGridVertexPosition, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
+
+ if (this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_ATTRIB_DIVISOR || this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_MIXED) {
+ if (this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_ATTRIB_DIVISOR) {
+ // Position offset attribute is instanced with separate offset for every instance.
+ /** @type {number} */ var offsetLoc = gl.getAttribLocation(program, 'a_instanceOffset');
+ gl.enableVertexAttribArray(offsetLoc);
+ gl.vertexAttribDivisor(offsetLoc, 1);
+
+ var offsetLocGlBuffer = gl.createBuffer();
+ var bufferOffsetLoc = new Float32Array(this.m_instanceOffsets);
+ gl.bindBuffer(gl.ARRAY_BUFFER, offsetLocGlBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, bufferOffsetLoc, gl.STATIC_DRAW);
+
+ gl.vertexAttribPointer(offsetLoc, es3fInstancedRenderingTests.OFFSET_COMPONENTS, gl.FLOAT, false, 0, 0);
+
+ /** @type {number} */ var rLoc = gl.getAttribLocation(program, 'a_instanceR');
+ this.setupVarAttribPointer(this.m_instanceColorR, rLoc, es3fInstancedRenderingTests.ATTRIB_DIVISOR_R);
+ }
+
+ /** @type {number} */ var gLoc = gl.getAttribLocation(program, 'a_instanceG');
+ this.setupVarAttribPointer(this.m_instanceColorG, gLoc, es3fInstancedRenderingTests.ATTRIB_DIVISOR_G);
+
+ /** @type {number} */ var bLoc = gl.getAttribLocation(program, 'a_instanceB');
+ this.setupVarAttribPointer(this.m_instanceColorB, bLoc, es3fInstancedRenderingTests.ATTRIB_DIVISOR_B);
+ }
+
+ // Draw using appropriate function.
+
+ if (this.m_function == es3fInstancedRenderingTests.DrawFunction.FUNCTION_DRAW_ARRAYS_INSTANCED) {
+ /** @type {number} */ var numPositionComponents = 2;
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, Math.floor(this.m_gridVertexPositions.length / numPositionComponents), this.m_numInstances);
+ } else {
+ var gridIndicesGLBuffer = gl.createBuffer();
+ var bufferGridIndices = new Uint16Array(this.m_gridIndices);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gridIndicesGLBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, bufferGridIndices, gl.STATIC_DRAW);
+
+ gl.drawElementsInstanced(gl.TRIANGLES, this.m_gridIndices.length, gl.UNSIGNED_SHORT, 0, this.m_numInstances);
+ }
+ gl.useProgram(null);
+ };
+
+ /**
+ * @param {tcuSurface.Surface} dst
+ */
+ es3fInstancedRenderingTests.InstancedRenderingCase.prototype.computeReference = function(dst) {
+ /** @type {number} */ var wid = dst.getWidth();
+ /** @type {number} */ var hei = dst.getHeight();
+
+ // Draw a rectangle (vertical bar) for each instance.
+
+ for (var instanceNdx = 0; instanceNdx < this.m_numInstances; instanceNdx++) {
+ /** @type {number} */ var xStart = Math.floor(instanceNdx * wid / this.m_numInstances);
+ /** @type {number} */ var xEnd = Math.floor((instanceNdx + 1) * wid / this.m_numInstances);
+
+ // Emulate attribute divisors if that is the case.
+
+ /** @type {number} */ var clrNdxR = this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_ATTRIB_DIVISOR ? Math.floor(instanceNdx / es3fInstancedRenderingTests.ATTRIB_DIVISOR_R) : instanceNdx;
+ /** @type {number} */ var clrNdxG = this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_ATTRIB_DIVISOR || this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_MIXED ? Math.floor(instanceNdx / es3fInstancedRenderingTests.ATTRIB_DIVISOR_G) : instanceNdx;
+ /** @type {number} */ var clrNdxB = this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_ATTRIB_DIVISOR || this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_MIXED ? Math.floor(instanceNdx / es3fInstancedRenderingTests.ATTRIB_DIVISOR_B) : instanceNdx;
+
+ /** @type {number} */ var rInstances = this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_ATTRIB_DIVISOR ? Math.floor(this.m_numInstances / es3fInstancedRenderingTests.ATTRIB_DIVISOR_R) + (this.m_numInstances % es3fInstancedRenderingTests.ATTRIB_DIVISOR_R == 0 ? 0 : 1) : this.m_numInstances;
+ /** @type {number} */ var gInstances = this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_ATTRIB_DIVISOR || this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_MIXED ? Math.floor(this.m_numInstances / es3fInstancedRenderingTests.ATTRIB_DIVISOR_G) + (this.m_numInstances % es3fInstancedRenderingTests.ATTRIB_DIVISOR_G == 0 ? 0 : 1) : this.m_numInstances;
+ /** @type {number} */ var bInstances = this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_ATTRIB_DIVISOR || this.m_instancingType == es3fInstancedRenderingTests.InstancingType.TYPE_MIXED ? Math.floor(this.m_numInstances / es3fInstancedRenderingTests.ATTRIB_DIVISOR_B) + (this.m_numInstances % es3fInstancedRenderingTests.ATTRIB_DIVISOR_B == 0 ? 0 : 1) : this.m_numInstances;
+
+ // Calculate colors.
+
+ /** @type {number} */ var r = clrNdxR / rInstances;
+ /** @type {number} */ var g = clrNdxG * 2.0 / gInstances;
+ /** @type {number} */ var b = 1.0 - clrNdxB / bInstances;
+
+ // Convert to integer and back if shader inputs are integers.
+
+ if (gluShaderUtil.isDataTypeIntOrIVec(this.m_rgbAttrType)) {
+ /** @type {number} */var intR = (r * es3fInstancedRenderingTests.FLOAT_INT_SCALE + es3fInstancedRenderingTests.FLOAT_INT_BIAS);
+ /** @type {number} */var intG = (g * es3fInstancedRenderingTests.FLOAT_INT_SCALE + es3fInstancedRenderingTests.FLOAT_INT_BIAS);
+ /** @type {number} */var intB = (b * es3fInstancedRenderingTests.FLOAT_INT_SCALE + es3fInstancedRenderingTests.FLOAT_INT_BIAS);
+ r = (intR - es3fInstancedRenderingTests.FLOAT_INT_BIAS) / es3fInstancedRenderingTests.FLOAT_INT_SCALE;
+ g = (intG - es3fInstancedRenderingTests.FLOAT_INT_BIAS) / es3fInstancedRenderingTests.FLOAT_INT_SCALE;
+ b = (intB - es3fInstancedRenderingTests.FLOAT_INT_BIAS) / es3fInstancedRenderingTests.FLOAT_INT_SCALE;
+ } else if (gluShaderUtil.isDataTypeUintOrUVec(this.m_rgbAttrType)) {
+ /** @type {number} */var uintR = (r * es3fInstancedRenderingTests.FLOAT_UINT_SCALE + es3fInstancedRenderingTests.FLOAT_UINT_BIAS);
+ /** @type {number} */var uintG = (g * es3fInstancedRenderingTests.FLOAT_UINT_SCALE + es3fInstancedRenderingTests.FLOAT_UINT_BIAS);
+ /** @type {number} */var uintB = (b * es3fInstancedRenderingTests.FLOAT_UINT_SCALE + es3fInstancedRenderingTests.FLOAT_UINT_BIAS);
+ r = (uintR - es3fInstancedRenderingTests.FLOAT_UINT_BIAS) / es3fInstancedRenderingTests.FLOAT_UINT_SCALE;
+ g = (uintG - es3fInstancedRenderingTests.FLOAT_UINT_BIAS) / es3fInstancedRenderingTests.FLOAT_UINT_SCALE;
+ b = (uintB - es3fInstancedRenderingTests.FLOAT_UINT_BIAS) / es3fInstancedRenderingTests.FLOAT_UINT_SCALE;
+ }
+
+ // Convert from float to unorm8.
+ var color = deMath.add(deMath.scale([r, g, b, 1.0], 255), [0.5, 0.5, 0.5, 0.5]);
+ color = deMath.clampVector(color, 0, 255);
+
+ // Draw rectangle.
+ for (var y = 0; y < hei; y++)
+ for (var x = xStart; x < xEnd; x++)
+ dst.setPixel(x, y, color);
+ }
+ };
+
+ es3fInstancedRenderingTests.init = function() {
+ var testGroup = tcuTestCase.runner.testCases;
+ /** @type {Array<number>} */ var instanceCounts = [1, 2, 4, 20];
+
+ for (var _function in es3fInstancedRenderingTests.DrawFunction) {
+ /** @type {?string} */ var functionName =
+ es3fInstancedRenderingTests.DrawFunction[_function] == es3fInstancedRenderingTests.DrawFunction.FUNCTION_DRAW_ARRAYS_INSTANCED ? 'draw_arrays_instanced' :
+ es3fInstancedRenderingTests.DrawFunction[_function] == es3fInstancedRenderingTests.DrawFunction.FUNCTION_DRAW_ELEMENTS_INSTANCED ? 'draw_elements_instanced' :
+ null;
+
+ /** @type {?string} */ var functionDesc =
+ es3fInstancedRenderingTests.DrawFunction[_function] == es3fInstancedRenderingTests.DrawFunction.FUNCTION_DRAW_ARRAYS_INSTANCED ? 'Use glDrawArraysInstanced()' :
+ es3fInstancedRenderingTests.DrawFunction[_function] == es3fInstancedRenderingTests.DrawFunction.FUNCTION_DRAW_ELEMENTS_INSTANCED ? 'Use glDrawElementsInstanced()' :
+ null;
+
+ DE_ASSERT(functionName != null);
+ DE_ASSERT(functionDesc != null);
+
+ /** @type {tcuTestCase.DeqpTest} */ var functionGroup = tcuTestCase.newTest(functionName, functionDesc);
+ testGroup.addChild(functionGroup);
+
+ for (var instancingType in es3fInstancedRenderingTests.InstancingType) {
+ /** @type {?string} */ var instancingTypeName =
+ es3fInstancedRenderingTests.InstancingType[instancingType] == es3fInstancedRenderingTests.InstancingType.TYPE_INSTANCE_ID ? 'instance_id' :
+ es3fInstancedRenderingTests.InstancingType[instancingType] == es3fInstancedRenderingTests.InstancingType.TYPE_ATTRIB_DIVISOR ? 'attribute_divisor' :
+ es3fInstancedRenderingTests.InstancingType[instancingType] == es3fInstancedRenderingTests.InstancingType.TYPE_MIXED ? 'mixed' :
+ null;
+
+ /** @type {?string} */ var instancingTypeDesc =
+ es3fInstancedRenderingTests.InstancingType[instancingType] == es3fInstancedRenderingTests.InstancingType.TYPE_INSTANCE_ID ? 'Use gl_InstanceID for instancing' :
+ es3fInstancedRenderingTests.InstancingType[instancingType] == es3fInstancedRenderingTests.InstancingType.TYPE_ATTRIB_DIVISOR ? 'Use vertex attribute divisors for instancing' :
+ es3fInstancedRenderingTests.InstancingType[instancingType] == es3fInstancedRenderingTests.InstancingType.TYPE_MIXED ? 'Use both gl_InstanceID and vertex attribute divisors for instancing' :
+ null;
+
+ DE_ASSERT(instancingTypeName != null);
+ DE_ASSERT(instancingTypeDesc != null);
+
+ /** @type {tcuTestCase.DeqpTest} */
+ var instancingTypeGroup = tcuTestCase.newTest(instancingTypeName, instancingTypeDesc);
+
+ functionGroup.addChild(instancingTypeGroup);
+
+ for (var countNdx in instanceCounts) {
+ /** @type {string} */ var countName = instanceCounts[countNdx].toString() + '_instances';
+ instancingTypeGroup.addChild(new es3fInstancedRenderingTests.InstancedRenderingCase(countName,
+ '',
+ es3fInstancedRenderingTests.DrawFunction[_function],
+ es3fInstancedRenderingTests.InstancingType[instancingType],
+ gluShaderUtil.DataType.FLOAT,
+ instanceCounts[countNdx]));
+ }
+ }
+ }
+
+ /** @type {Array<gluShaderUtil.DataType>} */ var s_testTypes =
+ [
+ gluShaderUtil.DataType.FLOAT,
+ gluShaderUtil.DataType.FLOAT_VEC2,
+ gluShaderUtil.DataType.FLOAT_VEC3,
+ gluShaderUtil.DataType.FLOAT_VEC4,
+ gluShaderUtil.DataType.FLOAT_MAT2,
+ gluShaderUtil.DataType.FLOAT_MAT2X3,
+ gluShaderUtil.DataType.FLOAT_MAT2X4,
+ gluShaderUtil.DataType.FLOAT_MAT3X2,
+ gluShaderUtil.DataType.FLOAT_MAT3,
+ gluShaderUtil.DataType.FLOAT_MAT3X4,
+ gluShaderUtil.DataType.FLOAT_MAT4X2,
+ gluShaderUtil.DataType.FLOAT_MAT4X3,
+ gluShaderUtil.DataType.FLOAT_MAT4,
+
+ gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT_VEC2,
+ gluShaderUtil.DataType.INT_VEC3,
+ gluShaderUtil.DataType.INT_VEC4,
+
+ gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT_VEC2,
+ gluShaderUtil.DataType.UINT_VEC3,
+ gluShaderUtil.DataType.UINT_VEC4
+ ];
+
+ /** @type {number} */ var typeTestNumInstances = 4;
+
+ /** @type {tcuTestCase.DeqpTest} */ var typesGroup = tcuTestCase.newTest('types', 'Tests for instanced attributes of particular data types');
+
+ testGroup.addChild(typesGroup);
+
+ for (var typeNdx in s_testTypes) {
+ /** @type {gluShaderUtil.DataType} */ var type = s_testTypes[typeNdx];
+ typesGroup.addChild(new es3fInstancedRenderingTests.InstancedRenderingCase(gluShaderUtil.getDataTypeName(type), '',
+ es3fInstancedRenderingTests.DrawFunction.FUNCTION_DRAW_ARRAYS_INSTANCED,
+ es3fInstancedRenderingTests.InstancingType.TYPE_ATTRIB_DIVISOR,
+ type,
+ typeTestNumInstances));
+ }
+ };
+
+ es3fInstancedRenderingTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var testName = 'instanced_rendering';
+ var testDescription = 'Instanced Rendering Tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.setRoot(tcuTestCase.newTest(testName, testDescription, null));
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ es3fInstancedRenderingTests.init();
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fInstancedRenderingTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fIntegerStateQueryTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fIntegerStateQueryTests.js
new file mode 100644
index 0000000000..ec5048e4f3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fIntegerStateQueryTests.js
@@ -0,0 +1,2049 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fIntegerStateQueryTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('functional.gles3.es3fApiCase');
+goog.require('modules.shared.glsStateQuery');
+
+goog.scope(function() {
+ var es3fIntegerStateQueryTests = functional.gles3.es3fIntegerStateQueryTests;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var deRandom = framework.delibs.debase.deRandom;
+ var es3fApiCase = functional.gles3.es3fApiCase;
+ var glsStateQuery = modules.shared.glsStateQuery;
+
+ /** @type {string} */ var transformFeedbackTestVertSource = '' +
+ '#version 300 es\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(0.0);\n' +
+ '}\n';
+
+ /** @type {string} */ var transformFeedbackTestFragSource = '' +
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ /** @type {string} */ var testVertSource = '' +
+ '#version 300 es\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(0.0);\n' +
+ '}\n';
+
+ /** @type {string} */ var testFragSource = '' +
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.TransformFeedbackTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {WebGLTransformFeedback} */ this.m_transformfeedback;
+ };
+
+ es3fIntegerStateQueryTests.TransformFeedbackTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.TransformFeedbackTestCase.prototype.constructor = es3fIntegerStateQueryTests.TransformFeedbackTestCase;
+
+ es3fIntegerStateQueryTests.TransformFeedbackTestCase.prototype.testTransformFeedback = function() {
+ throw new Error('This method should be implemented by child classes.');
+ };
+
+ es3fIntegerStateQueryTests.TransformFeedbackTestCase.prototype.test = function() {
+ this.beforeTransformFeedbackTest(); // [dag] added this as there is no other way this method would be called.
+
+ this.m_transformfeedback = gl.createTransformFeedback();
+
+ /** @type {WebGLShader} */ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(shaderVert, transformFeedbackTestVertSource);
+ gl.compileShader(shaderVert);
+
+ var compileStatus = /** @type {boolean} */ (gl.getShaderParameter(shaderVert, gl.COMPILE_STATUS));
+ glsStateQuery.compare(compileStatus, true);
+
+ /** @type {WebGLShader} */ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(shaderFrag, transformFeedbackTestFragSource);
+ gl.compileShader(shaderFrag);
+
+ compileStatus = /** @type {boolean} */ (gl.getShaderParameter(shaderFrag, gl.COMPILE_STATUS));
+ glsStateQuery.compare(compileStatus, true);
+
+ /** @type {WebGLProgram} */ var shaderProg = gl.createProgram();
+ gl.attachShader(shaderProg, shaderVert);
+ gl.attachShader(shaderProg, shaderFrag);
+ /** @type {Array<string>} */ var transform_feedback_outputs = ['gl_Position'];
+ gl.transformFeedbackVaryings(shaderProg, transform_feedback_outputs, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram(shaderProg);
+
+ var linkStatus = /** @type {boolean} */ (gl.getProgramParameter(shaderProg, gl.LINK_STATUS));
+ glsStateQuery.compare(linkStatus, true);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, this.m_transformfeedback);
+
+
+ /** @type {WebGLBuffer} */ var feedbackBufferId = gl.createBuffer();
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, feedbackBufferId);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, new Float32Array(16), gl.DYNAMIC_READ);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, feedbackBufferId);
+
+ gl.useProgram(shaderProg);
+
+ this.testTransformFeedback();
+
+ gl.useProgram(null);
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+ gl.deleteTransformFeedback(this.m_transformfeedback);
+ gl.deleteBuffer(feedbackBufferId);
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(shaderProg);
+
+ this.afterTransformFeedbackTest(); // [dag] added this as there is no other way this method would be called.
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fIntegerStateQueryTests.TransformFeedbackTestCase}
+ * @param {string} name
+ */
+ es3fIntegerStateQueryTests.TransformFeedbackBindingTestCase = function(name) {
+ es3fIntegerStateQueryTests.TransformFeedbackTestCase.call(this, name, 'GL_TRANSFORM_FEEDBACK_BINDING');
+ };
+
+ es3fIntegerStateQueryTests.TransformFeedbackBindingTestCase.prototype = Object.create(es3fIntegerStateQueryTests.TransformFeedbackTestCase.prototype);
+ es3fIntegerStateQueryTests.TransformFeedbackBindingTestCase.prototype.constructor = es3fIntegerStateQueryTests.TransformFeedbackBindingTestCase;
+
+
+ es3fIntegerStateQueryTests.TransformFeedbackBindingTestCase.prototype.beforeTransformFeedbackTest = function() {
+ this.check(glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_BINDING, null), 'beforeTransformFeedbackTest');
+ };
+
+ es3fIntegerStateQueryTests.TransformFeedbackBindingTestCase.prototype.testTransformFeedback = function() {
+ this.check(glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_BINDING, this.m_transformfeedback), 'testTransformFeedback');
+ };
+
+ es3fIntegerStateQueryTests.TransformFeedbackBindingTestCase.prototype.afterTransformFeedbackTest = function() {
+ this.check(glsStateQuery.verify(gl.TRANSFORM_FEEDBACK_BINDING, null), 'afterTransformFeedbackTest');
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} targetName
+ * @param {number} minValue
+ */
+ es3fIntegerStateQueryTests.ConstantMinimumValueTestCase = function(name, description, targetName, minValue) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_targetName = targetName;
+ /** @type {number} */ this.m_minValue = minValue;
+ };
+
+ es3fIntegerStateQueryTests.ConstantMinimumValueTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.ConstantMinimumValueTestCase.prototype.constructor = es3fIntegerStateQueryTests.ConstantMinimumValueTestCase;
+
+ es3fIntegerStateQueryTests.ConstantMinimumValueTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verifyGreaterOrEqual(this.m_targetName, this.m_minValue), 'Fail');
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} targetName
+ * @param {number} minValue
+ */
+ es3fIntegerStateQueryTests.ConstantMaximumValueTestCase = function(name, description, targetName, minValue) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_targetName = targetName;
+ /** @type {number} */ this.m_minValue = minValue;
+ };
+
+ es3fIntegerStateQueryTests.ConstantMaximumValueTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.ConstantMaximumValueTestCase.prototype.constructor = es3fIntegerStateQueryTests.ConstantMaximumValueTestCase;
+
+ es3fIntegerStateQueryTests.ConstantMaximumValueTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verifyLessOrEqual(this.m_targetName, this.m_minValue), 'Fail');
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.SampleBuffersTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.SampleBuffersTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.SampleBuffersTestCase.prototype.constructor = es3fIntegerStateQueryTests.SampleBuffersTestCase;
+
+ es3fIntegerStateQueryTests.SampleBuffersTestCase.prototype.test = function() {
+ /** @type {number} */ var expectedSampleBuffers = (/** @type {number} */ (gl.getParameter(gl.SAMPLES)) > 1) ? 1 : 0;
+
+ bufferedLogToConsole('Sample count is ' + expectedSampleBuffers + ', expecting GL_SAMPLE_BUFFERS to be ' + expectedSampleBuffers);
+
+ this.check(glsStateQuery.verify(gl.SAMPLE_BUFFERS, expectedSampleBuffers));
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.SamplesTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.SamplesTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.SamplesTestCase.prototype.constructor = es3fIntegerStateQueryTests.SamplesTestCase;
+
+ es3fIntegerStateQueryTests.SamplesTestCase.prototype.test = function() {
+ var numSamples = /** @type {number} */ (gl.getParameter(gl.SAMPLES));
+ // MSAA?
+ if (numSamples > 1) {
+ bufferedLogToConsole('Sample count is ' + numSamples);
+
+ this.check(glsStateQuery.verify(gl.SAMPLES, numSamples));
+ } else {
+ /** @type {Array<number>} */ var validSamples = [0, 1];
+
+ bufferedLogToConsole('Expecting GL_SAMPLES to be 0 or 1');
+
+ this.check(glsStateQuery.verifyAnyOf(gl.SAMPLES, validSamples));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} targetName
+ */
+ es3fIntegerStateQueryTests.HintTestCase = function(name, description, targetName) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_targetName = targetName;
+ };
+
+ es3fIntegerStateQueryTests.HintTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.HintTestCase.prototype.constructor = es3fIntegerStateQueryTests.HintTestCase;
+
+ es3fIntegerStateQueryTests.HintTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(this.m_targetName, gl.DONT_CARE));
+
+ gl.hint(this.m_targetName, gl.NICEST);
+ this.check(glsStateQuery.verify(this.m_targetName, gl.NICEST));
+
+ gl.hint(this.m_targetName, gl.FASTEST);
+ this.check(glsStateQuery.verify(this.m_targetName, gl.FASTEST));
+
+ gl.hint(this.m_targetName, gl.DONT_CARE);
+ this.check(glsStateQuery.verify(this.m_targetName, gl.DONT_CARE));
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.DepthFuncTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.DepthFuncTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.DepthFuncTestCase.prototype.constructor = es3fIntegerStateQueryTests.DepthFuncTestCase;
+
+ es3fIntegerStateQueryTests.DepthFuncTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(gl.DEPTH_FUNC, gl.LESS));
+
+ /** @type {Array<number>} */ var depthFunctions = [gl.NEVER, gl.ALWAYS, gl.LESS, gl.LEQUAL, gl.EQUAL, gl.GREATER, gl.GEQUAL, gl.NOTEQUAL];
+ for (var ndx = 0; ndx < depthFunctions.length; ndx++) {
+ gl.depthFunc(depthFunctions[ndx]);
+
+ this.check(glsStateQuery.verify(gl.DEPTH_FUNC, depthFunctions[ndx]));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.CullFaceTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.CullFaceTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.CullFaceTestCase.prototype.constructor = es3fIntegerStateQueryTests.CullFaceTestCase;
+
+ es3fIntegerStateQueryTests.CullFaceTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(gl.CULL_FACE_MODE, gl.BACK));
+
+ /** @type {Array<number>} */ var cullFaces = [gl.FRONT, gl.BACK, gl.FRONT_AND_BACK];
+ for (var ndx = 0; ndx < cullFaces.length; ndx++) {
+ gl.cullFace(cullFaces[ndx]);
+
+ this.check(glsStateQuery.verify(gl.CULL_FACE_MODE, cullFaces[ndx]));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.FrontFaceTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.FrontFaceTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.FrontFaceTestCase.prototype.constructor = es3fIntegerStateQueryTests.FrontFaceTestCase;
+
+ es3fIntegerStateQueryTests.FrontFaceTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(gl.FRONT_FACE, gl.CCW));
+
+ /** @type {Array<number>} */ var frontFaces = [gl.CW, gl.CCW];
+ for (var ndx = 0; ndx < frontFaces.length; ndx++) {
+ gl.frontFace(frontFaces[ndx]);
+
+ this.check(glsStateQuery.verify(gl.FRONT_FACE, frontFaces[ndx]));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.ViewPortTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.ViewPortTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.ViewPortTestCase.prototype.constructor = es3fIntegerStateQueryTests.ViewPortTestCase;
+
+ es3fIntegerStateQueryTests.ViewPortTestCase.prototype.test = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0xabcdef);
+
+ var maxViewportDimensions = /** @type {Array<number>} */ (gl.getParameter(gl.MAX_VIEWPORT_DIMS));
+
+ // verify initial value of first two values
+ this.check(glsStateQuery.verify(gl.VIEWPORT, new Int32Array([0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight])));
+
+ /** @type {number} */ var numIterations = 120;
+ for (var i = 0; i < numIterations; ++i) {
+ /** @type {number} */ var x = rnd.getInt(-64000, 64000);
+ /** @type {number} */ var y = rnd.getInt(-64000, 64000);
+ /** @type {number} */ var width = rnd.getInt(0, maxViewportDimensions[0]);
+ /** @type {number} */ var height = rnd.getInt(0, maxViewportDimensions[1]);
+
+ gl.viewport(x, y, width, height);
+ this.check(glsStateQuery.verify(gl.VIEWPORT, new Int32Array([x, y, width, height])));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.ScissorBoxTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.ScissorBoxTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.ScissorBoxTestCase.prototype.constructor = es3fIntegerStateQueryTests.ScissorBoxTestCase;
+
+ es3fIntegerStateQueryTests.ScissorBoxTestCase.prototype.test = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0xabcdef);
+
+ // verify initial value of first two values
+ this.check(glsStateQuery.verifyMask(gl.SCISSOR_BOX, [0, 0, 0, 0], [true, true, false, false]));
+
+ /** @type {number} */ var numIterations = 120;
+ for (var i = 0; i < numIterations; ++i) {
+ /** @type {number} */ var left = rnd.getInt(-64000, 64000);
+ /** @type {number} */ var bottom = rnd.getInt(-64000, 64000);
+ /** @type {number} */ var width = rnd.getInt(0, 64000);
+ /** @type {number} */ var height = rnd.getInt(0, 64000);
+
+ gl.scissor(left, bottom, width, height);
+ this.check(glsStateQuery.verify(gl.SCISSOR_BOX, new Int32Array([left, bottom, width, height])));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.MaxViewportDimsTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.MaxViewportDimsTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.MaxViewportDimsTestCase.prototype.constructor = es3fIntegerStateQueryTests.MaxViewportDimsTestCase;
+
+ es3fIntegerStateQueryTests.MaxViewportDimsTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verifyGreaterOrEqual(gl.MAX_VIEWPORT_DIMS, [gl.drawingBufferWidth, gl.drawingBufferHeight]));
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} testTargetName
+ */
+ es3fIntegerStateQueryTests.StencilRefTestCase = function(name, description, testTargetName) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_testTargetName = testTargetName;
+ };
+
+ es3fIntegerStateQueryTests.StencilRefTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.StencilRefTestCase.prototype.constructor = es3fIntegerStateQueryTests.StencilRefTestCase;
+
+ es3fIntegerStateQueryTests.StencilRefTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(this.m_testTargetName, 0));
+
+ var stencilBits = /** @type {number} */ (gl.getParameter(gl.STENCIL_BITS));
+
+ for (var stencilBit = 0; stencilBit < stencilBits; ++stencilBit) {
+ /** @type {number} */ var ref = 1 << stencilBit;
+
+ gl.stencilFunc(gl.ALWAYS, ref, 0); // mask should not affect the REF
+
+ this.check(glsStateQuery.verify(this.m_testTargetName, ref));
+
+ gl.stencilFunc(gl.ALWAYS, ref, ref);
+
+ this.check(glsStateQuery.verify(this.m_testTargetName, ref));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} testTargetName
+ * @param {number} stencilFuncTargetFace
+ */
+ es3fIntegerStateQueryTests.StencilRefSeparateTestCase = function(name, description, testTargetName, stencilFuncTargetFace) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_testTargetName = testTargetName;
+ /** @type {number} */ this.m_stencilFuncTargetFace = stencilFuncTargetFace;
+ };
+
+ es3fIntegerStateQueryTests.StencilRefSeparateTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.StencilRefSeparateTestCase.prototype.constructor = es3fIntegerStateQueryTests.StencilRefSeparateTestCase;
+
+ es3fIntegerStateQueryTests.StencilRefSeparateTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(this.m_testTargetName, 0));
+
+ var stencilBits = /** @type {number} */ (gl.getParameter(gl.STENCIL_BITS));
+
+ for (var stencilBit = 0; stencilBit < stencilBits; ++stencilBit) {
+ /** @type {number} */ var ref = 1 << stencilBit;
+
+ gl.stencilFuncSeparate(this.m_stencilFuncTargetFace, gl.ALWAYS, ref, 0);
+
+ this.check(glsStateQuery.verify(this.m_testTargetName, ref));
+
+ gl.stencilFuncSeparate(this.m_stencilFuncTargetFace, gl.ALWAYS, ref, ref);
+
+ this.check(glsStateQuery.verify(this.m_testTargetName, ref));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} stencilOpName
+ */
+ es3fIntegerStateQueryTests.StencilOpTestCase = function(name, description, stencilOpName) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_stencilOpName = stencilOpName;
+ };
+
+ es3fIntegerStateQueryTests.StencilOpTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.StencilOpTestCase.prototype.constructor = es3fIntegerStateQueryTests.StencilOpTestCase;
+
+ es3fIntegerStateQueryTests.StencilOpTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(this.m_stencilOpName, gl.KEEP));
+
+ /** @type {Array<number>} */ var stencilOpValues = [gl.KEEP, gl.ZERO, gl.REPLACE, gl.INCR, gl.DECR, gl.INVERT, gl.INCR_WRAP, gl.DECR_WRAP];
+ for (var ndx = 0; ndx < stencilOpValues.length; ++ndx) {
+ this.setStencilOp(stencilOpValues[ndx]);
+
+ this.check(glsStateQuery.verify(this.m_stencilOpName, stencilOpValues[ndx]));
+ }
+ };
+
+ es3fIntegerStateQueryTests.StencilOpTestCase.prototype.deinit = function() {
+ // [dag] need to reset everything once the test is done, otherwise related tests fail
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
+ };
+
+ /**
+ * @param {number} stencilOpValue
+ */
+ es3fIntegerStateQueryTests.StencilOpTestCase.prototype.setStencilOp = function(stencilOpValue) {
+ switch (this.m_stencilOpName) {
+ case gl.STENCIL_FAIL:
+ case gl.STENCIL_BACK_FAIL:
+ gl.stencilOp(stencilOpValue, gl.KEEP, gl.KEEP);
+ break;
+
+ case gl.STENCIL_PASS_DEPTH_FAIL:
+ case gl.STENCIL_BACK_PASS_DEPTH_FAIL:
+ gl.stencilOp(gl.KEEP, stencilOpValue, gl.KEEP);
+ break;
+
+ case gl.STENCIL_PASS_DEPTH_PASS:
+ case gl.STENCIL_BACK_PASS_DEPTH_PASS:
+ gl.stencilOp(gl.KEEP, gl.KEEP, stencilOpValue);
+ break;
+
+ default:
+ throw new Error('should not happen');
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fIntegerStateQueryTests.StencilOpTestCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} stencilOpName
+ * @param {number} stencilOpFace
+ */
+ es3fIntegerStateQueryTests.StencilOpSeparateTestCase = function(name, description, stencilOpName, stencilOpFace) {
+ es3fIntegerStateQueryTests.StencilOpTestCase.call(this, name, description, stencilOpName);
+ /** @type {number} */ this.m_stencilOpName = stencilOpName;
+ /** @type {number} */ this.m_stencilOpFace = stencilOpFace;
+ };
+
+ es3fIntegerStateQueryTests.StencilOpSeparateTestCase.prototype = Object.create(es3fIntegerStateQueryTests.StencilOpTestCase.prototype);
+ es3fIntegerStateQueryTests.StencilOpSeparateTestCase.prototype.constructor = es3fIntegerStateQueryTests.StencilOpSeparateTestCase;
+
+ es3fIntegerStateQueryTests.StencilOpSeparateTestCase.prototype.test = function() {};
+
+ /**
+ * @param {number} stencilOpValue
+ */
+ es3fIntegerStateQueryTests.StencilOpSeparateTestCase.prototype.setStencilOp = function(stencilOpValue) {
+ switch (this.m_stencilOpName) {
+ case gl.STENCIL_FAIL:
+ case gl.STENCIL_BACK_FAIL:
+ gl.stencilOpSeparate(this.m_stencilOpFace, stencilOpValue, gl.KEEP, gl.KEEP);
+ break;
+
+ case gl.STENCIL_PASS_DEPTH_FAIL:
+ case gl.STENCIL_BACK_PASS_DEPTH_FAIL:
+ gl.stencilOpSeparate(this.m_stencilOpFace, gl.KEEP, stencilOpValue, gl.KEEP);
+ break;
+
+ case gl.STENCIL_PASS_DEPTH_PASS:
+ case gl.STENCIL_BACK_PASS_DEPTH_PASS:
+ gl.stencilOpSeparate(this.m_stencilOpFace, gl.KEEP, gl.KEEP, stencilOpValue);
+ break;
+
+ default:
+ throw new Error('should not happen');
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.StencilFuncTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.StencilFuncTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.StencilFuncTestCase.prototype.constructor = es3fIntegerStateQueryTests.StencilFuncTestCase;
+
+ es3fIntegerStateQueryTests.StencilFuncTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(gl.STENCIL_FUNC, gl.ALWAYS));
+
+ /** @type {Array<number>} */ var stencilfuncValues = [gl.NEVER, gl.ALWAYS, gl.LESS, gl.LEQUAL, gl.EQUAL, gl.GEQUAL, gl.GREATER, gl.NOTEQUAL];
+
+ for (var ndx = 0; ndx < stencilfuncValues.length; ++ndx) {
+ gl.stencilFunc(stencilfuncValues[ndx], 0, 0);
+
+ this.check(glsStateQuery.verify(gl.STENCIL_FUNC, stencilfuncValues[ndx]));
+
+ this.check(glsStateQuery.verify(gl.STENCIL_BACK_FUNC, stencilfuncValues[ndx]));
+ }
+ };
+
+ es3fIntegerStateQueryTests.StencilFuncTestCase.prototype.deinit = function() {
+ // [dag] reset stencilFunc to ALWAYS
+ gl.stencilFunc(gl.ALWAYS, 0, 0);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} stencilFuncName
+ * @param {number} stencilFuncFace
+ */
+ es3fIntegerStateQueryTests.StencilFuncSeparateTestCase = function(name, description, stencilFuncName, stencilFuncFace) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_stencilFuncName = stencilFuncName;
+ /** @type {number} */ this.m_stencilFuncFace = stencilFuncFace;
+ };
+
+ es3fIntegerStateQueryTests.StencilFuncSeparateTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.StencilFuncSeparateTestCase.prototype.constructor = es3fIntegerStateQueryTests.StencilFuncSeparateTestCase;
+
+ es3fIntegerStateQueryTests.StencilFuncSeparateTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(this.m_stencilFuncName, gl.ALWAYS));
+
+ /** @type {Array<number>} */ var stencilfuncValues = [gl.NEVER, gl.ALWAYS, gl.LESS, gl.LEQUAL, gl.EQUAL, gl.GEQUAL, gl.GREATER, gl.NOTEQUAL];
+
+ for (var ndx = 0; ndx < stencilfuncValues.length; ++ndx) {
+ gl.stencilFuncSeparate(this.m_stencilFuncFace, stencilfuncValues[ndx], 0, 0);
+
+ this.check(glsStateQuery.verify(this.m_stencilFuncName, stencilfuncValues[ndx]));
+ }
+ };
+
+ es3fIntegerStateQueryTests.StencilFuncSeparateTestCase.prototype.deinit = function() {
+ // [dag] reset the stencil func
+ gl.stencilFuncSeparate(this.m_stencilFuncFace, gl.ALWAYS, 0, 0);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} testTargetName
+ */
+ es3fIntegerStateQueryTests.StencilMaskTestCase = function(name, description, testTargetName) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_testTargetName = testTargetName;
+ };
+
+ es3fIntegerStateQueryTests.StencilMaskTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.StencilMaskTestCase.prototype.constructor = es3fIntegerStateQueryTests.StencilMaskTestCase;
+
+ es3fIntegerStateQueryTests.StencilMaskTestCase.prototype.test = function() {
+ var stencilBits = /** @type {number} */ (gl.getParameter(gl.STENCIL_BITS));
+
+ this.check(glsStateQuery.verify(this.m_testTargetName, stencilBits));
+
+ for (var stencilBit = 0; stencilBit < stencilBits; ++stencilBit) {
+ /** @type {number} */ var mask = 1 << stencilBit;
+
+ gl.stencilFunc(gl.ALWAYS, 0, mask);
+
+ this.check(glsStateQuery.verify(this.m_testTargetName, mask));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} testTargetName
+ * @param {number} stencilFuncTargetFace
+ */
+ es3fIntegerStateQueryTests.StencilMaskSeparateTestCase = function(name, description, testTargetName, stencilFuncTargetFace) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_testTargetName = testTargetName;
+ /** @type {number} */ this.m_stencilFuncTargetFace = stencilFuncTargetFace;
+ };
+
+ es3fIntegerStateQueryTests.StencilMaskSeparateTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.StencilMaskSeparateTestCase.prototype.constructor = es3fIntegerStateQueryTests.StencilMaskSeparateTestCase;
+
+ es3fIntegerStateQueryTests.StencilMaskSeparateTestCase.prototype.test = function() {
+ var stencilBits = /** @type {number} */ (gl.getParameter(gl.STENCIL_BITS));
+
+ this.check(glsStateQuery.verify(this.m_testTargetName, stencilBits));
+
+ for (var stencilBit = 0; stencilBit < stencilBits; ++stencilBit) {
+ /** @type {number} */ var mask = 1 << stencilBit;
+
+ gl.stencilFuncSeparate(this.m_stencilFuncTargetFace, gl.ALWAYS, 0, mask);
+
+ this.check(glsStateQuery.verify(this.m_testTargetName, mask));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} testTargetName
+ */
+ es3fIntegerStateQueryTests.StencilWriteMaskTestCase = function(name, description, testTargetName) {
+ /** @type {number} */ this.m_testTargetName = testTargetName;
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.StencilWriteMaskTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.StencilWriteMaskTestCase.prototype.constructor = es3fIntegerStateQueryTests.StencilWriteMaskTestCase;
+
+ es3fIntegerStateQueryTests.StencilWriteMaskTestCase.prototype.test = function() {
+ var stencilBits = /** @type {number} */ (gl.getParameter(gl.STENCIL_BITS));
+
+ for (var stencilBit = 0; stencilBit < stencilBits; ++stencilBit) {
+ /** @type {number} */ var mask = 1 << stencilBit;
+
+ gl.stencilMask(mask);
+
+ this.check(glsStateQuery.verify(this.m_testTargetName, mask));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} testTargetName
+ * @param {number} stencilTargetFace
+ */
+ es3fIntegerStateQueryTests.StencilWriteMaskSeparateTestCase = function(name, description, testTargetName, stencilTargetFace) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_testTargetName = testTargetName;
+ /** @type {number} */ this.m_stencilTargetFace = stencilTargetFace;
+ };
+
+ es3fIntegerStateQueryTests.StencilWriteMaskSeparateTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.StencilWriteMaskSeparateTestCase.prototype.constructor = es3fIntegerStateQueryTests.StencilWriteMaskSeparateTestCase;
+
+ es3fIntegerStateQueryTests.StencilWriteMaskSeparateTestCase.prototype.test = function() {
+ var stencilBits = /** @type {number} */ (gl.getParameter(gl.STENCIL_BITS));
+
+ for (var stencilBit = 0; stencilBit < stencilBits; ++stencilBit) {
+ /** @type {number} */ var mask = 1 << stencilBit;
+
+ gl.stencilMaskSeparate(this.m_stencilTargetFace, mask);
+
+ this.check(glsStateQuery.verify(this.m_testTargetName, mask));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} testTargetName
+ * @param {number} initialValue
+ */
+ es3fIntegerStateQueryTests.PixelStoreTestCase = function(name, description, testTargetName, initialValue) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_testTargetName = testTargetName;
+ /** @type {number} */ this.m_initialValue = initialValue;
+ };
+
+ es3fIntegerStateQueryTests.PixelStoreTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.PixelStoreTestCase.prototype.constructor = es3fIntegerStateQueryTests.PixelStoreTestCase;
+
+ es3fIntegerStateQueryTests.PixelStoreTestCase.prototype.test = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0xabcdef);
+
+ this.check(glsStateQuery.verify(this.m_testTargetName, this.m_initialValue));
+
+ /** @type {number} */ var numIterations = 120;
+ for (var i = 0; i < numIterations; ++i) {
+ /** @type {number} */ var referenceValue = rnd.getInt(0, 64000);
+
+ gl.pixelStorei(this.m_testTargetName, referenceValue);
+
+ this.check(glsStateQuery.verify(this.m_testTargetName, referenceValue));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} testTargetName
+ */
+ es3fIntegerStateQueryTests.PixelStoreAlignTestCase = function(name, description, testTargetName) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_testTargetName = testTargetName;
+ };
+
+ es3fIntegerStateQueryTests.PixelStoreAlignTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.PixelStoreAlignTestCase.prototype.constructor = es3fIntegerStateQueryTests.PixelStoreAlignTestCase;
+
+ es3fIntegerStateQueryTests.PixelStoreAlignTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(this.m_testTargetName, 4));
+
+ /** @type {Array<number>} */ var alignments = [1, 2, 4, 8];
+
+ for (var ndx = 0; ndx < alignments.length; ++ndx) {
+ /** @type {number} */ var referenceValue = alignments[ndx];
+
+ gl.pixelStorei(this.m_testTargetName, referenceValue);
+
+ this.check(glsStateQuery.verify(this.m_testTargetName, referenceValue));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} testTargetName
+ * @param {number} initialValue
+ */
+ es3fIntegerStateQueryTests.BlendFuncTestCase = function(name, description, testTargetName) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_testTargetName = testTargetName;
+ };
+
+ es3fIntegerStateQueryTests.BlendFuncTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.BlendFuncTestCase.prototype.constructor = es3fIntegerStateQueryTests.BlendFuncTestCase;
+
+ es3fIntegerStateQueryTests.BlendFuncTestCase.prototype.test = function() {
+ /** @type {Array<number>} */ var blendFuncValues = [
+ gl.ZERO, gl.ONE, gl.SRC_COLOR, gl.ONE_MINUS_SRC_COLOR, gl.DST_COLOR, gl.ONE_MINUS_DST_COLOR,
+ gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.DST_ALPHA, gl.ONE_MINUS_DST_ALPHA, gl.CONSTANT_COLOR,
+ gl.ONE_MINUS_CONSTANT_COLOR, gl.CONSTANT_ALPHA, gl.ONE_MINUS_CONSTANT_ALPHA,
+ gl.SRC_ALPHA_SATURATE
+ ];
+
+ for (var ndx = 0; ndx < blendFuncValues.length; ++ndx) {
+ /** @type {number} */ var referenceValue = blendFuncValues[ndx];
+
+ this.setBlendFunc(referenceValue);
+
+ this.check(glsStateQuery.verify(this.m_testTargetName, referenceValue));
+ }};
+
+ /**
+ * @param {number} func
+ */
+ es3fIntegerStateQueryTests.BlendFuncTestCase.prototype.setBlendFunc = function(func) {
+ switch (this.m_testTargetName) {
+ case gl.BLEND_SRC_RGB:
+ case gl.BLEND_SRC_ALPHA:
+ gl.blendFunc(func, gl.ZERO);
+ break;
+
+ case gl.BLEND_DST_RGB:
+ case gl.BLEND_DST_ALPHA:
+ gl.blendFunc(gl.ZERO, func);
+ break;
+
+ default:
+ throw new Error('should not happen');
+ }
+ };
+
+ es3fIntegerStateQueryTests.BlendFuncTestCase.prototype.deinit = function() {
+ gl.blendFunc(gl.ONE, gl.ZERO);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fIntegerStateQueryTests.BlendFuncTestCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} testTargetName
+ * @param {number} initialValue
+ */
+ es3fIntegerStateQueryTests.BlendFuncSeparateTestCase = function(name, description, testTargetName) {
+ es3fIntegerStateQueryTests.BlendFuncTestCase.call(this, name, description, testTargetName);
+ /** @type {number} */ this.m_testTargetName = testTargetName;
+ };
+
+ es3fIntegerStateQueryTests.BlendFuncSeparateTestCase.prototype = Object.create(es3fIntegerStateQueryTests.BlendFuncTestCase.prototype);
+ es3fIntegerStateQueryTests.BlendFuncSeparateTestCase.prototype.constructor = es3fIntegerStateQueryTests.BlendFuncSeparateTestCase;
+
+ /**
+ * @param {number} func
+ */
+ es3fIntegerStateQueryTests.BlendFuncSeparateTestCase.prototype.setBlendFunc = function(func) {
+ switch (this.m_testTargetName) {
+ case gl.BLEND_SRC_RGB:
+ gl.blendFuncSeparate(func, gl.ZERO, gl.ZERO, gl.ZERO);
+ break;
+
+ case gl.BLEND_DST_RGB:
+ gl.blendFuncSeparate(gl.ZERO, func, gl.ZERO, gl.ZERO);
+ break;
+
+ case gl.BLEND_SRC_ALPHA:
+ gl.blendFuncSeparate(gl.ZERO, gl.ZERO, func, gl.ZERO);
+ break;
+
+ case gl.BLEND_DST_ALPHA:
+ gl.blendFuncSeparate(gl.ZERO, gl.ZERO, gl.ZERO, func);
+ break;
+
+ default:
+ throw new Error('should not happen');
+ }
+ };
+
+ es3fIntegerStateQueryTests.BlendFuncSeparateTestCase.prototype.deinit = function() {
+ gl.blendFuncSeparate(gl.ONE, gl.ZERO, gl.ONE, gl.ZERO);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} testTargetName
+ * @param {number} initialValue
+ */
+ es3fIntegerStateQueryTests.BlendEquationTestCase = function(name, description, testTargetName, initialValue) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_testTargetName = testTargetName;
+ /** @type {number} */ this.m_initialValue = initialValue;
+ };
+
+ es3fIntegerStateQueryTests.BlendEquationTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.BlendEquationTestCase.prototype.constructor = es3fIntegerStateQueryTests.BlendEquationTestCase;
+
+ es3fIntegerStateQueryTests.BlendEquationTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(this.m_testTargetName, this.m_initialValue));
+
+ /** @type {Array<number>} */ var blendFuncValues = [gl.FUNC_ADD, gl.FUNC_SUBTRACT, gl.FUNC_REVERSE_SUBTRACT, gl.MIN, gl.MAX];
+
+ for (var ndx = 0; ndx < blendFuncValues.length; ++ndx) {
+ /** @type {number} */ var referenceValue = blendFuncValues[ndx];
+
+ this.setBlendEquation(referenceValue);
+
+ this.check(glsStateQuery.verify(this.m_testTargetName, referenceValue));
+ }
+ };
+
+ /**
+ * @param {number} equation
+ */
+ es3fIntegerStateQueryTests.BlendEquationTestCase.prototype.setBlendEquation = function(equation) {
+ gl.blendEquation(equation);
+ };
+
+ es3fIntegerStateQueryTests.BlendEquationTestCase.prototype.deinit = function() {
+ gl.blendEquation(this.m_initialValue);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fIntegerStateQueryTests.BlendEquationTestCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} testTargetName
+ * @param {number} initialValue
+ */
+ es3fIntegerStateQueryTests.BlendEquationSeparateTestCase = function(name, description, testTargetName, initialValue) {
+ es3fIntegerStateQueryTests.BlendEquationTestCase.call(this, name, description, testTargetName, initialValue);
+ /** @type {number} */ this.m_testTargetName = testTargetName;
+ /** @type {number} */ this.m_initialValue = initialValue;
+ };
+
+ es3fIntegerStateQueryTests.BlendEquationSeparateTestCase.prototype = Object.create(es3fIntegerStateQueryTests.BlendEquationTestCase.prototype);
+ es3fIntegerStateQueryTests.BlendEquationSeparateTestCase.prototype.constructor = es3fIntegerStateQueryTests.BlendEquationSeparateTestCase;
+
+ /**
+ * @param {number} equation
+ */
+ es3fIntegerStateQueryTests.BlendEquationSeparateTestCase.prototype.setBlendEquation = function(equation) {
+ switch (this.m_testTargetName) {
+ case gl.BLEND_EQUATION_RGB:
+ gl.blendEquationSeparate(equation, gl.FUNC_ADD);
+ break;
+
+ case gl.BLEND_EQUATION_ALPHA:
+ gl.blendEquationSeparate(gl.FUNC_ADD, equation);
+ break;
+
+ default:
+ throw new Error('should not happen');
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} testTargetName
+ * @param {number} minValue
+ */
+ es3fIntegerStateQueryTests.ImplementationArrayTestCase = function(name, description, testTargetName, minValue) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_testTargetName = testTargetName;
+ /** @type {number} */ this.m_minValue = minValue;
+ };
+
+ es3fIntegerStateQueryTests.ImplementationArrayTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.ImplementationArrayTestCase.prototype.constructor = es3fIntegerStateQueryTests.ImplementationArrayTestCase;
+
+ es3fIntegerStateQueryTests.ImplementationArrayTestCase.prototype.test = function() {
+ if (!framework.opengl.gluTextureUtil.enableCompressedTextureETC()) {
+ debug('Skipping ETC2 texture format tests: no support for WEBGL_compressed_texture_etc');
+ return;
+ }
+
+ var queryResult = /** @type {Array<number>} */ (gl.getParameter(this.m_testTargetName));
+ this.check(glsStateQuery.compare(queryResult.length, this.m_minValue));
+
+ /** @type {Array<number>} */ var textureFormats = [
+ gl.COMPRESSED_R11_EAC, gl.COMPRESSED_SIGNED_R11_EAC, gl.COMPRESSED_RG11_EAC, gl.COMPRESSED_SIGNED_RG11_EAC, gl.COMPRESSED_RGB8_ETC2, gl.COMPRESSED_SRGB8_ETC2,
+ gl.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, gl.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, gl.COMPRESSED_RGBA8_ETC2_EAC, gl.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
+ ];
+
+ for (var ndx = 0; ndx < textureFormats.length; ndx++) {
+ /** @type {number} */ var format = textureFormats[ndx];
+ /** @type {boolean} */ var isInArray = queryResult.indexOf(format) !== -1;
+ this.check(glsStateQuery.compare(isInArray, true));
+ }
+
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.CurrentProgramBindingTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.CurrentProgramBindingTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.CurrentProgramBindingTestCase.prototype.constructor = es3fIntegerStateQueryTests.CurrentProgramBindingTestCase;
+
+ es3fIntegerStateQueryTests.CurrentProgramBindingTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(gl.CURRENT_PROGRAM, null));
+
+ /** @type {WebGLShader} */ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(shaderVert, testVertSource);
+ gl.compileShader(shaderVert);
+ var compileStatus = /** @type {boolean} */ (gl.getShaderParameter(shaderVert, gl.COMPILE_STATUS));
+ this.check(glsStateQuery.compare(compileStatus, true));
+
+ /** @type {WebGLShader} */ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(shaderFrag, testFragSource);
+ gl.compileShader(shaderFrag);
+ compileStatus = /** @type {boolean} */ (gl.getShaderParameter(shaderFrag, gl.COMPILE_STATUS));
+ this.check(glsStateQuery.compare(compileStatus, true));
+
+ /** @type {WebGLProgram} */ var shaderProg = gl.createProgram();
+ gl.attachShader(shaderProg, shaderVert);
+ gl.attachShader(shaderProg, shaderFrag);
+ gl.linkProgram(shaderProg);
+ var linkStatus = /** @type {boolean} */ (gl.getProgramParameter(shaderProg, gl.LINK_STATUS));
+ this.check(glsStateQuery.compare(linkStatus, true));
+
+ gl.useProgram(shaderProg);
+
+ this.check(glsStateQuery.verify(gl.CURRENT_PROGRAM, shaderProg));
+
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(shaderProg);
+
+ this.check(glsStateQuery.verify(gl.CURRENT_PROGRAM, shaderProg));
+
+ gl.useProgram(null);
+ this.check(glsStateQuery.verify(gl.CURRENT_PROGRAM, null));
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.VertexArrayBindingTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.VertexArrayBindingTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.VertexArrayBindingTestCase.prototype.constructor = es3fIntegerStateQueryTests.VertexArrayBindingTestCase;
+
+ es3fIntegerStateQueryTests.VertexArrayBindingTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(gl.VERTEX_ARRAY_BINDING, null));
+
+ /** @type {WebGLVertexArrayObject} */ var vertexArrayObject = gl.createVertexArray();
+
+ gl.bindVertexArray(vertexArrayObject);
+ this.check(glsStateQuery.verify(gl.VERTEX_ARRAY_BINDING, vertexArrayObject));
+
+ gl.deleteVertexArray(vertexArrayObject);
+ this.check(glsStateQuery.verify(gl.VERTEX_ARRAY_BINDING, null));
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} bufferBindingName
+ * @param {number} bufferType
+ */
+ es3fIntegerStateQueryTests.BufferBindingTestCase = function(name, description, bufferBindingName, bufferType) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_bufferBindingName = bufferBindingName;
+ /** @type {number} */ this.m_bufferType = bufferType;
+ };
+
+ es3fIntegerStateQueryTests.BufferBindingTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.BufferBindingTestCase.prototype.constructor = es3fIntegerStateQueryTests.BufferBindingTestCase;
+
+ es3fIntegerStateQueryTests.BufferBindingTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(this.m_bufferBindingName, null));
+
+ /** @type {WebGLBuffer} */ var bufferObject = gl.createBuffer();
+
+ gl.bindBuffer(this.m_bufferType, bufferObject);
+ this.check(glsStateQuery.verify(this.m_bufferBindingName, bufferObject));
+
+ gl.deleteBuffer(bufferObject);
+ this.check(glsStateQuery.verify(this.m_bufferBindingName, null));
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ */
+ es3fIntegerStateQueryTests.ElementArrayBufferBindingTestCase = function(name) {
+ es3fApiCase.ApiCase.call(this, name, 'GL_ELEMENT_ARRAY_BUFFER_BINDING', gl);
+ };
+
+ es3fIntegerStateQueryTests.ElementArrayBufferBindingTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.ElementArrayBufferBindingTestCase.prototype.constructor = es3fIntegerStateQueryTests.ElementArrayBufferBindingTestCase;
+
+ es3fIntegerStateQueryTests.ElementArrayBufferBindingTestCase.prototype.test = function() {
+ // Test with default VAO
+ bufferedLogToConsole('DefaultVAO: Test with default VAO');
+
+ this.check(glsStateQuery.verify(gl.ELEMENT_ARRAY_BUFFER_BINDING, null));
+
+ /** @type {WebGLBuffer} */ var bufferObject = gl.createBuffer();
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferObject);
+ this.check(glsStateQuery.verify(gl.ELEMENT_ARRAY_BUFFER_BINDING, bufferObject));
+
+ gl.deleteBuffer(bufferObject);
+ this.check(glsStateQuery.verify(gl.ELEMENT_ARRAY_BUFFER_BINDING, null));
+
+ // Test with multiple VAOs
+ bufferedLogToConsole('WithVAO: Test with VAO');
+
+ /** @type {Array<WebGLVertexArrayObject>} */ var vaos = [];
+ /** @type {Array<WebGLBuffer>} */ var buffers = [];
+
+ for (var ndx = 0; ndx < 2; ndx++) {
+ vaos[ndx] = gl.createVertexArray();
+ buffers[ndx] = gl.createBuffer();
+ }
+
+ // initial
+ gl.bindVertexArray(vaos[0]);
+ this.check(glsStateQuery.verify(gl.ELEMENT_ARRAY_BUFFER_BINDING, null));
+
+ // after setting
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers[0]);
+ this.check(glsStateQuery.verify(gl.ELEMENT_ARRAY_BUFFER_BINDING, buffers[0]));
+
+ // initial of vao 2
+ gl.bindVertexArray(vaos[1]);
+ this.check(glsStateQuery.verify(gl.ELEMENT_ARRAY_BUFFER_BINDING, null));
+
+ // after setting to 2
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers[1]);
+ this.check(glsStateQuery.verify(gl.ELEMENT_ARRAY_BUFFER_BINDING, buffers[1]));
+
+ // vao 1 still has buffer 1 bound?
+ gl.bindVertexArray(vaos[0]);
+ this.check(glsStateQuery.verify(gl.ELEMENT_ARRAY_BUFFER_BINDING, buffers[0]));
+
+ // deleting clears from bound vaos ...
+ for (var ndx = 0; ndx < 2; ndx++)
+ gl.deleteBuffer(buffers[ndx]);
+ this.check(glsStateQuery.verify(gl.ELEMENT_ARRAY_BUFFER_BINDING, null));
+
+ // ... but does not from non-bound vaos?
+ gl.bindVertexArray(vaos[1]);
+ this.check(glsStateQuery.verify(gl.ELEMENT_ARRAY_BUFFER_BINDING, buffers[1]));
+
+ for (var ndx = 0; ndx < 2; ndx++)
+ gl.deleteVertexArray(vaos[ndx]);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.StencilClearValueTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.StencilClearValueTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.StencilClearValueTestCase.prototype.constructor = es3fIntegerStateQueryTests.StencilClearValueTestCase;
+
+ es3fIntegerStateQueryTests.StencilClearValueTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(gl.STENCIL_CLEAR_VALUE, 0));
+
+ var stencilBits = /** @type {number} */ (gl.getParameter(gl.STENCIL_BITS));
+
+ for (var stencilBit = 0; stencilBit < stencilBits; ++stencilBit) {
+ /** @type {number} */ var ref = 1 << stencilBit;
+
+ gl.clearStencil(ref); // mask should not affect the REF
+
+ this.check(glsStateQuery.verify(gl.STENCIL_CLEAR_VALUE, ref));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.ActiveTextureTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.ActiveTextureTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.ActiveTextureTestCase.prototype.constructor = es3fIntegerStateQueryTests.ActiveTextureTestCase;
+
+ es3fIntegerStateQueryTests.ActiveTextureTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(gl.ACTIVE_TEXTURE, gl.TEXTURE0));
+
+ var textureUnits = /** @type {number} */ (gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS));
+
+ for (var ndx = 0; ndx < textureUnits; ++ndx) {
+ gl.activeTexture(gl.TEXTURE0 + ndx);
+
+ this.check(glsStateQuery.verify(gl.ACTIVE_TEXTURE, gl.TEXTURE0 + ndx));
+ }
+ };
+
+ es3fIntegerStateQueryTests.ActiveTextureTestCase.prototype.deinit = function() {
+ // [dag] reset the state of the context
+ gl.activeTexture(gl.TEXTURE0);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.RenderbufferBindingTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.RenderbufferBindingTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.RenderbufferBindingTestCase.prototype.constructor = es3fIntegerStateQueryTests.RenderbufferBindingTestCase;
+
+ es3fIntegerStateQueryTests.RenderbufferBindingTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(gl.RENDERBUFFER_BINDING, null));
+
+ /** @type {WebGLRenderbuffer} */ var renderBuffer = gl.createRenderbuffer();
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderBuffer);
+
+ this.check(glsStateQuery.verify(gl.RENDERBUFFER_BINDING, renderBuffer));
+
+ gl.deleteRenderbuffer(renderBuffer);
+ this.check(glsStateQuery.verify(gl.RENDERBUFFER_BINDING, null));
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.SamplerObjectBindingTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.SamplerObjectBindingTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.SamplerObjectBindingTestCase.prototype.constructor = es3fIntegerStateQueryTests.SamplerObjectBindingTestCase;
+
+ es3fIntegerStateQueryTests.SamplerObjectBindingTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(gl.SAMPLER_BINDING, null));
+
+ bufferedLogToConsole('SingleUnit: Single unit');
+ /** @type {WebGLSampler} */ var sampler = gl.createSampler();
+
+ gl.bindSampler(0, sampler);
+
+ this.check(glsStateQuery.verify(gl.SAMPLER_BINDING, sampler));
+
+ gl.deleteSampler(sampler);
+ this.check(glsStateQuery.verify(gl.SAMPLER_BINDING, null));
+
+ bufferedLogToConsole('MultipleUnits: Multiple units');
+
+ /** @type {WebGLSampler} */ var samplerA = gl.createSampler();
+ /** @type {WebGLSampler} */ var samplerB = gl.createSampler();
+
+ gl.bindSampler(1, samplerA);
+ gl.bindSampler(2, samplerB);
+
+ this.check(glsStateQuery.verify(gl.SAMPLER_BINDING, null));
+
+ gl.activeTexture(gl.TEXTURE1);
+ this.check(glsStateQuery.verify(gl.SAMPLER_BINDING, samplerA));
+
+ gl.activeTexture(gl.TEXTURE2);
+ this.check(glsStateQuery.verify(gl.SAMPLER_BINDING, samplerB));
+
+ gl.deleteSampler(samplerB);
+ gl.deleteSampler(samplerA);
+ };
+
+ es3fIntegerStateQueryTests.SamplerObjectBindingTestCase.prototype.deinit = function() {
+ gl.activeTexture(gl.TEXTURE0);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} testBindingName
+ * @param {number} textureType
+ */
+ es3fIntegerStateQueryTests.TextureBindingTestCase = function(name, description, testBindingName, textureType) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_testBindingName = testBindingName;
+ /** @type {number} */ this.m_textureType = textureType;
+ };
+
+ es3fIntegerStateQueryTests.TextureBindingTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.TextureBindingTestCase.prototype.constructor = es3fIntegerStateQueryTests.TextureBindingTestCase;
+
+ es3fIntegerStateQueryTests.TextureBindingTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(this.m_testBindingName, null));
+
+ /** @type {WebGLTexture} */ var texture = gl.createTexture();
+
+ gl.bindTexture(this.m_textureType, texture);
+ this.check(glsStateQuery.verify(this.m_testBindingName, texture));
+
+ gl.deleteTexture(texture);
+
+ this.check(glsStateQuery.verify(this.m_testBindingName, null));
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.FrameBufferBindingTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.FrameBufferBindingTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.FrameBufferBindingTestCase.prototype.constructor = es3fIntegerStateQueryTests.FrameBufferBindingTestCase;
+
+ es3fIntegerStateQueryTests.FrameBufferBindingTestCase.prototype.test = function() {
+ this.check(glsStateQuery.verify(gl.DRAW_FRAMEBUFFER_BINDING, null));
+ this.check(glsStateQuery.verify(gl.FRAMEBUFFER_BINDING, null));
+ this.check(glsStateQuery.verify(gl.READ_FRAMEBUFFER_BINDING, null));
+
+ /** @type {WebGLFramebuffer} */ var framebufferId = gl.createFramebuffer();
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebufferId);
+
+ this.check(glsStateQuery.verify(gl.DRAW_FRAMEBUFFER_BINDING, framebufferId));
+ this.check(glsStateQuery.verify(gl.FRAMEBUFFER_BINDING, framebufferId));
+ this.check(glsStateQuery.verify(gl.READ_FRAMEBUFFER_BINDING, framebufferId));
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ this.check(glsStateQuery.verify(gl.DRAW_FRAMEBUFFER_BINDING, null));
+ this.check(glsStateQuery.verify(gl.FRAMEBUFFER_BINDING, null));
+ this.check(glsStateQuery.verify(gl.READ_FRAMEBUFFER_BINDING, null));
+
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, framebufferId);
+
+ this.check(glsStateQuery.verify(gl.DRAW_FRAMEBUFFER_BINDING, null));
+ this.check(glsStateQuery.verify(gl.FRAMEBUFFER_BINDING, null));
+ this.check(glsStateQuery.verify(gl.READ_FRAMEBUFFER_BINDING, framebufferId));
+
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, framebufferId);
+
+ this.check(glsStateQuery.verify(gl.DRAW_FRAMEBUFFER_BINDING, framebufferId));
+ this.check(glsStateQuery.verify(gl.FRAMEBUFFER_BINDING, framebufferId));
+ this.check(glsStateQuery.verify(gl.READ_FRAMEBUFFER_BINDING, framebufferId));
+
+ gl.deleteFramebuffer(framebufferId);
+
+ this.check(glsStateQuery.verify(gl.DRAW_FRAMEBUFFER_BINDING, null));
+ this.check(glsStateQuery.verify(gl.FRAMEBUFFER_BINDING, null));
+ this.check(glsStateQuery.verify(gl.READ_FRAMEBUFFER_BINDING, null));
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.ImplementationColorReadTestCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.ImplementationColorReadTestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.ImplementationColorReadTestCase.prototype.constructor = es3fIntegerStateQueryTests.ImplementationColorReadTestCase;
+
+ es3fIntegerStateQueryTests.ImplementationColorReadTestCase.prototype.test = function() {
+ /** @type {Array<number>} */ var defaultColorTypes = [
+ gl.UNSIGNED_BYTE, gl.BYTE, gl.UNSIGNED_SHORT, gl.SHORT,
+ gl.UNSIGNED_INT, gl.INT, gl.HALF_FLOAT, gl.FLOAT, gl.UNSIGNED_SHORT_5_6_5,
+ gl.UNSIGNED_SHORT_4_4_4_4, gl.UNSIGNED_SHORT_5_5_5_1,
+ gl.UNSIGNED_INT_2_10_10_10_REV, gl.UNSIGNED_INT_10F_11F_11F_REV
+ ];
+
+ /** @type {Array<number>} */ var defaultColorFormats = [
+ gl.RGBA, gl.RGBA_INTEGER, gl.RGB, gl.RGB_INTEGER,
+ gl.RG, gl.RG_INTEGER, gl.RED, gl.RED_INTEGER
+ ];
+
+ /** @type {Array<number>} */ var validColorTypes = [];
+ /** @type {Array<number>} */ var validColorFormats = [];
+
+ // Defined by the spec
+
+ for (var ndx = 0; ndx < defaultColorTypes.length; ++ndx)
+ validColorTypes.push(defaultColorTypes[ndx]);
+ for (var ndx = 0; ndx < defaultColorFormats.length; ++ndx)
+ validColorFormats.push(defaultColorFormats[ndx]);
+
+ // Extensions
+
+ // if (this.m_context.getContextInfo().isExtensionSupported("gl.EXT_texture_format_BGRA8888") ||
+ // this.m_context.getContextInfo().isExtensionSupported("gl.APPLE_texture_format_BGRA8888"))
+ // validColorFormats.push(gl.BGRA);
+ //
+ // if (this.m_context.getContextInfo().isExtensionSupported("gl.EXT_read_format_bgra")) {
+ // validColorFormats.push(gl.BGRA);
+ // validColorTypes.push(gl.UNSIGNED_SHORT_4_4_4_4_REV);
+ // validColorTypes.push(gl.UNSIGNED_SHORT_1_5_5_5_REV);
+ // }
+ //
+ // if (this.m_context.getContextInfo().isExtensionSupported("gl.IMG_read_format")) {
+ // validColorFormats.push(gl.BGRA);
+ // validColorTypes.push(gl.UNSIGNED_SHORT_4_4_4_4_REV);
+ // }
+ //
+ // if (this.m_context.getContextInfo().isExtensionSupported("gl.NV_sRGB_formats")) {
+ // validColorFormats.push(gl.SLUMINANCE_NV);
+ // validColorFormats.push(gl.SLUMINANCE_ALPHA_NV);
+ // }
+ //
+ // if (this.m_context.getContextInfo().isExtensionSupported("gl.NV_bgr")) {
+ // validColorFormats.push(gl.BGR_NV);
+ // }
+
+ this.check(glsStateQuery.verifyAnyOf(gl.IMPLEMENTATION_COLOR_READ_TYPE, validColorTypes));
+ this.check(glsStateQuery.verifyAnyOf(gl.IMPLEMENTATION_COLOR_READ_FORMAT, validColorFormats));
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.ReadBufferCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.ReadBufferCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.ReadBufferCase.prototype.constructor = es3fIntegerStateQueryTests.ReadBufferCase;
+
+ es3fIntegerStateQueryTests.ReadBufferCase.prototype.test = function() {
+ /** @type {Array<number>} */ var validInitialValues = [gl.BACK, gl.NONE];
+ this.check(glsStateQuery.verifyAnyOf(gl.READ_BUFFER, validInitialValues));
+
+ gl.readBuffer(gl.NONE);
+ this.check(glsStateQuery.verify(gl.READ_BUFFER, gl.NONE));
+
+ gl.readBuffer(gl.BACK);
+ this.check(glsStateQuery.verify(gl.READ_BUFFER, gl.BACK));
+
+ // test gl.READ_BUFFER with framebuffers
+
+ /** @type {WebGLFramebuffer} */ var framebufferId = gl.createFramebuffer();
+
+ /** @type {WebGLRenderbuffer} */ var renderbuffer_id = gl.createRenderbuffer();
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer_id);
+
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 128, 128);
+
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, framebufferId);
+
+ gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbuffer_id);
+
+ this.check(glsStateQuery.verify(gl.READ_BUFFER, gl.COLOR_ATTACHMENT0));
+
+ gl.deleteFramebuffer(framebufferId);
+ gl.deleteRenderbuffer(renderbuffer_id);
+
+ this.check(glsStateQuery.verify(gl.READ_BUFFER, gl.BACK));
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fIntegerStateQueryTests.DrawBufferCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ };
+
+ es3fIntegerStateQueryTests.DrawBufferCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.DrawBufferCase.prototype.constructor = es3fIntegerStateQueryTests.DrawBufferCase;
+
+ es3fIntegerStateQueryTests.DrawBufferCase.prototype.test = function() {
+ /** @type {Array<number>} */ var validInitialValues = [gl.BACK, gl.NONE];
+ this.check(glsStateQuery.verifyAnyOf(gl.DRAW_BUFFER0, validInitialValues));
+
+ /** @type {number} */ var bufs = gl.NONE;
+ gl.drawBuffers([bufs]);
+ this.check(glsStateQuery.verify(gl.DRAW_BUFFER0, gl.NONE));
+
+ bufs = gl.BACK;
+ gl.drawBuffers([bufs]);
+ this.check(glsStateQuery.verify(gl.DRAW_BUFFER0, gl.BACK));
+
+ // test gl.DRAW_BUFFER with framebuffers
+
+ /** @type {WebGLFramebuffer} */ var framebufferId = gl.createFramebuffer();
+
+ /** @type {Array<WebGLRenderbuffer>} */ var renderbuffer_ids = [];
+
+ for (var ndx = 0; ndx < 2; ndx++)
+ renderbuffer_ids[ndx] = gl.createRenderbuffer();
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer_ids[0]);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 128, 128);
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer_ids[1]);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 128, 128);
+
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, framebufferId);
+
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbuffer_ids[0]);
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.RENDERBUFFER, renderbuffer_ids[1]);
+
+ // only the initial state the draw buffer for fragment color zero is defined
+ this.check(glsStateQuery.verify(gl.DRAW_BUFFER0, gl.COLOR_ATTACHMENT0));
+
+ /** @type {Array<number>} */ var bufTargets = [gl.NONE, gl.COLOR_ATTACHMENT1];
+ gl.drawBuffers(bufTargets);
+ this.check(glsStateQuery.verify(gl.DRAW_BUFFER0, gl.NONE));
+ this.check(glsStateQuery.verify(gl.DRAW_BUFFER1, gl.COLOR_ATTACHMENT1));
+
+ gl.deleteFramebuffer(framebufferId);
+ gl.deleteRenderbuffer(renderbuffer_ids[0]);
+ gl.deleteRenderbuffer(renderbuffer_ids[1]);
+
+ this.check(glsStateQuery.verify(gl.DRAW_BUFFER0, gl.BACK));
+ };
+
+ // Integer64
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} targetName
+ * @param {number} minValue
+ */
+ es3fIntegerStateQueryTests.ConstantMinimumValue64TestCase = function(name, description, targetName, minValue) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_targetName = targetName;
+ /** @type {number} */ this.m_minValue = minValue;
+ };
+
+ es3fIntegerStateQueryTests.ConstantMinimumValue64TestCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.ConstantMinimumValue64TestCase.prototype.constructor = es3fIntegerStateQueryTests.ConstantMinimumValue64TestCase;
+
+ es3fIntegerStateQueryTests.ConstantMinimumValue64TestCase.prototype.test = function() {
+ this.check(glsStateQuery.verifyGreaterOrEqual(this.m_targetName, this.m_minValue), 'Fail');
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} targetName
+ * @param {number} targetMaxUniformBlocksName
+ * @param {number} targetMaxUniformComponentsName
+ */
+ es3fIntegerStateQueryTests.MaxCombinedStageUniformComponentsCase = function(name, description, targetName, targetMaxUniformBlocksName, targetMaxUniformComponentsName) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {number} */ this.m_targetName = targetName;
+ /** @type {number} */ this.m_targetMaxUniformBlocksName = targetMaxUniformBlocksName;
+ /** @type {number} */ this.m_targetMaxUniformComponentsName = targetMaxUniformComponentsName;
+ };
+
+ es3fIntegerStateQueryTests.MaxCombinedStageUniformComponentsCase.prototype = Object.create(es3fApiCase.ApiCase.prototype);
+ es3fIntegerStateQueryTests.MaxCombinedStageUniformComponentsCase.prototype.constructor = es3fIntegerStateQueryTests.MaxCombinedStageUniformComponentsCase;
+
+ es3fIntegerStateQueryTests.MaxCombinedStageUniformComponentsCase.prototype.test = function() {
+ var uniformBlockSize = /** @type {number} */ (gl.getParameter(gl.MAX_UNIFORM_BLOCK_SIZE));
+ var maxUniformBlocks = /** @type {number} */ (gl.getParameter(this.m_targetMaxUniformBlocksName));
+ var maxUniformComponents = /** @type {number} */ (gl.getParameter(this.m_targetMaxUniformComponentsName));
+
+ // MAX_stage_UNIFORM_BLOCKS * MAX_UNIFORM_BLOCK_SIZE / 4 + MAX_stage_UNIFORM_COMPONENTS
+ /** @type {number} */ var minCombinedUniformComponents = maxUniformBlocks * uniformBlockSize / 4 + maxUniformComponents;
+
+ this.check(glsStateQuery.verifyGreaterOrEqual(this.m_targetName, minCombinedUniformComponents));
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fIntegerStateQueryTests.IntegerStateQueryTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'integers', 'Integer Values');
+ };
+
+ es3fIntegerStateQueryTests.IntegerStateQueryTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fIntegerStateQueryTests.IntegerStateQueryTests.prototype.constructor = es3fIntegerStateQueryTests.IntegerStateQueryTests;
+
+ es3fIntegerStateQueryTests.IntegerStateQueryTests.prototype.init = function() {
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {string} description
+ * @param {number} targetName
+ * @param {number} value
+ */
+ var LimitedStateInteger = function(name, description, targetName, value) {
+ /** @type {string} */ this.name = name;
+ /** @type {string} */ this.description = description;
+ /** @type {number} */ this.targetName = targetName;
+ /** @type {number} */ this.value = value;
+ };
+
+ /** @type {Array<LimitedStateInteger>} */ var implementationMinLimits = [
+ new LimitedStateInteger('subpixel_bits', 'SUBPIXEL_BITS has minimum value of 4', gl.SUBPIXEL_BITS, 4),
+ new LimitedStateInteger('max_3d_texture_size', 'MAX_3D_TEXTURE_SIZE has minimum value of 256', gl.MAX_3D_TEXTURE_SIZE, 256),
+ new LimitedStateInteger('max_texture_size', 'MAX_TEXTURE_SIZE has minimum value of 2048', gl.MAX_TEXTURE_SIZE, 2048),
+ new LimitedStateInteger('max_array_texture_layers', 'MAX_ARRAY_TEXTURE_LAYERS has minimum value of 256', gl.MAX_ARRAY_TEXTURE_LAYERS, 256),
+ new LimitedStateInteger('max_cube_map_texture_size', 'MAX_CUBE_MAP_TEXTURE_SIZE has minimum value of 2048', gl.MAX_CUBE_MAP_TEXTURE_SIZE, 2048),
+ new LimitedStateInteger('max_renderbuffer_size', 'MAX_RENDERBUFFER_SIZE has minimum value of 2048', gl.MAX_RENDERBUFFER_SIZE, 2048),
+ new LimitedStateInteger('max_draw_buffers', 'MAX_DRAW_BUFFERS has minimum value of 4', gl.MAX_DRAW_BUFFERS, 4),
+ new LimitedStateInteger('max_color_attachments', 'MAX_COLOR_ATTACHMENTS has minimum value of 4', gl.MAX_COLOR_ATTACHMENTS, 4),
+ new LimitedStateInteger('max_elements_indices', 'MAX_ELEMENTS_INDICES has minimum value of 0', gl.MAX_ELEMENTS_INDICES, 0),
+ new LimitedStateInteger('max_elements_vertices', 'MAX_ELEMENTS_VERTICES has minimum value of 0', gl.MAX_ELEMENTS_VERTICES, 0),
+ new LimitedStateInteger('max_vertex_attribs', 'MAX_VERTEX_ATTRIBS has minimum value of 16', gl.MAX_VERTEX_ATTRIBS, 16),
+ new LimitedStateInteger('max_vertex_uniform_components', 'MAX_VERTEX_UNIFORM_COMPONENTS has minimum value of 1024', gl.MAX_VERTEX_UNIFORM_COMPONENTS, 1024),
+ new LimitedStateInteger('max_vertex_uniform_vectors', 'MAX_VERTEX_UNIFORM_VECTORS has minimum value of 256', gl.MAX_VERTEX_UNIFORM_VECTORS, 256),
+ new LimitedStateInteger('max_vertex_uniform_blocks', 'MAX_VERTEX_UNIFORM_BLOCKS has minimum value of 12', gl.MAX_VERTEX_UNIFORM_BLOCKS, 12),
+ new LimitedStateInteger('max_vertex_output_components', 'MAX_VERTEX_OUTPUT_COMPONENTS has minimum value of 64', gl.MAX_VERTEX_OUTPUT_COMPONENTS, 64),
+ new LimitedStateInteger('max_vertex_texture_image_units', 'MAX_VERTEX_TEXTURE_IMAGE_UNITS has minimum value of 16', gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS, 16),
+ new LimitedStateInteger('max_fragment_uniform_components', 'MAX_FRAGMENT_UNIFORM_COMPONENTS has minimum value of 896', gl.MAX_FRAGMENT_UNIFORM_COMPONENTS, 896),
+ new LimitedStateInteger('max_fragment_uniform_vectors', 'MAX_FRAGMENT_UNIFORM_VECTORS has minimum value of 224', gl.MAX_FRAGMENT_UNIFORM_VECTORS, 224),
+ new LimitedStateInteger('max_fragment_uniform_blocks', 'MAX_FRAGMENT_UNIFORM_BLOCKS has minimum value of 12', gl.MAX_FRAGMENT_UNIFORM_BLOCKS, 12),
+ new LimitedStateInteger('max_fragment_input_components', 'MAX_FRAGMENT_INPUT_COMPONENTS has minimum value of 60', gl.MAX_FRAGMENT_INPUT_COMPONENTS, 60),
+ new LimitedStateInteger('max_texture_image_units', 'MAX_TEXTURE_IMAGE_UNITS has minimum value of 16', gl.MAX_TEXTURE_IMAGE_UNITS, 16),
+ new LimitedStateInteger('max_program_texel_offset', 'MAX_PROGRAM_TEXEL_OFFSET has minimum value of 7', gl.MAX_PROGRAM_TEXEL_OFFSET, 7),
+ new LimitedStateInteger('max_uniform_buffer_bindings', 'MAX_UNIFORM_BUFFER_BINDINGS has minimum value of 24', gl.MAX_UNIFORM_BUFFER_BINDINGS, 24),
+ new LimitedStateInteger('max_combined_uniform_blocks', 'MAX_COMBINED_UNIFORM_BLOCKS has minimum value of 24', gl.MAX_COMBINED_UNIFORM_BLOCKS, 24),
+ new LimitedStateInteger('max_varying_components', 'MAX_VARYING_COMPONENTS has minimum value of 60', gl.MAX_VARYING_COMPONENTS, 60),
+ new LimitedStateInteger('max_varying_vectors', 'MAX_VARYING_VECTORS has minimum value of 15', gl.MAX_VARYING_VECTORS, 15),
+ new LimitedStateInteger('max_combined_texture_image_units', 'MAX_COMBINED_TEXTURE_IMAGE_UNITS has minimum value of 32', gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS, 32),
+ new LimitedStateInteger('max_transform_feedback_interleaved_components', 'MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS has minimum value of 64', gl.MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, 64),
+ new LimitedStateInteger('max_transform_feedback_separate_attribs', 'MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS has minimum value of 4', gl.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, 4),
+ new LimitedStateInteger('max_transform_feedback_separate_components', 'MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS has minimum value of 4', gl.MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, 4),
+ new LimitedStateInteger('max_samples', 'MAX_SAMPLES has minimum value of 4', gl.MAX_SAMPLES, 4),
+ new LimitedStateInteger('red_bits', 'RED_BITS has minimum value of 0', gl.RED_BITS, 0),
+ new LimitedStateInteger('green_bits', 'GREEN_BITS has minimum value of 0', gl.GREEN_BITS, 0),
+ new LimitedStateInteger('blue_bits', 'BLUE_BITS has minimum value of 0', gl.BLUE_BITS, 0),
+ new LimitedStateInteger('alpha_bits', 'ALPHA_BITS has minimum value of 0', gl.ALPHA_BITS, 0),
+ new LimitedStateInteger('depth_bits', 'DEPTH_BITS has minimum value of 0', gl.DEPTH_BITS, 0),
+ new LimitedStateInteger('stencil_bits', 'STENCIL_BITS has minimum value of 0', gl.STENCIL_BITS, 0)
+ ];
+
+ /** @type {Array<LimitedStateInteger>} */ var implementationMaxLimits = [
+ new LimitedStateInteger('min_program_texel_offset', 'MIN_PROGRAM_TEXEL_OFFSET has maximum value of -8', gl.MIN_PROGRAM_TEXEL_OFFSET, -8),
+ new LimitedStateInteger('uniform_buffer_offset_alignment', 'UNIFORM_BUFFER_OFFSET_ALIGNMENT has minimum value of 1', gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT, 256)
+ ];
+
+ var testCtx = this;
+
+ for (var testNdx = 0; testNdx < implementationMinLimits.length; testNdx++)
+ testCtx.addChild(new es3fIntegerStateQueryTests.ConstantMinimumValueTestCase(implementationMinLimits[testNdx].name, implementationMinLimits[testNdx].description, implementationMinLimits[testNdx].targetName, implementationMinLimits[testNdx].value));
+
+ for (var testNdx = 0; testNdx < implementationMaxLimits.length; testNdx++)
+ testCtx.addChild(new es3fIntegerStateQueryTests.ConstantMaximumValueTestCase(implementationMaxLimits[testNdx].name, implementationMaxLimits[testNdx].description, implementationMaxLimits[testNdx].targetName, implementationMaxLimits[testNdx].value));
+
+ testCtx.addChild(new es3fIntegerStateQueryTests.SampleBuffersTestCase('sample_buffers', 'SAMPLE_BUFFERS'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.SamplesTestCase('samples' , 'SAMPLES'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.HintTestCase('generate_mipmap_hint', 'GENERATE_MIPMAP_HINT', gl.GENERATE_MIPMAP_HINT));
+ testCtx.addChild(new es3fIntegerStateQueryTests.HintTestCase('fragment_shader_derivative_hint', 'FRAGMENT_SHADER_DERIVATIVE_HINT', gl.FRAGMENT_SHADER_DERIVATIVE_HINT));
+ testCtx.addChild(new es3fIntegerStateQueryTests.DepthFuncTestCase('depth_func', 'DEPTH_FUNC'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.CullFaceTestCase('cull_face_mode', 'CULL_FACE_MODE'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.FrontFaceTestCase('front_face_mode', 'FRONT_FACE'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.ViewPortTestCase('viewport', 'VIEWPORT'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.ScissorBoxTestCase('scissor_box', 'SCISSOR_BOX'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.MaxViewportDimsTestCase('max_viewport_dims', 'MAX_VIEWPORT_DIMS'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilRefTestCase('stencil_ref', 'STENCIL_REF', gl.STENCIL_REF));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilRefTestCase('stencil_back_ref', 'STENCIL_BACK_REF', gl.STENCIL_BACK_REF));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilRefSeparateTestCase('stencil_ref_separate', 'STENCIL_REF (separate)', gl.STENCIL_REF, gl.FRONT));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilRefSeparateTestCase('stencil_ref_separate_both', 'STENCIL_REF (separate)', gl.STENCIL_REF, gl.FRONT_AND_BACK));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilRefSeparateTestCase('stencil_back_ref_separate', 'STENCIL_BACK_REF (separate)', gl.STENCIL_BACK_REF, gl.BACK));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilRefSeparateTestCase('stencil_back_ref_separate_both', 'STENCIL_BACK_REF (separate)', gl.STENCIL_BACK_REF, gl.FRONT_AND_BACK));
+
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {string} frontDescription
+ * @param {number} frontTarget
+ * @param {string} backDescription
+ * @param {number} backTarget
+ */
+ var NamedStencilOp = function(name, frontDescription, frontTarget, backDescription, backTarget) {
+ /** @type {string} */ this.name = name;
+ /** @type {string} */ this.frontDescription = frontDescription;
+ /** @type {number} */ this.frontTarget = frontTarget;
+ /** @type {string} */ this.backDescription = backDescription;
+ /** @type {number} */ this.backTarget = backTarget;
+ };
+
+ /** @type {Array<NamedStencilOp>} */ var stencilOps = [
+ new NamedStencilOp('fail', 'STENCIL_FAIL', gl.STENCIL_FAIL, 'STENCIL_BACK_FAIL', gl.STENCIL_BACK_FAIL),
+ new NamedStencilOp('depth_fail', 'STENCIL_PASS_DEPTH_FAIL', gl.STENCIL_PASS_DEPTH_FAIL, 'STENCIL_BACK_PASS_DEPTH_FAIL', gl.STENCIL_BACK_PASS_DEPTH_FAIL),
+ new NamedStencilOp('depth_pass', 'STENCIL_PASS_DEPTH_PASS', gl.STENCIL_PASS_DEPTH_PASS, 'STENCIL_BACK_PASS_DEPTH_PASS', gl.STENCIL_BACK_PASS_DEPTH_PASS)
+ ];
+
+ for (var testNdx = 0; testNdx < stencilOps.length; testNdx++) {
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilOpTestCase('stencil_' + stencilOps[testNdx].name, stencilOps[testNdx].frontDescription, stencilOps[testNdx].frontTarget));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilOpTestCase('stencil_back_' + stencilOps[testNdx].name, stencilOps[testNdx].backDescription, stencilOps[testNdx].backTarget));
+
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilOpSeparateTestCase('stencil_' + stencilOps[testNdx].name + '_separate_both', stencilOps[testNdx].frontDescription, stencilOps[testNdx].frontTarget, gl.FRONT_AND_BACK));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilOpSeparateTestCase('stencil_back_' + stencilOps[testNdx].name + '_separate_both', stencilOps[testNdx].backDescription, stencilOps[testNdx].backTarget, gl.FRONT_AND_BACK));
+
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilOpSeparateTestCase('stencil_' + stencilOps[testNdx].name + '_separate', stencilOps[testNdx].frontDescription, stencilOps[testNdx].frontTarget, gl.FRONT));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilOpSeparateTestCase('stencil_back_' + stencilOps[testNdx].name + '_separate', stencilOps[testNdx].backDescription, stencilOps[testNdx].backTarget, gl.BACK));
+ }
+
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilFuncTestCase('stencil_func', 'STENCIL_FUNC'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilFuncSeparateTestCase('stencil_func_separate', 'STENCIL_FUNC (separate)', gl.STENCIL_FUNC, gl.FRONT));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilFuncSeparateTestCase('stencil_func_separate_both', 'STENCIL_FUNC (separate)', gl.STENCIL_FUNC, gl.FRONT_AND_BACK));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilFuncSeparateTestCase('stencil_back_func_separate', 'STENCIL_FUNC (separate)', gl.STENCIL_BACK_FUNC, gl.BACK));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilFuncSeparateTestCase('stencil_back_func_separate_both', 'STENCIL_FUNC (separate)', gl.STENCIL_BACK_FUNC, gl.FRONT_AND_BACK));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilMaskTestCase('stencil_value_mask', 'STENCIL_VALUE_MASK', gl.STENCIL_VALUE_MASK));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilMaskTestCase('stencil_back_value_mask', 'STENCIL_BACK_VALUE_MASK', gl.STENCIL_BACK_VALUE_MASK));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilMaskSeparateTestCase('stencil_value_mask_separate', 'STENCIL_VALUE_MASK (separate)', gl.STENCIL_VALUE_MASK, gl.FRONT));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilMaskSeparateTestCase('stencil_value_mask_separate_both', 'STENCIL_VALUE_MASK (separate)', gl.STENCIL_VALUE_MASK, gl.FRONT_AND_BACK));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilMaskSeparateTestCase('stencil_back_value_mask_separate', 'STENCIL_BACK_VALUE_MASK (separate)', gl.STENCIL_BACK_VALUE_MASK, gl.BACK));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilMaskSeparateTestCase('stencil_back_value_mask_separate_both', 'STENCIL_BACK_VALUE_MASK (separate)', gl.STENCIL_BACK_VALUE_MASK, gl.FRONT_AND_BACK));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilWriteMaskTestCase('stencil_writemask', 'STENCIL_WRITEMASK', gl.STENCIL_WRITEMASK));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilWriteMaskTestCase('stencil_back_writemask', 'STENCIL_BACK_WRITEMASK', gl.STENCIL_BACK_WRITEMASK));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilWriteMaskSeparateTestCase('stencil_writemask_separate', 'STENCIL_WRITEMASK (separate)', gl.STENCIL_WRITEMASK, gl.FRONT));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilWriteMaskSeparateTestCase('stencil_writemask_separate_both', 'STENCIL_WRITEMASK (separate)', gl.STENCIL_WRITEMASK, gl.FRONT_AND_BACK));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilWriteMaskSeparateTestCase('stencil_back_writemask_separate', 'STENCIL_BACK_WRITEMASK (separate)', gl.STENCIL_BACK_WRITEMASK, gl.BACK));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilWriteMaskSeparateTestCase('stencil_back_writemask_separate_both', 'STENCIL_BACK_WRITEMASK (separate)', gl.STENCIL_BACK_WRITEMASK, gl.FRONT_AND_BACK));
+
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {string} description
+ * @param {number} target
+ * @param {number} initialValue
+ */
+ var PixelStoreState = function(name, description, target, initialValue) {
+ /** @type {string} */ this.name = name;
+ /** @type {string} */ this.description = description;
+ /** @type {number} */ this.target = target;
+ /** @type {number} */ this.initialValue = initialValue;
+ };
+
+ /** @type {Array<PixelStoreState>} */ var pixelStoreStates = [
+ new PixelStoreState('unpack_image_height', 'UNPACK_IMAGE_HEIGHT', gl.UNPACK_IMAGE_HEIGHT, 0),
+ new PixelStoreState('unpack_skip_images', 'UNPACK_SKIP_IMAGES', gl.UNPACK_SKIP_IMAGES, 0),
+ new PixelStoreState('unpack_row_length', 'UNPACK_ROW_LENGTH', gl.UNPACK_ROW_LENGTH, 0),
+ new PixelStoreState('unpack_skip_rows', 'UNPACK_SKIP_ROWS', gl.UNPACK_SKIP_ROWS, 0),
+ new PixelStoreState('unpack_skip_pixels', 'UNPACK_SKIP_PIXELS', gl.UNPACK_SKIP_PIXELS, 0),
+ new PixelStoreState('pack_row_length', 'PACK_ROW_LENGTH', gl.PACK_ROW_LENGTH, 0),
+ new PixelStoreState('pack_skip_rows', 'PACK_SKIP_ROWS', gl.PACK_SKIP_ROWS, 0),
+ new PixelStoreState('pack_skip_pixels', 'PACK_SKIP_PIXELS', gl.PACK_SKIP_PIXELS, 0)
+ ];
+
+ for (var testNdx = 0; testNdx < pixelStoreStates.length; testNdx++)
+ testCtx.addChild(new es3fIntegerStateQueryTests.PixelStoreTestCase(pixelStoreStates[testNdx].name, pixelStoreStates[testNdx].description, pixelStoreStates[testNdx].target, pixelStoreStates[testNdx].initialValue));
+
+ testCtx.addChild(new es3fIntegerStateQueryTests.PixelStoreAlignTestCase('unpack_alignment', 'UNPACK_ALIGNMENT', gl.UNPACK_ALIGNMENT));
+ testCtx.addChild(new es3fIntegerStateQueryTests.PixelStoreAlignTestCase('pack_alignment', 'PACK_ALIGNMENT', gl.PACK_ALIGNMENT));
+
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {string} description
+ * @param {number} target
+ * @param {number} initialValue
+ */
+ var BlendColorState = function(name, description, target, initialValue) {
+ /** @type {string} */ this.name = name;
+ /** @type {string} */ this.description = description;
+ /** @type {number} */ this.target = target;
+ /** @type {number} */ this.initialValue = initialValue;
+ };
+
+ /** @type {Array<PixelStoreState>} */ var blendColorStates = [
+ new BlendColorState('blend_src_rgb', 'BLEND_SRC_RGB', gl.BLEND_SRC_RGB),
+ new BlendColorState('blend_src_alpha', 'BLEND_SRC_ALPHA', gl.BLEND_SRC_ALPHA),
+ new BlendColorState('blend_dst_rgb', 'BLEND_DST_RGB', gl.BLEND_DST_RGB),
+ new BlendColorState('blend_dst_alpha', 'BLEND_DST_ALPHA', gl.BLEND_DST_ALPHA)
+ ];
+
+ for (var testNdx = 0; testNdx < blendColorStates.length; testNdx++) {
+ testCtx.addChild(new es3fIntegerStateQueryTests.BlendFuncTestCase(blendColorStates[testNdx].name, blendColorStates[testNdx].description, blendColorStates[testNdx].target));
+ testCtx.addChild(new es3fIntegerStateQueryTests.BlendFuncSeparateTestCase(blendColorStates[testNdx].name + '_separate', blendColorStates[testNdx].description, blendColorStates[testNdx].target));
+ }
+
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {string} description
+ * @param {number} target
+ * @param {number} initialValue
+ */
+ var BlendEquationState = function(name, description, target, initialValue) {
+ /** @type {string} */ this.name = name;
+ /** @type {string} */ this.description = description;
+ /** @type {number} */ this.target = target;
+ /** @type {number} */ this.initialValue = initialValue;
+ };
+
+ /** @type {Array<PixelStoreState>} */ var blendEquationStates = [
+ new BlendEquationState('blend_equation_rgb', 'BLEND_EQUATION_RGB', gl.BLEND_EQUATION_RGB, gl.FUNC_ADD),
+ new BlendEquationState('blend_equation_alpha', 'BLEND_EQUATION_ALPHA', gl.BLEND_EQUATION_ALPHA, gl.FUNC_ADD)
+ ];
+
+ for (var testNdx = 0; testNdx < blendEquationStates.length; testNdx++) {
+ testCtx.addChild(new es3fIntegerStateQueryTests.BlendEquationTestCase(blendEquationStates[testNdx].name, blendEquationStates[testNdx].description, blendEquationStates[testNdx].target, blendEquationStates[testNdx].initialValue));
+ testCtx.addChild(new es3fIntegerStateQueryTests.BlendEquationSeparateTestCase(blendEquationStates[testNdx].name + '_separate', blendEquationStates[testNdx].description, blendEquationStates[testNdx].target, blendEquationStates[testNdx].initialValue));
+ }
+
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {string} description
+ * @param {number} target
+ * @param {number} minValue
+ */
+ var ImplementationArrayReturningState = function(name, description, target, minValue) {
+ /** @type {string} */ this.name = name;
+ /** @type {string} */ this.description = description;
+ /** @type {number} */ this.target = target;
+ /** @type {number} */ this.minValue = minValue;
+ };
+
+ /** @type {ImplementationArrayReturningState} */ var implementationArrayReturningStates = new ImplementationArrayReturningState('compressed_texture_formats', 'COMPRESSED_TEXTURE_FORMATS', gl.COMPRESSED_TEXTURE_FORMATS, 10);
+
+ testCtx.addChild(new es3fIntegerStateQueryTests.ImplementationArrayTestCase(implementationArrayReturningStates.name, implementationArrayReturningStates.description, implementationArrayReturningStates.target, implementationArrayReturningStates.minValue));
+
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {string} description
+ * @param {number} target
+ * @param {number} type
+ */
+ var BufferBindingState = function(name, description, target, type) {
+ /** @type {string} */ this.name = name;
+ /** @type {string} */ this.description = description;
+ /** @type {number} */ this.target = target;
+ /** @type {number} */ this.type = type;
+ };
+
+ /** @type {Array<BufferBindingState>} */ var bufferBindingStates = [
+ new BufferBindingState('array_buffer_binding', 'ARRAY_BUFFER_BINDING', gl.ARRAY_BUFFER_BINDING, gl.ARRAY_BUFFER),
+ new BufferBindingState('uniform_buffer_binding', 'UNIFORM_BUFFER_BINDING', gl.UNIFORM_BUFFER_BINDING, gl.UNIFORM_BUFFER),
+ new BufferBindingState('pixel_pack_buffer_binding', 'PIXEL_PACK_BUFFER_BINDING', gl.PIXEL_PACK_BUFFER_BINDING, gl.PIXEL_PACK_BUFFER),
+ new BufferBindingState('pixel_unpack_buffer_binding', 'PIXEL_UNPACK_BUFFER_BINDING', gl.PIXEL_UNPACK_BUFFER_BINDING, gl.PIXEL_UNPACK_BUFFER),
+ new BufferBindingState('transform_feedback_buffer_binding', 'TRANSFORM_FEEDBACK_BUFFER_BINDING', gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, gl.TRANSFORM_FEEDBACK_BUFFER),
+ new BufferBindingState('copy_read_buffer_binding', 'COPY_READ_BUFFER_BINDING', gl.COPY_READ_BUFFER_BINDING, gl.COPY_READ_BUFFER),
+ new BufferBindingState('copy_write_buffer_binding', 'COPY_WRITE_BUFFER_BINDING', gl.COPY_WRITE_BUFFER_BINDING, gl.COPY_WRITE_BUFFER)
+ ];
+
+ for (var testNdx = 0; testNdx < bufferBindingStates.length; testNdx++)
+ testCtx.addChild(new es3fIntegerStateQueryTests.BufferBindingTestCase(bufferBindingStates[testNdx].name, bufferBindingStates[testNdx].description, bufferBindingStates[testNdx].target, bufferBindingStates[testNdx].type));
+
+ testCtx.addChild(new es3fIntegerStateQueryTests.ElementArrayBufferBindingTestCase('element_array_buffer_binding'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.TransformFeedbackBindingTestCase('transform_feedback_binding'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.TransformFeedbackBindingTestCase('transform_feedback_binding'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.CurrentProgramBindingTestCase('current_program_binding', 'CURRENT_PROGRAM'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.VertexArrayBindingTestCase('vertex_array_binding', 'VERTEX_ARRAY_BINDING'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.StencilClearValueTestCase('stencil_clear_value', 'STENCIL_CLEAR_VALUE'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.ActiveTextureTestCase('active_texture', 'ACTIVE_TEXTURE'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.RenderbufferBindingTestCase('renderbuffer_binding', 'RENDERBUFFER_BINDING'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.SamplerObjectBindingTestCase('sampler_binding', 'SAMPLER_BINDING'));
+
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {string} description
+ * @param {number} target
+ * @param {number} type
+ */
+ var TextureBinding = function(name, description, target, type) {
+ /** @type {string} */ this.name = name;
+ /** @type {string} */ this.description = description;
+ /** @type {number} */ this.target = target;
+ /** @type {number} */ this.type = type;
+ };
+
+ /** @type {Array<TextureBinding>} */ var textureBindings = [
+ new TextureBinding('texture_binding_2d', 'TEXTURE_BINDING_2D', gl.TEXTURE_BINDING_2D, gl.TEXTURE_2D),
+ new TextureBinding('texture_binding_3d', 'TEXTURE_BINDING_3D', gl.TEXTURE_BINDING_3D, gl.TEXTURE_3D),
+ new TextureBinding('texture_binding_2d_array', 'TEXTURE_BINDING_2D_ARRAY', gl.TEXTURE_BINDING_2D_ARRAY, gl.TEXTURE_2D_ARRAY),
+ new TextureBinding('texture_binding_cube_map', 'TEXTURE_BINDING_CUBE_MAP', gl.TEXTURE_BINDING_CUBE_MAP, gl.TEXTURE_CUBE_MAP)
+ ];
+
+ for (var testNdx = 0; testNdx < textureBindings.length; testNdx++)
+ testCtx.addChild(new es3fIntegerStateQueryTests.TextureBindingTestCase(textureBindings[testNdx].name, textureBindings[testNdx].description, textureBindings[testNdx].target, textureBindings[testNdx].type));
+
+ testCtx.addChild(new es3fIntegerStateQueryTests.FrameBufferBindingTestCase('framebuffer_binding', 'DRAW_FRAMEBUFFER_BINDING and READ_FRAMEBUFFER_BINDING'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.ImplementationColorReadTestCase('implementation_color_read', 'IMPLEMENTATION_COLOR_READ_TYPE and IMPLEMENTATION_COLOR_READ_FORMAT'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.ReadBufferCase('read_buffer', 'READ_BUFFER'));
+ testCtx.addChild(new es3fIntegerStateQueryTests.DrawBufferCase('draw_buffer', 'DRAW_BUFFER'));
+
+
+ // Integer64
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {string} description
+ * @param {number} targetName
+ * @param {number} minValue
+ */
+ var LimitedStateInteger64 = function(name, description, targetName, minValue) {
+ /** @type {string} */ this.name = name;
+ /** @type {string} */ this.description = description;
+ /** @type {number} */ this.targetName = targetName;
+ /** @type {number} */ this.minValue = minValue;
+
+ };
+
+ /** @type {Array<LimitedStateInteger64>} */ var implementationLimits = [
+ new LimitedStateInteger64('max_element_index', 'MAX_ELEMENT_INDEX', gl.MAX_ELEMENT_INDEX, 0x00FFFFFF),
+ new LimitedStateInteger64('max_server_wait_timeout', 'MAX_SERVER_WAIT_TIMEOUT', gl.MAX_SERVER_WAIT_TIMEOUT, 0),
+ new LimitedStateInteger64('max_uniform_block_size', 'MAX_UNIFORM_BLOCK_SIZE', gl.MAX_UNIFORM_BLOCK_SIZE, 16384)
+ ];
+
+ for (var testNdx = 0; testNdx < implementationLimits.length; testNdx++)
+ this.addChild(new es3fIntegerStateQueryTests.ConstantMinimumValue64TestCase(implementationLimits[testNdx].name, implementationLimits[testNdx].description, implementationLimits[testNdx].targetName, implementationLimits[testNdx].minValue));
+
+ this.addChild(new es3fIntegerStateQueryTests.MaxCombinedStageUniformComponentsCase('max_combined_vertex_uniform_components', 'MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS', gl.MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, gl.MAX_VERTEX_UNIFORM_BLOCKS, gl.MAX_VERTEX_UNIFORM_COMPONENTS));
+ this.addChild(new es3fIntegerStateQueryTests.MaxCombinedStageUniformComponentsCase('max_combined_fragment_uniform_components', 'MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS', gl.MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, gl.MAX_FRAGMENT_UNIFORM_BLOCKS, gl.MAX_FRAGMENT_UNIFORM_COMPONENTS));
+
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fIntegerStateQueryTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fIntegerStateQueryTests.IntegerStateQueryTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fIntegerStateQueryTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fInternalFormatQueryTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fInternalFormatQueryTests.js
new file mode 100644
index 0000000000..8eb1b0e2c0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fInternalFormatQueryTests.js
@@ -0,0 +1,173 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fInternalFormatQueryTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('functional.gles3.es3fApiCase');
+goog.require('modules.shared.glsStateQuery');
+
+goog.scope(function() {
+var es3fInternalFormatQueryTests = functional.gles3.es3fInternalFormatQueryTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var glsStateQuery = modules.shared.glsStateQuery;
+var es3fApiCase = functional.gles3.es3fApiCase;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} internalFormat
+ * @param {boolean} isIntegerInternalFormat
+ */
+es3fInternalFormatQueryTests.SamplesCase = function(name, description, internalFormat, isIntegerInternalFormat) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ this.m_internalFormat = internalFormat;
+ this.m_isIntegerInternalFormat = isIntegerInternalFormat;
+};
+
+setParentClass(es3fInternalFormatQueryTests.SamplesCase, es3fApiCase.ApiCase);
+
+es3fInternalFormatQueryTests.SamplesCase.prototype.test = function() {
+ var samples = gl.getInternalformatParameter(gl.RENDERBUFFER, this.m_internalFormat, gl.SAMPLES);
+
+ this.check(!this.m_isIntegerInternalFormat || samples.length == 0, 'integer internal format should have 0 samples, got ' + samples.length);
+
+ if (samples.length == 0)
+ return;
+
+ var prevSampleCount = 0;
+ var sampleCount = 0;
+ for (var ndx = 0; ndx < samples.length; ++ndx, prevSampleCount = sampleCount) {
+ sampleCount = samples[ndx];
+
+ // sample count must be > 0
+ this.check(sampleCount > 0, 'Expected sample count to be at least one; got ' + sampleCount);
+
+ // samples must be ordered descending
+ this.check(ndx == 0 || sampleCount < prevSampleCount, 'Expected sample count to be ordered in descending order; got ' + prevSampleCount + ' at index ' + (ndx - 1) + ', and ' + sampleCount + ' at index ' + ndx);
+ }
+
+ // the maximum value in SAMPLES is guaranteed to be at least the value of MAX_SAMPLES
+ var maxSamples = /** @type {number} */ (gl.getParameter(gl.MAX_SAMPLES));
+ var maximumFormatSampleCount = samples[0];
+ this.check(maximumFormatSampleCount >= maxSamples, 'Expected maximum value in SAMPLES (' + maximumFormatSampleCount + ') to be at least the value of MAX_SAMPLES (' + maxSamples + ')');
+};
+
+/**
+* @constructor
+* @extends {tcuTestCase.DeqpTest}
+*/
+es3fInternalFormatQueryTests.InternalFormatQueryTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'internal_format', 'Internal Format Query tests');
+};
+
+es3fInternalFormatQueryTests.InternalFormatQueryTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fInternalFormatQueryTests.InternalFormatQueryTests.prototype.constructor = es3fInternalFormatQueryTests.InternalFormatQueryTests;
+
+es3fInternalFormatQueryTests.InternalFormatQueryTests.prototype.init = function() {
+ var internalFormats = [
+ //name, format, is_integer
+ // color renderable and unsized
+ // \note These unsized formats seem to allowed by the spec, but they are not useful in any way. (You can't create a renderbuffer with such internalFormat)
+ ['rgba', gl.RGBA, false],
+ ['rgb', gl.RGB, false],
+
+ // color renderable
+ ['r8', gl.R8, false],
+ ['rg8', gl.RG8, false],
+ ['rgb8', gl.RGB8, false],
+ ['rgb565', gl.RGB565, false],
+ ['rgba4', gl.RGBA4, false],
+ ['rgb5_a1', gl.RGB5_A1, false],
+ ['rgba8', gl.RGBA8, false],
+ ['rgb10_a2', gl.RGB10_A2, false],
+ ['rgb10_a2ui', gl.RGB10_A2UI, true],
+ ['srgb8_alpha8', gl.SRGB8_ALPHA8, false],
+ ['r8i', gl.R8I, true],
+ ['r8ui', gl.R8UI, true],
+ ['r16i', gl.R16I, true],
+ ['r16ui', gl.R16UI, true],
+ ['r32i', gl.R32I, true],
+ ['r32ui', gl.R32UI, true],
+ ['rg8i', gl.RG8I, true],
+ ['rg8ui', gl.RG8UI, true],
+ ['rg16i', gl.RG16I, true],
+ ['rg16ui', gl.RG16UI, true],
+ ['rg32i', gl.RG32I, true],
+ ['rg32ui', gl.RG32UI, true],
+ ['rgba8i', gl.RGBA8I, true],
+ ['rgba8ui', gl.RGBA8UI, true],
+ ['rgba16i', gl.RGBA16I, true],
+ ['rgba16ui', gl.RGBA16UI, true],
+ ['rgba32i', gl.RGBA32I, true],
+ ['rgba32ui', gl.RGBA32UI, true],
+
+ // depth renderable
+ ['depth_component16', gl.DEPTH_COMPONENT16, false],
+ ['depth_component24', gl.DEPTH_COMPONENT24, false],
+ ['depth_component32f', gl.DEPTH_COMPONENT32F, false],
+ ['depth24_stencil8', gl.DEPTH24_STENCIL8, false],
+ ['depth32f_stencil8', gl.DEPTH32F_STENCIL8, false],
+
+ // stencil renderable
+ ['stencil_index8', gl.STENCIL_INDEX8, false]
+ // DEPTH24_STENCIL8, duplicate
+ // DEPTH32F_STENCIL8 duplicate
+ ];
+
+ for (var ndx = 0; ndx < internalFormats.length; ++ndx) {
+ var internalFormat = internalFormats[ndx];
+
+ this.addChild(new es3fInternalFormatQueryTests.SamplesCase(internalFormat[0] + '_samples', 'SAMPLES and NUM_SAMPLE_COUNTS', internalFormat[1], internalFormat[2]));
+ }
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fInternalFormatQueryTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fInternalFormatQueryTests.InternalFormatQueryTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fInternalFormatQueryTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fLifetimeTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fLifetimeTests.js
new file mode 100644
index 0000000000..b179022bfd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fLifetimeTests.js
@@ -0,0 +1,471 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+'use strict';
+goog.provide('functional.gles3.es3fLifetimeTests');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('modules.shared.glsLifetimeTests');
+goog.require('modules.shared.glsTextureTestUtil');
+
+goog.scope(function() {
+var es3fLifetimeTests = functional.gles3.es3fLifetimeTests;
+var glsLifetimeTests = modules.shared.glsLifetimeTests;
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+var deRandom = framework.delibs.debase.deRandom;
+var tcuSurface = framework.common.tcuSurface;
+var glsTextureTestUtil = modules.shared.glsTextureTestUtil;
+var tcuTestCase = framework.common.tcuTestCase;
+
+/** @const */ var VIEWPORT_SIZE = 128;
+/** @const */ var NUM_COMPONENTS = 4;
+/** @const */ var NUM_VERTICES = 3;
+
+/** @type {WebGL2RenderingContext} */ var gl;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+/**
+ * @constructor
+ * @extends {gluShaderProgram.ShaderProgram}
+ */
+es3fLifetimeTests.ScaleProgram = function() {
+ gluShaderProgram.ShaderProgram.call(this, gl, this.getSources());
+ assertMsgOptions(this.isOk(), 'Program creation failed', false, true);
+ this.m_scaleLoc = gl.getUniformLocation(this.getProgram(), 'scale');
+ this.m_posLoc = gl.getAttribLocation(this.getProgram(), 'pos');
+};
+
+setParentClass(es3fLifetimeTests.ScaleProgram, gluShaderProgram.ShaderProgram);
+
+/**
+ * @param {WebGLVertexArrayObject} vao
+ * @param {number} scale
+ * @param {boolean} tf
+ * @param {tcuSurface.Surface} dst
+ */
+es3fLifetimeTests.ScaleProgram.prototype.draw = function(vao, scale, tf, dst) {
+ es3fLifetimeTests.ScaleProgram.seed = es3fLifetimeTests.ScaleProgram.seed || 0;
+ ++es3fLifetimeTests.ScaleProgram.seed;
+
+ var viewport = new glsTextureTestUtil.RandomViewport(document.getElementById('canvas'), VIEWPORT_SIZE, VIEWPORT_SIZE, es3fLifetimeTests.ScaleProgram.seed);
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+ gl.clearColor(0, 0, 0, 1);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ gl.bindVertexArray(vao);
+ gl.enableVertexAttribArray(this.m_posLoc);
+ gl.useProgram(this.getProgram());
+
+ gl.uniform1f(this.m_scaleLoc, scale);
+
+ if (tf)
+ gl.beginTransformFeedback(gl.TRIANGLES);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+ if (tf)
+ gl.endTransformFeedback();
+
+ if (dst)
+ glsLifetimeTests.readRectangle(viewport, dst);
+
+ gl.bindVertexArray(null);
+
+};
+
+/**
+ * @param {WebGLBuffer} buffer
+ * @param {WebGLVertexArrayObject} vao
+ */
+es3fLifetimeTests.ScaleProgram.prototype.setPos = function(buffer, vao) {
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bindVertexArray(vao);
+ gl.vertexAttribPointer(this.m_posLoc, NUM_COMPONENTS, gl.FLOAT, false, 0, 0);
+ gl.bindVertexArray(null);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+};
+
+/**
+ * @private
+ */
+es3fLifetimeTests.ScaleProgram.prototype.getSources = function() {
+/** @const */ var s_vertexShaderSrc =
+ '#version 100\n' +
+ 'attribute vec4 pos;\n' +
+ 'uniform float scale;\n' +
+ 'void main ()\n' +
+ '{\n' +
+ ' gl_Position = vec4(scale * pos.xy, pos.zw);\n' +
+ '}';
+
+/** @const */ var s_fragmentShaderSrc =
+ '#version 100\n' +
+ 'void main ()\n' +
+ '{\n' +
+ ' gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);\n' +
+ '}';
+ var sources = new gluShaderProgram.ProgramSources();
+ sources.add(new gluShaderProgram.VertexSource(s_vertexShaderSrc));
+ sources.add(new gluShaderProgram.FragmentSource(s_fragmentShaderSrc));
+ sources.add(new gluShaderProgram.TransformFeedbackMode(gl.INTERLEAVED_ATTRIBS));
+ sources.add(new gluShaderProgram.TransformFeedbackVarying('gl_Position'));
+ return sources;
+};
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.SimpleBinder}
+ */
+es3fLifetimeTests.VertexArrayBinder = function() {
+ glsLifetimeTests.SimpleBinder.call(this, null, gl.NONE, gl.VERTEX_ARRAY_BINDING);
+};
+
+setParentClass(es3fLifetimeTests.VertexArrayBinder, glsLifetimeTests.SimpleBinder);
+
+es3fLifetimeTests.VertexArrayBinder.prototype.bind = function(obj) {
+ var vao = /** @type {WebGLVertexArrayObject} */ (obj);
+ gl.bindVertexArray(vao);
+};
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.Binder}
+ */
+es3fLifetimeTests.SamplerBinder = function() {
+ glsLifetimeTests.Binder.call(this);
+};
+
+setParentClass(es3fLifetimeTests.SamplerBinder, glsLifetimeTests.Binder);
+
+es3fLifetimeTests.SamplerBinder.prototype.bind = function(obj) {
+ var sampler = /** @type {WebGLSampler} */ (obj);
+ gl.bindSampler(0, sampler);
+};
+es3fLifetimeTests.SamplerBinder.prototype.getBinding = function() { return /** @type {WebGLSampler} */ (gl.getParameter(gl.SAMPLER_BINDING)); };
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.Binder}
+ */
+es3fLifetimeTests.QueryBinder = function() {
+ glsLifetimeTests.Binder.call(this);
+};
+
+setParentClass(es3fLifetimeTests.QueryBinder, glsLifetimeTests.Binder);
+
+es3fLifetimeTests.QueryBinder.prototype.bind = function(obj) {
+ var query = /** @type {WebGLQuery} */ (obj);
+ if (query)
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED, query);
+ else
+ gl.endQuery(gl.ANY_SAMPLES_PASSED);
+};
+
+es3fLifetimeTests.QueryBinder.prototype.getBinding = function() { return null; };
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.Attacher}
+ * @param {glsLifetimeTests.Type} elementType
+ * @param {glsLifetimeTests.Type} varrType
+ * @param {es3fLifetimeTests.ScaleProgram} program
+ */
+es3fLifetimeTests.BufferVAOAttacher = function(elementType, varrType, program) {
+ glsLifetimeTests.Attacher.call(this, elementType, varrType);
+ this.m_program = program;
+};
+
+setParentClass(es3fLifetimeTests.BufferVAOAttacher, glsLifetimeTests.Attacher);
+
+/**
+ * @return {es3fLifetimeTests.ScaleProgram}
+ */
+es3fLifetimeTests.BufferVAOAttacher.prototype.getProgram = function() { return this.m_program; };
+
+/**
+ * @param {number} seed
+ * @param {number} usage
+ * @param {WebGLBuffer} buffer
+ */
+es3fLifetimeTests.initBuffer = function(seed, usage, buffer) {
+ /** @const */ var s_varrData = [
+ -1.0, 0.0, 0.0, 1.0,
+ 1.0, 1.0, 0.0, 1.0,
+ 0.0, -1.0, 0.0, 1.0
+ ];
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ if (seed == 0)
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(s_varrData), usage);
+ else {
+ var rnd = new deRandom.Random(seed);
+ var data = [];
+
+ for (var ndx = 0; ndx < NUM_VERTICES; ndx++) {
+ data.push(2 * (rnd.getFloat() - 0.5));
+ data.push(2 * (rnd.getFloat() - 0.5));
+ data.push(0);
+ data.push(1);
+ }
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), usage);
+ }
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+};
+
+es3fLifetimeTests.BufferVAOAttacher.prototype.initAttachment = function(seed, obj) {
+ var buffer = /** @type {WebGLBuffer} */ (obj);
+ es3fLifetimeTests.initBuffer(seed, gl.STATIC_DRAW, buffer);
+ bufferedLogToConsole('Initialized buffer ' + buffer + ' from seed ' + seed);
+};
+
+es3fLifetimeTests.BufferVAOAttacher.prototype.attach = function(element, target) {
+ var buffer = /** @type {WebGLBuffer} */ (element);
+ var vao = /** @type {WebGLVertexArrayObject} */ (target);
+
+ this.m_program.setPos(buffer, vao);
+ bufferedLogToConsole('Set the `pos` attribute in VAO ' + vao + ' to buffer ' + buffer);
+};
+
+es3fLifetimeTests.BufferVAOAttacher.prototype.detach = function(element, target) {
+ var vao = /** @type {WebGLVertexArrayObject} */ (target);
+ this.attach(null, vao);
+};
+
+es3fLifetimeTests.BufferVAOAttacher.prototype.getAttachment = function(target) {
+ var vao = /** @type {WebGLVertexArrayObject} */ (target);
+ gl.bindVertexArray(vao);
+ var name = gl.getVertexAttrib(this.m_posLoc, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
+ gl.bindVertexArray(null);
+ return name;
+};
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.InputAttacher}
+ * @param {es3fLifetimeTests.BufferVAOAttacher} attacher
+ */
+es3fLifetimeTests.BufferVAOInputAttacher = function(attacher) {
+ glsLifetimeTests.InputAttacher.call(this, attacher);
+ this.m_program = attacher.getProgram();
+};
+
+setParentClass(es3fLifetimeTests.BufferVAOInputAttacher, glsLifetimeTests.InputAttacher);
+
+es3fLifetimeTests.BufferVAOInputAttacher.prototype.drawContainer = function(obj, dst) {
+ var vao = /** @type {WebGLVertexArrayObject} */ (obj);
+ this.m_program.draw(vao, 1.0, false, dst);
+ bufferedLogToConsole('Drew an output image with VAO ' + vao);
+};
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.Attacher}
+ * @param {glsLifetimeTests.Type} elementType
+ * @param {glsLifetimeTests.Type} tfType
+*/
+es3fLifetimeTests.BufferTfAttacher = function(elementType, tfType) {
+ glsLifetimeTests.Attacher.call(this, elementType, tfType);
+};
+
+setParentClass(es3fLifetimeTests.BufferTfAttacher, glsLifetimeTests.Attacher);
+
+es3fLifetimeTests.BufferTfAttacher.prototype.initAttachment = function(seed, obj) {
+ var buffer = /** @type {WebGLBuffer} */ (obj);
+ es3fLifetimeTests.initBuffer(seed, gl.DYNAMIC_READ, buffer);
+ bufferedLogToConsole('Initialized buffer ' + buffer + ' from seed ' + seed);
+};
+
+es3fLifetimeTests.BufferTfAttacher.prototype.attach = function(element, target) {
+ var buffer = /** @type {WebGLBuffer} */ (element);
+ var tf = /** @type {WebGLTransformFeedback} */ (target);
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+};
+
+es3fLifetimeTests.BufferTfAttacher.prototype.detach = function(element, target) {
+ var buffer = /** @type {WebGLBuffer} */ (element);
+ var tf = /** @type {WebGLTransformFeedback} */ (target);
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+
+};
+
+es3fLifetimeTests.BufferTfAttacher.prototype.getAttachment = function(target) {
+ var tf = /** @type {WebGLTransformFeedback} */ (target);
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ var name = gl.getIndexedParameter(gl.TRANSFORM_FEEDBACK_BUFFER_BINDING, 0);
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+ return name;
+};
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.OutputAttacher}
+ */
+es3fLifetimeTests.BufferTfOutputAttacher = function(attacher, program) {
+ glsLifetimeTests.OutputAttacher.call(this, attacher);
+ this.m_program = program;
+};
+
+setParentClass(es3fLifetimeTests.BufferTfOutputAttacher, glsLifetimeTests.OutputAttacher);
+
+es3fLifetimeTests.BufferTfOutputAttacher.prototype.setupContainer = function(seed, obj) {
+ var tf = /** @type {WebGLTransformFeedback} */ (obj);
+ var posBuf = gl.createBuffer();
+ var vao = gl.createVertexArray();
+
+ es3fLifetimeTests.initBuffer(seed, gl.STATIC_DRAW, posBuf);
+ this.m_program.setPos(posBuf, vao);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ this.m_program.draw(vao, -1.0, true, null);
+ bufferedLogToConsole('Drew an image with seed ' + seed + ' with transform feedback to ' + tf);
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+ gl.deleteVertexArray(vao);
+ gl.deleteBuffer(posBuf);
+};
+
+es3fLifetimeTests.BufferTfOutputAttacher.prototype.drawAttachment = function(buffer, dst) {
+ var vao = gl.createVertexArray();
+
+ this.m_program.setPos(buffer, vao);
+ this.m_program.draw(vao, 1.0, false, dst);
+ bufferedLogToConsole('Drew output image with vertices from buffer ' + buffer);
+ gl.deleteVertexArray(vao);
+};
+
+/**
+ * @constructor
+ * @extends {glsLifetimeTests.ES2Types}
+ */
+es3fLifetimeTests.ES3Types = function() {
+ glsLifetimeTests.ES2Types.call(this);
+ this.m_program = new es3fLifetimeTests.ScaleProgram();
+ this.m_queryBind = new es3fLifetimeTests.QueryBinder();
+ this.m_queryType = new glsLifetimeTests.SimpleType('query', gl.createQuery, gl.deleteQuery, gl.isQuery, this.m_queryBind);
+ this.m_tfBind = new glsLifetimeTests.SimpleBinder(gl.bindTransformFeedback, gl.TRANSFORM_FEEDBACK,
+ gl.TRANSFORM_FEEDBACK_BINDING);
+ this.m_tfType = new glsLifetimeTests.SimpleType('transform_feedback', gl.createTransformFeedback, gl.deleteTransformFeedback, gl.isTransformFeedback, this.m_tfBind);
+ this.m_varrBind = new es3fLifetimeTests.VertexArrayBinder();
+ this.m_varrType = new glsLifetimeTests.SimpleType('vertex_array', gl.createVertexArray, gl.deleteVertexArray, gl.isVertexArray, this.m_varrBind);
+ this.m_samplerBind = new es3fLifetimeTests.SamplerBinder();
+ this.m_samplerType = new glsLifetimeTests.SimpleType('sampler', gl.createSampler, gl.deleteSampler, gl.isSampler, this.m_samplerBind, true);
+ this.m_bufVarrAtt = new es3fLifetimeTests.BufferVAOAttacher(this.m_bufferType, this.m_varrType, this.m_program);
+ this.m_bufVarrInAtt = new es3fLifetimeTests.BufferVAOInputAttacher(this.m_bufVarrAtt);
+ this.m_bufTfAtt = new es3fLifetimeTests.BufferTfAttacher(this.m_bufferType, this.m_tfType);
+ this.m_bufTfOutAtt = new es3fLifetimeTests.BufferTfOutputAttacher(this.m_bufTfAtt, this.m_program);
+
+ this.m_types.push(this.m_queryType, this.m_tfType, this.m_varrType, this.m_samplerType);
+ this.m_attachers.push(this.m_bufVarrAtt, this.m_bufTfAtt);
+ this.m_inAttachers.push(this.m_bufVarrInAtt);
+ this.m_outAttachers.push(this.m_bufTfOutAtt);
+};
+
+setParentClass(es3fLifetimeTests.ES3Types, glsLifetimeTests.ES2Types);
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+es3fLifetimeTests.TfDeleteActiveTest = function(name, description) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+};
+
+setParentClass(es3fLifetimeTests.TfDeleteActiveTest, tcuTestCase.DeqpTest);
+
+es3fLifetimeTests.TfDeleteActiveTest.prototype.iterate = function() {
+/** @const */ var s_xfbVertexSource =
+ '#version 300 es\n' +
+ 'void main ()\n' +
+ '{\n' +
+ ' gl_Position = vec4(float(gl_VertexID) / 2.0, float(gl_VertexID % 2) / 2.0, 0.0, 1.0);\n' +
+ '}\n';
+
+/** @const */ var s_xfbFragmentSource =
+ '#version 300 es\n' +
+ 'layout(location=0) out mediump vec4 dEQP_FragColor;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' dEQP_FragColor = vec4(1.0, 1.0, 0.0, 1.0);\n' +
+ '}\n';
+ var buf = gl.createBuffer();
+
+ var sources = new gluShaderProgram.ProgramSources();
+ sources.add(new gluShaderProgram.VertexSource(s_xfbVertexSource));
+ sources.add(new gluShaderProgram.FragmentSource(s_xfbFragmentSource));
+ sources.add(new gluShaderProgram.TransformFeedbackMode(gl.SEPARATE_ATTRIBS));
+ sources.add(new gluShaderProgram.TransformFeedbackVarying('gl_Position'));
+ var program = new gluShaderProgram.ShaderProgram(gl, sources);
+ if (!program.isOk()) {
+ bufferedLogToConsole(program.getProgramInfo().infoLog);
+ testFailedOptions('failed to build program', true);
+ }
+ gl.useProgram(program.getProgram());
+
+ var tf = gl.createTransformFeedback();
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tf);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 48, gl.STATIC_DRAW);
+
+ gl.beginTransformFeedback(gl.TRIANGLES);
+ var errCode = gl.NONE;
+ gl.deleteTransformFeedback(tf);
+ errCode = gl.getError();
+ assertMsgOptions(errCode == gl.INVALID_OPERATION,
+ 'Deleting active transform feedback must produce INVALID_OPERATION', false, true);
+ gl.endTransformFeedback();
+ gl.deleteTransformFeedback(tf);
+ testPassed();
+ return tcuTestCase.IterateResult.STOP;
+};
+
+es3fLifetimeTests.genTestCases = function() {
+ var state = tcuTestCase.runner;
+ state.setRoot(tcuTestCase.newTest('lifetime', 'Top level'));
+
+ var types = new es3fLifetimeTests.ES3Types();
+ glsLifetimeTests.addTestCases(state.testCases, types);
+ /* TODO: Add TfDeleteActiveTest test */
+ var deleteActiveGroup = tcuTestCase.newTest('delete_active', 'Delete active object');
+ state.testCases.addChild(deleteActiveGroup);
+ deleteActiveGroup.addChild(
+ new es3fLifetimeTests.TfDeleteActiveTest('transform_feedback', 'Transform Feedback'));
+};
+
+/**
+ * Create and execute the test cases
+ */
+es3fLifetimeTests.run = function(context) {
+ gl = context;
+ try {
+ es3fLifetimeTests.genTestCases();
+ tcuTestCase.runner.runCallback(tcuTestCase.runTestCases);
+ } catch (err) {
+ bufferedLogToConsole(err);
+ tcuTestCase.runner.terminate();
+ }
+
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fMultisampleTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fMultisampleTests.js
new file mode 100644
index 0000000000..47e6267d35
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fMultisampleTests.js
@@ -0,0 +1,1744 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fMultisampleTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluStrUtil');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuLogImage');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTexture');
+goog.require('modules.shared.glsTextureTestUtil');
+
+goog.scope(function() {
+ /** @type {?WebGL2RenderingContext} */ var gl;
+ var es3fMultisampleTests = functional.gles3.es3fMultisampleTests;
+ var deMath = framework.delibs.debase.deMath;
+ var deRandom = framework.delibs.debase.deRandom;
+ var deString = framework.delibs.debase.deString;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var tcuRGBA = framework.common.tcuRGBA;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuTexture = framework.common.tcuTexture;
+ var gluStrUtil = framework.opengl.gluStrUtil;
+ var glsTextureTestUtil = modules.shared.glsTextureTestUtil;
+ var tcuImageCompare = framework.common.tcuImageCompare;
+ var gluTextureUtil = framework.opengl.gluTextureUtil;
+ var tcuLogImage = framework.common.tcuLogImage;
+
+ /**
+ * @constructor
+ * @struct
+ * @param {Array<number>} p0_
+ * @param {Array<number>} p1_
+ * @param {Array<number>} p2_
+ * @param {Array<number>} p3_
+ */
+ es3fMultisampleTests.QuadCorners = function(p0_, p1_, p2_, p3_) {
+ /** @type {Array<number>} */ this.p0 = p0_;
+ /** @type {Array<number>} */ this.p1 = p1_;
+ /** @type {Array<number>} */ this.p2 = p2_;
+ /** @type {Array<number>} */ this.p3 = p3_;
+ };
+
+ /**
+ * @param {number} defaultCount
+ * @return {number}
+ */
+ es3fMultisampleTests.getIterationCount = function(defaultCount) {
+ // The C++ test takes an argument from the command line.
+ // Leaving this function in case we want to be able to take an argument from the URL
+ return defaultCount;
+ };
+
+ /**
+ * @param {Array<number>} point
+ * @param {Array<number>} p0
+ * @param {Array<number>} p1
+ * @param {Array<number>} p2
+ * @param {Array<number>} p3
+ * @return {boolean}
+ */
+ es3fMultisampleTests.isInsideQuad = function(point, p0, p1, p2, p3) {
+ /** @type {number} */ var dot0 = (point[0] - p0[0]) * (p1[1] - p0[1]) + (point[1] - p0[1]) * (p0[0] - p1[0]);
+ /** @type {number} */ var dot1 = (point[0] - p1[0]) * (p2[1] - p1[1]) + (point[1] - p1[1]) * (p1[0] - p2[0]);
+ /** @type {number} */ var dot2 = (point[0] - p2[0]) * (p3[1] - p2[1]) + (point[1] - p2[1]) * (p2[0] - p3[0]);
+ /** @type {number} */ var dot3 = (point[0] - p3[0]) * (p0[1] - p3[1]) + (point[1] - p3[1]) * (p3[0] - p0[0]);
+
+ return (dot0 > 0) == (dot1 > 0) && (dot1 > 0) == (dot2 > 0) && (dot2 > 0) == (dot3 > 0);
+ };
+
+ /**
+ * Check if a region in an image is unicolored.
+ *
+ * Checks if the pixels in img inside the convex quadilateral defined by
+ * p0, p1, p2 and p3 are all (approximately) of the same color.
+ *
+ * @param {tcuSurface.Surface} img
+ * @param {Array<number>} p0
+ * @param {Array<number>} p1
+ * @param {Array<number>} p2
+ * @param {Array<number>} p3
+ * @return {boolean}
+ */
+ es3fMultisampleTests.isPixelRegionUnicolored = function(img, p0, p1, p2, p3) {
+ /** @type {number} */ var xMin = deMath.clamp(Math.min(p0[0], p1[0], p2[0], p3[0]), 0, img.getWidth() - 1);
+ /** @type {number} */ var yMin = deMath.clamp(Math.min(p0[1], p1[1], p2[1], p3[1]), 0, img.getHeight() - 1);
+ /** @type {number} */ var xMax = deMath.clamp(Math.max(p0[0], p1[0], p2[0], p3[0]), 0, img.getWidth() - 1);
+ /** @type {number} */ var yMax = deMath.clamp(Math.max(p0[1], p1[1], p2[1], p3[1]), 0, img.getHeight() - 1);
+ /** @type {boolean} */ var insideEncountered = false; //!< Whether we have already seen at least one pixel inside the region.
+ /** @type {tcuRGBA.RGBA} */ var insideColor; //!< Color of the first pixel inside the region.
+ /** @type {tcuRGBA.RGBA} */ var threshold = tcuRGBA.newRGBAComponents(3, 3, 3, 3);
+ for (var y = yMin; y <= yMax; y++)
+ for (var x = xMin; x <= xMax; x++)
+ if (es3fMultisampleTests.isInsideQuad([x, y], p0, p1, p2, p3)) {
+ /** @type {tcuRGBA.RGBA} */ var pixColor = new tcuRGBA.RGBA(img.getPixel(x, y));
+
+ if (insideEncountered)
+ if (!tcuRGBA.compareThreshold(pixColor, insideColor, threshold)) // Pixel color differs from already-detected color inside same region - region not unicolored.
+ return false;
+ else {
+ insideEncountered = true;
+ insideColor = pixColor;
+ }
+ }
+ return true;
+ };
+
+ /**
+ * [drawUnicolorTestErrors description]
+ * @param {tcuSurface.Surface} img
+ * @param {tcuTexture.PixelBufferAccess} errorImg
+ * @param {Array<number>} p0
+ * @param {Array<number>} p1
+ * @param {Array<number>} p2
+ * @param {Array<number>} p3
+ * @return {boolean}
+ */
+ es3fMultisampleTests.drawUnicolorTestErrors = function(img, errorImg, p0, p1, p2, p3) {
+ /** @type {number} */ var xMin = deMath.clamp(Math.min(p0[0], p1[0], p2[0], p3[0]), 0, img.getWidth() - 1);
+ /** @type {number} */ var yMin = deMath.clamp(Math.min(p0[1], p1[1], p2[1], p3[1]), 0, img.getHeight() - 1);
+ /** @type {number} */ var xMax = deMath.clamp(Math.max(p0[0], p1[0], p2[0], p3[0]), 0, img.getWidth() - 1);
+ /** @type {number} */ var yMax = deMath.clamp(Math.max(p0[1], p1[1], p2[1], p3[1]), 0, img.getHeight() - 1);
+ /** @type {tcuRGBA.RGBA} */ var refColor = new tcuRGBA.RGBA(img.getPixel(Math.floor((xMin + xMax) / 2), Math.floor((yMin + yMax) / 2)));
+ /** @type {tcuRGBA.RGBA} */ var threshold = tcuRGBA.newRGBAComponents(3, 3, 3, 3);
+ for (var y = yMin; y <= yMax; y++)
+ for (var x = xMin; x <= xMax; x++)
+ if (es3fMultisampleTests.isInsideQuad([x, y], p0, p1, p2, p3)) {
+ if (!tcuRGBA.compareThreshold(new tcuRGBA.RGBA(img.getPixel(x, y)), refColor, threshold)) {
+ img.setPixel(x, y, tcuRGBA.RGBA.red.toVec()); // TODO: this might also be toIVec()
+ errorImg.setPixel([1.0, 0.0, 0.0, 1.0], x, y);
+ }
+ }
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @struct
+ * @param {number=} numSamples_
+ * @param {boolean=} useDepth_
+ * @param {boolean=} useStencil_
+ */
+ es3fMultisampleTests.FboParams = function(numSamples_, useDepth_, useStencil_) {
+ /** @type {boolean} */ var useFbo_ = true;
+ if (numSamples_ === undefined && useDepth_ === undefined && useStencil_ === undefined)
+ useFbo_ = false;
+ /** @type {boolean} */ this.useFbo = useFbo_;
+ /** @type {number} */ this.numSamples = numSamples_ === undefined ? -1 : numSamples_;
+ /** @type {boolean} */ this.useDepth = useDepth_ === undefined ? false : useDepth_;
+ /** @type {boolean} */ this.useStencil = useStencil_ === undefined ? false : useStencil_;
+
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} desiredViewportSize
+ * @param {es3fMultisampleTests.FboParams} fboParams
+ */
+ es3fMultisampleTests.MultisampleCase = function(name, desc, desiredViewportSize, fboParams) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ /** @type {number} */ this.m_numSamples = 0;
+ /** @type {number} */ this.m_viewportSize = 0;
+ /** @type {number} */ this.m_desiredViewportSize = desiredViewportSize;
+ /** @type {es3fMultisampleTests.FboParams} */ this.m_fboParams = fboParams;
+ /** @type {WebGLRenderbuffer} */ this.m_msColorRbo = null;
+ /** @type {WebGLRenderbuffer} */ this.m_msDepthStencilRbo = null;
+ /** @type {WebGLRenderbuffer} */ this.m_resolveColorRbo = null;
+ /** @type {WebGLFramebuffer} */ this.m_msFbo = null;
+ /** @type {WebGLFramebuffer} */ this.m_resolveFbo = null;
+ /** @type {gluShaderProgram.ShaderProgram} */ this.m_program = null;
+ /** @type {number} */ this.m_attrPositionLoc = -1;
+ /** @type {number} */ this.m_attrColorLoc = -1;
+ /** @type {number} */ this.m_renderWidth = fboParams.useFbo ? 2 * desiredViewportSize : gl.drawingBufferWidth;
+ /** @type {number} */ this.m_renderHeight = fboParams.useFbo ? 2 * desiredViewportSize : gl.drawingBufferHeight;
+ /** @type {number} */ this.m_viewportX = 0;
+ /** @type {number} */ this.m_viewportY = 0;
+ /** @type {deRandom.Random} */ this.m_rnd = new deRandom.Random(deString.deStringHash(this.name));
+ if (this.m_fboParams.useFbo)
+ assertMsgOptions(this.m_fboParams.numSamples >= 0, 'fboParams.numSamples < 0', false, true);
+ };
+
+ es3fMultisampleTests.MultisampleCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+
+ /** Copy the constructor */
+ es3fMultisampleTests.MultisampleCase.prototype.constructor = es3fMultisampleTests.MultisampleCase;
+
+ /* Rest states */
+ es3fMultisampleTests.MultisampleCase.prototype.deinit = function() {
+ gl.colorMask(true, true, true, true);
+ gl.depthMask(true);
+
+ gl.clearColor(0.0, 0.0, 0.0, 0.0);
+ gl.clearDepth(1.0);
+ gl.clearStencil(0);
+
+ gl.disable(gl.STENCIL_TEST);
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.BLEND)
+ gl.disable(gl.SAMPLE_COVERAGE);
+ gl.disable(gl.SAMPLE_ALPHA_TO_COVERAGE);
+
+ if (this.m_program) {
+ gl.deleteProgram(this.m_program.getProgram());
+ this.m_program = null;
+ }
+ if (this.m_msColorRbo) {
+ gl.deleteRenderbuffer(this.m_msColorRbo);
+ this.m_msColorRbo = null;
+ }
+ if (this.m_msDepthStencilRbo) {
+ gl.deleteRenderbuffer(this.m_msDepthStencilRbo);
+ this.m_msDepthStencilRbo = null;
+ }
+ if (this.m_resolveColorRbo) {
+ gl.deleteRenderbuffer(this.m_resolveColorRbo);
+ this.m_resolveColorRbo = null;
+ }
+
+ if (this.m_msFbo) {
+ gl.deleteFramebuffer(this.m_msFbo);
+ this.m_msFbo = null;
+ }
+ if (this.m_resolveFbo) {
+ gl.deleteFramebuffer(this.m_resolveFbo);
+ this.m_resolveFbo = null;
+ }
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ }
+
+ /**
+ * @protected
+ * @param {Array<number>} p0
+ * @param {Array<number>} p1
+ * @param {Array<number>} p2
+ * @param {Array<number>} c0
+ * @param {Array<number>} c1
+ * @param {Array<number>} c2
+ */
+ es3fMultisampleTests.MultisampleCase.prototype.renderTriangle_pAsVec3cAsVec4 = function(p0, p1, p2, c0, c1, c2) {
+ /** @type {Array<number>} */ var vertexPositions = [
+ p0[0], p0[1], p0[2], 1.0,
+ p1[0], p1[1], p1[2], 1.0,
+ p2[0], p2[1], p2[2], 1.0
+ ];
+ /** @type {Array<number>} */ var vertexColors = [
+ c0[0], c0[1], c0[2], c0[3],
+ c1[0], c1[1], c1[2], c1[3],
+ c2[0], c2[1], c2[2], c2[3]
+ ];
+
+ var posGLBuffer = gl.createBuffer();
+ /** @type {ArrayBufferView} */ var posBuffer = new Float32Array(vertexPositions);
+ gl.bindBuffer(gl.ARRAY_BUFFER, posGLBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, posBuffer, gl.STATIC_DRAW);
+
+ gl.enableVertexAttribArray(this.m_attrPositionLoc);
+ gl.vertexAttribPointer(this.m_attrPositionLoc, 4, gl.FLOAT, false, 0, 0);
+
+ var colGLBuffer = gl.createBuffer();
+ /** @type {ArrayBufferView} */ var colBuffer = new Float32Array(vertexColors);
+ gl.bindBuffer(gl.ARRAY_BUFFER, colGLBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, colBuffer, gl.STATIC_DRAW);
+
+ gl.enableVertexAttribArray(this.m_attrColorLoc);
+ gl.vertexAttribPointer(this.m_attrColorLoc, 4, gl.FLOAT, false, 0, 0);
+
+ gl.useProgram(this.m_program.getProgram());
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.deleteBuffer(colGLBuffer);
+ gl.deleteBuffer(posGLBuffer);
+ };
+
+ /**
+ * @protected
+ * @param {Array<number>} p0
+ * @param {Array<number>} p1
+ * @param {Array<number>} p2
+ * @param {Array<number>} color
+ */
+ es3fMultisampleTests.MultisampleCase.prototype.renderTriangle_pAsVec3WithColor = function(p0, p1, p2, color) {
+ this.renderTriangle_pAsVec3cAsVec4(p0, p1, p2, color, color, color);
+ };
+
+ /**
+ * @protected
+ * @param {Array<number>} p0
+ * @param {Array<number>} p1
+ * @param {Array<number>} p2
+ * @param {Array<number>} c0
+ * @param {Array<number>} c1
+ * @param {Array<number>} c2
+ */
+ es3fMultisampleTests.MultisampleCase.prototype.renderTriangle_pAsVec2 = function(p0, p1, p2, c0, c1, c2) {
+ this.renderTriangle_pAsVec3cAsVec4(
+ [p0[0], p0[1], 0.0],
+ [p1[0], p1[1], 0.0],
+ [p2[0], p2[1], 0.0],
+ c0, c1, c2);
+ };
+
+ /**
+ * @protected
+ * @param {Array<number>} p0
+ * @param {Array<number>} p1
+ * @param {Array<number>} p2
+ * @param {Array<number>} color
+ */
+ es3fMultisampleTests.MultisampleCase.prototype.renderTriangle_pAsVec2WithColor = function(p0, p1, p2, color) {
+ this.renderTriangle_pAsVec2(p0, p1, p2, color, color, color);
+ };
+
+ /**
+ * @protected
+ * @param {Array<number>} p0
+ * @param {Array<number>} p1
+ * @param {Array<number>} p2
+ * @param {Array<number>} p3
+ * @param {Array<number>} c0
+ * @param {Array<number>} c1
+ * @param {Array<number>} c2
+ * @param {Array<number>} c3
+ */
+ es3fMultisampleTests.MultisampleCase.prototype.renderQuad = function(p0, p1, p2, p3, c0, c1, c2, c3) {
+ this.renderTriangle_pAsVec2(p0, p1, p2, c0, c1, c2);
+ this.renderTriangle_pAsVec2(p2, p1, p3, c2, c1, c3);
+ };
+
+ /**
+ * @protected
+ * @param {Array<number>} p0
+ * @param {Array<number>} p1
+ * @param {Array<number>} p2
+ * @param {Array<number>} p3
+ * @param {Array<number>} color
+ */
+ es3fMultisampleTests.MultisampleCase.prototype.renderQuad_WithColor = function(p0, p1, p2, p3, color) {
+ this.renderQuad(p0, p1, p2, p3, color, color, color, color);
+ };
+
+ /**
+ * @protected
+ * @param {Array<number>} p0
+ * @param {Array<number>} p1
+ * @param {Array<number>} color
+ */
+ es3fMultisampleTests.MultisampleCase.prototype.renderLine = function(p0, p1, color) {
+ /** @type {Array<number>} */ var vertexPositions = [
+ p0[0], p0[1], 0.0, 1.0,
+ p1[0], p1[1], 0.0, 1.0
+ ];
+ /** @type {Array<number>} */ var vertexColors = [
+ color[0], color[1], color[2], color[3],
+ color[0], color[1], color[2], color[3]
+ ];
+
+ var posGLBuffer = gl.createBuffer();
+ /** @type {ArrayBufferView} */ var posBuffer = new Float32Array(vertexPositions);
+ gl.bindBuffer(gl.ARRAY_BUFFER, posGLBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, posBuffer, gl.STATIC_DRAW);
+
+ gl.enableVertexAttribArray(this.m_attrPositionLoc);
+ gl.vertexAttribPointer(this.m_attrPositionLoc, 4, gl.FLOAT, false, 0, 0);
+
+ var colGLBuffer = gl.createBuffer();
+ /** @type {ArrayBufferView} */ var colBuffer = new Float32Array(vertexColors);
+ gl.bindBuffer(gl.ARRAY_BUFFER, colGLBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, colBuffer, gl.STATIC_DRAW);
+
+ gl.enableVertexAttribArray(this.m_attrColorLoc);
+ gl.vertexAttribPointer(this.m_attrColorLoc, 4, gl.FLOAT, false, 0, 0);
+
+ gl.useProgram(this.m_program.getProgram());
+ gl.drawArrays(gl.LINES, 0, 2);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.deleteBuffer(colGLBuffer);
+ gl.deleteBuffer(posGLBuffer);
+ };
+
+ /**
+ * @protected
+ */
+ es3fMultisampleTests.MultisampleCase.prototype.randomizeViewport = function() {
+ this.m_viewportX = this.m_rnd.getInt(0, this.m_renderWidth - this.m_viewportSize);
+ this.m_viewportY = this.m_rnd.getInt(0, this.m_renderHeight - this.m_viewportSize);
+
+ gl.viewport(this.m_viewportX, this.m_viewportY, this.m_viewportSize, this.m_viewportSize);
+ };
+
+ /**
+ * @protected
+ * @return {tcuSurface.Surface}
+ */
+ es3fMultisampleTests.MultisampleCase.prototype.readImage = function() {
+ /** @type {tcuSurface.Surface} */
+ var dst = new tcuSurface.Surface(this.m_viewportSize, this.m_viewportSize);
+ /** @type {number} */ var pixelSize = dst.getAccess().getFormat().getPixelSize();
+ /** @type {number} */ var param = deMath.deIsPowerOfTwo32(pixelSize) ? Math.min(pixelSize, 8) : 1;
+ /** @type {gluTextureUtil.TransferFormat} */ var format = gluTextureUtil.getTransferFormat(dst.getAccess().getFormat());
+ /** @type {number} */ var width = dst.getAccess().getWidth();
+ /** @type {number} */ var height = dst.getAccess().getHeight();
+ if (this.m_fboParams.useFbo) {
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, this.m_resolveFbo);
+ gl.blitFramebuffer(0, 0, this.m_renderWidth, this.m_renderHeight, 0, 0, this.m_renderWidth, this.m_renderHeight, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, this.m_resolveFbo);
+
+ gl.pixelStorei(gl.PACK_ALIGNMENT, param);
+ gl.readPixels(this.m_viewportX, this.m_viewportY, width, height, format.format, format.dataType, dst.getAccess().getDataPtr());
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.m_msFbo);
+ }
+ else {
+ gl.pixelStorei(gl.PACK_ALIGNMENT, param);
+ gl.readPixels(this.m_viewportX, this.m_viewportY, width, height, format.format, format.dataType, dst.getAccess().getDataPtr());
+ }
+ return dst;
+ };
+
+ es3fMultisampleTests.MultisampleCase.prototype.init = function() {
+ /** @type {string} */ var vertShaderSource = '' +
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in mediump vec4 a_color;\n' +
+ 'out mediump vec4 v_color;\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ ' v_color = a_color;\n' +
+ '}\n';
+
+ /** @type {string} */ var fragShaderSource = '' +
+ '#version 300 es\n' +
+ 'in mediump vec4 v_color;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' o_color = v_color;\n' +
+ '}\n';
+
+ var numSamples = /** @type {number} */ (gl.getParameter(gl.SAMPLES));
+ if (!this.m_fboParams.useFbo && numSamples <= 1) {
+ var msg = 'No multisample buffers';
+ checkMessage(false, msg);
+ return false;
+ }
+
+ if (this.m_fboParams.useFbo) {
+ if (this.m_fboParams.numSamples > 0)
+ this.m_numSamples = this.m_fboParams.numSamples;
+ else {
+ bufferedLogToConsole('Querying maximum number of samples for ' + gluStrUtil.getPixelFormatName(gl.RGBA8) + ' with gl.getInternalformatParameter()');
+ var supportedSampleCountArray = /** @type {Int32Array} */ (gl.getInternalformatParameter(gl.RENDERBUFFER, gl.RGBA8, gl.SAMPLES));
+ if (supportedSampleCountArray.length == 0) {
+ var msg = 'No supported sample counts';
+ checkMessage(false, msg);
+ return false;
+ }
+ this.m_numSamples = supportedSampleCountArray[0];
+ }
+
+ bufferedLogToConsole('Using FBO of size (' + this.m_renderWidth + ', ' + this.m_renderHeight + ') with ' + this.m_numSamples + ' samples');
+ }
+ else {
+ // Query and log number of samples per pixel.
+ this.m_numSamples = numSamples;
+ bufferedLogToConsole('gl.SAMPLES =' + this.m_numSamples);
+ }
+
+ // Prepare program.
+
+ assertMsgOptions(!this.m_program, 'Program loaded when it should not be.', false, true);
+
+ this.m_program = new gluShaderProgram.ShaderProgram(
+ gl,
+ gluShaderProgram.makeVtxFragSources(vertShaderSource, fragShaderSource));
+
+ if (!this.m_program.isOk())
+ throw new Error('Failed to compile program');
+
+ this.m_attrPositionLoc = gl.getAttribLocation(this.m_program.getProgram(), 'a_position');
+ this.m_attrColorLoc = gl.getAttribLocation(this.m_program.getProgram(), 'a_color');
+
+ if (this.m_attrPositionLoc < 0 || this.m_attrColorLoc < 0) {
+ this.m_program = null;
+ throw new Error('Invalid attribute locations');
+ }
+
+ if (this.m_fboParams.useFbo) {
+ // Setup ms color RBO.
+ this.m_msColorRbo = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, this.m_msColorRbo);
+
+ /** @type {Int32Array} */ var supportedSampleCountArray = /** @type {Int32Array} */ (gl.getInternalformatParameter(gl.RENDERBUFFER, gl.RGBA8, gl.SAMPLES));
+ var maxSampleCount = supportedSampleCountArray[0];
+ if (maxSampleCount < this.m_numSamples) {
+ bufferedLogToConsole('skipping test: ' + this.m_numSamples + ' samples not supported; max is ' + maxSampleCount);
+ return false;
+ }
+
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'should be no GL error before renderbufferStorageMultisample');
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, gl.RGBA8, this.m_renderWidth, this.m_renderHeight);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'should be no GL error after renderbufferStorageMultisample');
+
+
+ if (this.m_fboParams.useDepth || this.m_fboParams.useStencil) {
+ // Setup ms depth & stencil RBO.
+ this.m_msDepthStencilRbo = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, this.m_msDepthStencilRbo);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, gl.DEPTH24_STENCIL8, this.m_renderWidth, this.m_renderHeight);
+ }
+
+ // Setup ms FBO.
+ this.m_msFbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.m_msFbo);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this.m_msColorRbo);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this.m_msDepthStencilRbo);
+
+ // Setup resolve color RBO.
+ this.m_resolveColorRbo = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, this.m_resolveColorRbo);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, this.m_renderWidth, this.m_renderHeight);
+
+ // Setup resolve FBO.
+ this.m_resolveFbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.m_resolveFbo);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this.m_resolveColorRbo);
+
+ // Use ms FBO.
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.m_msFbo);
+ }
+
+ // Get suitable viewport size.
+
+ this.m_viewportSize = Math.min(this.m_desiredViewportSize, this.m_renderWidth, this.m_renderHeight);
+ this.randomizeViewport();
+ return true;
+ };
+
+ /**
+ * Base class for cases testing the value of sample count.
+ *
+ * Draws a test pattern (defined by renderPattern() of an inheriting class)
+ * and counts the number of distinct colors in the resulting image. That
+ * number should be at least the value of sample count plus one. This is
+ * repeated with increased values of m_currentIteration until this correct
+ * number of colors is detected or m_currentIteration reaches
+ * m_maxNumIterations.
+ *
+ * @extends {es3fMultisampleTests.MultisampleCase}
+ * @constructor
+ * @param {string} name
+ * @param {string} desc
+ * @param {es3fMultisampleTests.FboParams} fboParams
+ */
+ es3fMultisampleTests.NumSamplesCase = function(name, desc, fboParams) {
+ es3fMultisampleTests.MultisampleCase.call(this, name, desc, 256, fboParams);
+ /** @type {number} */ var DEFAULT_MAX_NUM_ITERATIONS = 16;
+ /** @type {number} */ this.m_currentIteration = 0;
+ /** @type {number} */ this.m_maxNumIterations = es3fMultisampleTests.getIterationCount(DEFAULT_MAX_NUM_ITERATIONS);
+ /** @type {Array<tcuRGBA.RGBA>} */ this.m_detectedColors = [];
+ };
+
+ es3fMultisampleTests.NumSamplesCase.prototype = Object.create(es3fMultisampleTests.MultisampleCase.prototype);
+
+ /** Copy the constructor */
+ es3fMultisampleTests.NumSamplesCase.prototype.constructor = es3fMultisampleTests.NumSamplesCase;
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fMultisampleTests.NumSamplesCase.prototype.iterate = function() {
+ this.randomizeViewport();
+
+ gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ this.renderPattern();
+
+ // Read and log rendered image.
+
+ /** @type {tcuSurface.Surface} */ var renderedImg = this.readImage();
+ tcuLogImage.logImage('RenderedImage', 'Rendered image', renderedImg.getAccess());
+
+ // Detect new, previously unseen colors from image.
+
+ /** @type {number} */ var requiredNumDistinctColors = this.m_numSamples + 1;
+
+ // If the number of samples is high (64 or more), we need to lower the threshold for detecting unique colors, otherwise two expected unique colors would be treated as the same color.
+ var threshold = Math.min(3, Math.floor(255 / this.m_numSamples) - 1);
+ var thresholdRGBA = tcuRGBA.newRGBAComponents(threshold, threshold, threshold, threshold);
+
+ for (var y = 0; y < renderedImg.getHeight() && this.m_detectedColors.length < requiredNumDistinctColors; y++)
+ for (var x = 0; x < renderedImg.getWidth() && this.m_detectedColors.length < requiredNumDistinctColors; x++) {
+ /** @type {tcuRGBA.RGBA} */ var color = new tcuRGBA.RGBA(renderedImg.getPixel(x, y));
+
+ /** @type {number} */ var i;
+ for (i = 0; i < this.m_detectedColors.length; i++) {
+ if (tcuRGBA.compareThreshold(color, this.m_detectedColors[i], thresholdRGBA))
+ break;
+ }
+
+ if (i === this.m_detectedColors.length)
+ this.m_detectedColors.push(color); // Color not previously detected.
+ }
+
+ // Log results.
+
+ bufferedLogToConsole('Number of distinct colors detected so far: ' + (this.m_detectedColors.length >= requiredNumDistinctColors ? 'at least ' : '') + this.m_detectedColors.length);
+
+
+ if (this.m_detectedColors.length < requiredNumDistinctColors) {
+ // Haven't detected enough different colors yet.
+
+ this.m_currentIteration++;
+
+ if (this.m_currentIteration >= this.m_maxNumIterations) {
+ testFailedOptions('Failure: Number of distinct colors detected is lower than sample count+1', false);
+ return tcuTestCase.IterateResult.STOP;
+ }
+ else {
+ bufferedLogToConsole('The number of distinct colors detected is lower than sample count+1 - trying again with a slightly altered pattern');
+ return tcuTestCase.IterateResult.CONTINUE;
+ }
+ }
+ else {
+ testPassedOptions('Success: The number of distinct colors detected is at least sample count+1', true);
+ return tcuTestCase.IterateResult.STOP;
+ }
+ };
+
+ /**
+ * @extends {es3fMultisampleTests.NumSamplesCase}
+ * @constructor
+ * @param {string} name
+ * @param {string} desc
+ * @param {number=} numFboSamples
+ */
+ es3fMultisampleTests.PolygonNumSamplesCase = function(name, desc, numFboSamples) {
+ numFboSamples = numFboSamples === undefined ? 0 : numFboSamples;
+ /** @type {es3fMultisampleTests.FboParams} */
+ var params = numFboSamples >= 0 ? new es3fMultisampleTests.FboParams(numFboSamples, false, false) : new es3fMultisampleTests.FboParams();
+ es3fMultisampleTests.NumSamplesCase.call(this, name, desc, params);
+ };
+
+ es3fMultisampleTests.PolygonNumSamplesCase.prototype = Object.create(es3fMultisampleTests.NumSamplesCase.prototype);
+
+ /** Copy the constructor */
+ es3fMultisampleTests.PolygonNumSamplesCase.prototype.constructor = es3fMultisampleTests.PolygonNumSamplesCase;
+
+ es3fMultisampleTests.PolygonNumSamplesCase.prototype.renderPattern = function() {
+ // The test pattern consists of several triangles with edges at different angles.
+
+ /** @type {number} */ var numTriangles = 25;
+ for (var i = 0; i < numTriangles; i++) {
+ /** @type {number} */ var angle0 = 2.0 * Math.PI * i / numTriangles + 0.001 * this.m_currentIteration;
+ /** @type {number} */ var angle1 = 2.0 * Math.PI * (i + 0.5) / numTriangles + 0.001 * this.m_currentIteration;
+
+ this.renderTriangle_pAsVec2WithColor(
+ [0.0, 0.0],
+ [Math.cos(angle0) * 0.95, Math.sin(angle0) * 0.95],
+ [Math.cos(angle1) * 0.95, Math.sin(angle1) * 0.95],
+ [1.0, 1.0, 1.0, 1.0]);
+ }
+ };
+
+ /**
+ * @extends {es3fMultisampleTests.NumSamplesCase}
+ * @constructor
+ * @param {string} name
+ * @param {string} desc
+ * @param {number=} numFboSamples
+ */
+ es3fMultisampleTests.LineNumSamplesCase = function(name, desc, numFboSamples) {
+ numFboSamples = numFboSamples === undefined ? 0 : numFboSamples;
+ /** @type {es3fMultisampleTests.FboParams} */
+ var params = numFboSamples >= 0 ? new es3fMultisampleTests.FboParams(numFboSamples, false, false) : new es3fMultisampleTests.FboParams();
+ es3fMultisampleTests.NumSamplesCase.call(this, name, desc, params);
+ };
+
+ es3fMultisampleTests.LineNumSamplesCase.prototype = Object.create(es3fMultisampleTests.NumSamplesCase.prototype);
+
+ /** Copy the constructor */
+ es3fMultisampleTests.LineNumSamplesCase.prototype.constructor = es3fMultisampleTests.LineNumSamplesCase;
+
+ es3fMultisampleTests.LineNumSamplesCase.prototype.renderPattern = function() {
+ // The test pattern consists of several lines at different angles.
+
+ // We scale the number of lines based on the viewport size. This is because a gl line's thickness is
+ // constant in pixel units, i.e. they get relatively thicker as viewport size decreases. Thus we must
+ // decrease the number of lines in order to decrease the extent of overlap among the lines in the
+ // center of the pattern.
+ /** @type {number} */ var numLines = Math.floor(100.0 * Math.sqrt(this.m_viewportSize / 256.0));
+
+ for (var i = 0; i < numLines; i++) {
+ /** @type {number} */ var angle = 2.0 * Math.PI * i / numLines + 0.001 * this.m_currentIteration;
+ this.renderLine([0.0, 0.0], [Math.cos(angle) * 0.95, Math.sin(angle) * 0.95], [1.0, 1.0, 1.0, 1.0]);
+ }
+ };
+
+ /**
+ * Case testing behaviour of common edges when multisampling.
+ *
+ * Draws a number of test patterns, each with a number of quads, each made
+ * of two triangles, rotated at different angles. The inner edge inside the
+ * quad (i.e. the common edge of the two triangles) still should not be
+ * visible, despite multisampling - i.e. the two triangles forming the quad
+ * should never get any common coverage bits in any pixel.
+ *
+ * @extends {es3fMultisampleTests.MultisampleCase}
+ * @constructor
+ * @param {string} name
+ * @param {string} desc
+ * @param {es3fMultisampleTests.CommonEdgeCase.CaseType} caseType
+ * @param {number} numFboSamples
+ */
+ es3fMultisampleTests.CommonEdgeCase = function(name, desc, caseType, numFboSamples) {
+ /** @type {number} */ var cases = caseType === es3fMultisampleTests.CommonEdgeCase.CaseType.SMALL_QUADS ? 128 : 32;
+ numFboSamples = numFboSamples === undefined ? 0 : numFboSamples;
+ /** @type {es3fMultisampleTests.FboParams} */
+ var params = numFboSamples >= 0 ? new es3fMultisampleTests.FboParams(numFboSamples, false, false) : new es3fMultisampleTests.FboParams();
+
+ es3fMultisampleTests.MultisampleCase.call(this, name, desc, cases, params);
+ /** @type {number} */ var DEFAULT_SMALL_QUADS_ITERATIONS = 16;
+ /** @type {number} */ var DEFAULT_BIGGER_THAN_VIEWPORT_QUAD_ITERATIONS = 64; // 8*8
+ /** @type {es3fMultisampleTests.CommonEdgeCase.CaseType} */ this.m_caseType = caseType;
+ /** @type {number} */ this.m_currentIteration = 0;
+ /** @type {number} */
+ this.m_numIterations = caseType === es3fMultisampleTests.CommonEdgeCase.CaseType.SMALL_QUADS ? es3fMultisampleTests.getIterationCount(DEFAULT_SMALL_QUADS_ITERATIONS) :
+ caseType === es3fMultisampleTests.CommonEdgeCase.CaseType.BIGGER_THAN_VIEWPORT_QUAD ? es3fMultisampleTests.getIterationCount(DEFAULT_BIGGER_THAN_VIEWPORT_QUAD_ITERATIONS) :
+ 8;
+ };
+
+ es3fMultisampleTests.CommonEdgeCase.prototype = Object.create(es3fMultisampleTests.MultisampleCase.prototype);
+
+ /** Copy the constructor */
+ es3fMultisampleTests.CommonEdgeCase.prototype.constructor = es3fMultisampleTests.CommonEdgeCase;
+
+ /**
+ * @enum {number}
+ */
+ es3fMultisampleTests.CommonEdgeCase.CaseType = {
+ SMALL_QUADS: 0, //!< Draw several small quads per iteration.
+ BIGGER_THAN_VIEWPORT_QUAD: 1, //!< Draw one bigger-than-viewport quad per iteration.
+ FIT_VIEWPORT_QUAD: 2 //!< Draw one exactly viewport-sized, axis aligned quad per iteration.
+ };
+
+ es3fMultisampleTests.CommonEdgeCase.prototype.init = function() {
+ var inited = es3fMultisampleTests.MultisampleCase.prototype.init.call(this);
+ if (!inited) {
+ return false;
+ }
+
+ if (this.m_caseType === es3fMultisampleTests.CommonEdgeCase.CaseType.SMALL_QUADS) {
+ // Check for a big enough viewport. With too small viewports the test case can't analyze the resulting image well enough.
+
+ /** @type {number} */ var minViewportSize = 32;
+
+ if (this.m_viewportSize < minViewportSize)
+ throw new Error('Render target width or height too low (is ' + this.m_viewportSize + ', should be at least ' + minViewportSize + ')');
+ }
+
+ gl.enable(gl.BLEND);
+ gl.blendEquation(gl.FUNC_ADD);
+ gl.blendFunc(gl.ONE, gl.ONE);
+ bufferedLogToConsole('Additive blending enabled in order to detect (erroneously) overlapping samples');
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fMultisampleTests.CommonEdgeCase.prototype.iterate = function() {
+ /** @type {tcuSurface.Surface} */ var errorImg = new tcuSurface.Surface(this.m_viewportSize, this.m_viewportSize);
+
+ this.randomizeViewport();
+
+ gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ // Draw test pattern. Test patterns consist of quads formed with two triangles.
+ // After drawing the pattern, we check that the interior pixels of each quad are
+ // all the same color - this is meant to verify that there are no artifacts on the inner edge.
+
+ /** @type {Array<es3fMultisampleTests.QuadCorners>} */ var unicoloredRegions = [];
+
+ /** @type {Array<Array<number>>} */ var corners;
+ /** @type {number} */ var angleCos;
+ /** @type {number} */ var angleSin;
+ /** @type {number} */ var angle;
+ /** @type {number} */ var quadDiagLen;
+ /** @type {number} */ var unicolorRegionScale;
+ /** @type {number} */ var quadBaseAngleNdx
+ /** @type {number} */ var quadSubAngleNdx;
+
+ if (this.m_caseType == es3fMultisampleTests.CommonEdgeCase.CaseType.SMALL_QUADS) {
+ // Draw several quads, rotated at different angles.
+
+ quadDiagLen = 2.0 / 3.0 * 0.9; // \note Fit 3 quads in both x and y directions.
+
+
+ // \note First and second iteration get exact 0 (and 90, 180, 270) and 45 (and 135, 225, 315) angle quads, as they are kind of a special case.
+
+ if (this.m_currentIteration === 0) {
+ angleCos = 1.0;
+ angleSin = 0.0;
+ }
+ else if (this.m_currentIteration === 1) {
+ angleCos = Math.SQRT1_2;
+ angleSin = Math.SQRT1_2;
+ }
+ else {
+ angle = 0.5 * Math.PI * (this.m_currentIteration - 1) / (this.m_numIterations - 1);
+ angleCos = Math.cos(angle);
+ angleSin = Math.sin(angle);
+ }
+
+ corners = [
+ deMath.scale([angleCos, angleSin], 0.5 * quadDiagLen),
+ deMath.scale([-angleSin, angleCos], 0.5 * quadDiagLen),
+ deMath.scale([-angleCos, -angleSin], 0.5 * quadDiagLen),
+ deMath.scale([angleSin, -angleCos], 0.5 * quadDiagLen)
+ ];
+
+ // Draw 8 quads.
+ // First four are rotated at angles angle+0, angle+90, angle+180 and angle+270.
+ // Last four are rotated the same angles as the first four, but the ordering of the last triangle's vertices is reversed.
+
+ for (var quadNdx = 0; quadNdx < 8; quadNdx++) {
+ /** @type {Array<number>} */
+ var center = deMath.addScalar(
+ deMath.scale([quadNdx % 3, quadNdx / 3], (2.0 - quadDiagLen)/ 2.0),
+ (-0.5 * (2.0 - quadDiagLen)));
+
+ this.renderTriangle_pAsVec2WithColor(
+ deMath.add(corners[(0 + quadNdx) % 4], center),
+ deMath.add(corners[(1 + quadNdx) % 4], center),
+ deMath.add(corners[(2 + quadNdx) % 4], center),
+ [0.5, 0.5, 0.5, 1.0]);
+
+ if (quadNdx >= 4) {
+ this.renderTriangle_pAsVec2WithColor(
+ deMath.add(corners[(3 + quadNdx) % 4], center),
+ deMath.add(corners[(2 + quadNdx) % 4], center),
+ deMath.add(corners[(0 + quadNdx) % 4], center),
+ [0.5, 0.5, 0.5, 1.0]);
+ }
+ else {
+ this.renderTriangle_pAsVec2WithColor(
+ deMath.add(corners[(0 + quadNdx) % 4], center),
+ deMath.add(corners[(2 + quadNdx) % 4], center),
+ deMath.add(corners[(3 + quadNdx) % 4], center),
+ [0.5, 0.5, 0.5, 1.0]);
+ }
+
+ // The size of the 'interior' of a quad is assumed to be approximately unicolorRegionScale*<actual size of quad>.
+ // By 'interior' we here mean the region of non-boundary pixels of the rendered quad for which we can safely assume
+ // that it has all coverage bits set to 1, for every pixel.
+ unicolorRegionScale = 1.0 - 6.0 * 2.0 / this.m_viewportSize / quadDiagLen;
+ unicoloredRegions.push(
+ new es3fMultisampleTests.QuadCorners(
+ deMath.add(center, deMath.scale(corners[0], unicolorRegionScale)),
+ deMath.add(center, deMath.scale(corners[1], unicolorRegionScale)),
+ deMath.add(center, deMath.scale(corners[2], unicolorRegionScale)),
+ deMath.add(center, deMath.scale(corners[3], unicolorRegionScale))));
+ }
+ }
+ else if (this.m_caseType === es3fMultisampleTests.CommonEdgeCase.CaseType.BIGGER_THAN_VIEWPORT_QUAD) {
+ // Draw a bigger-than-viewport quad, rotated at an angle depending on m_currentIteration.
+
+ quadBaseAngleNdx = Math.floor(this.m_currentIteration / 8);
+ quadSubAngleNdx = this.m_currentIteration % 8;
+
+ if (quadBaseAngleNdx === 0) {
+ angleCos = 1.0;
+ angleSin = 0.0;
+ }
+ else if (quadBaseAngleNdx === 1) {
+ angleCos = Math.SQRT1_2;
+ angleSin = Math.SQRT1_2;
+ }
+ else {
+ angle = 0.5 * Math.PI * (this.m_currentIteration - 1) / (this.m_numIterations - 1);
+ angleCos = Math.cos(angle);
+ angleSin = Math.sin(angle);
+ }
+
+ quadDiagLen = 2.5 / Math.max(angleCos, angleSin);
+
+ corners = [
+ deMath.scale([angleCos, angleSin], 0.5 * quadDiagLen),
+ deMath.scale([-angleSin, angleCos], 0.5 * quadDiagLen),
+ deMath.scale([-angleCos, -angleSin], 0.5 * quadDiagLen),
+ deMath.scale([angleSin, -angleCos], 0.5 * quadDiagLen)
+ ];
+
+ this.renderTriangle_pAsVec2WithColor(
+ corners[(0 + quadSubAngleNdx) % 4],
+ corners[(1 + quadSubAngleNdx) % 4],
+ corners[(2 + quadSubAngleNdx) % 4],
+ [0.5, 0.5, 0.5, 1.0]);
+
+ if (quadSubAngleNdx >= 4) {
+ this.renderTriangle_pAsVec2WithColor(
+ corners[(3 + quadSubAngleNdx) % 4],
+ corners[(2 + quadSubAngleNdx) % 4],
+ corners[(0 + quadSubAngleNdx) % 4],
+ [0.5, 0.5, 0.5, 1.0]);
+ }
+ else {
+ this.renderTriangle_pAsVec2WithColor(
+ corners[(0 + quadSubAngleNdx) % 4],
+ corners[(2 + quadSubAngleNdx) % 4],
+ corners[(3 + quadSubAngleNdx) % 4],
+ [0.5, 0.5, 0.5, 1.0]);
+ }
+
+ unicolorRegionScale = 1.0 - 6.0 * 2.0 / this.m_viewportSize / quadDiagLen;
+ unicoloredRegions.push(
+ new es3fMultisampleTests.QuadCorners(
+ deMath.scale(corners[0], unicolorRegionScale),
+ deMath.scale(corners[1], unicolorRegionScale),
+ deMath.scale(corners[2], unicolorRegionScale),
+ deMath.scale(corners[3], unicolorRegionScale)));
+ }
+ else if (this.m_caseType === es3fMultisampleTests.CommonEdgeCase.CaseType.FIT_VIEWPORT_QUAD) {
+ // Draw an exactly viewport-sized quad, rotated by multiples of 90 degrees angle depending on m_currentIteration.
+
+ quadSubAngleNdx = this.m_currentIteration % 8;
+
+ corners = [
+ [1.0, 1.0],
+ [-1.0, 1.0],
+ [-1.0, -1.0],
+ [1.0, -1.0]
+ ];
+
+ this.renderTriangle_pAsVec2WithColor(
+ corners[(0 + quadSubAngleNdx) % 4],
+ corners[(1 + quadSubAngleNdx) % 4],
+ corners[(2 + quadSubAngleNdx) % 4],
+ [0.5, 0.5, 0.5, 1.0]);
+
+ if (quadSubAngleNdx >= 4) {
+ this.renderTriangle_pAsVec2WithColor(
+ corners[(3 + quadSubAngleNdx) % 4],
+ corners[(2 + quadSubAngleNdx) % 4],
+ corners[(0 + quadSubAngleNdx) % 4],
+ [0.5, 0.5, 0.5, 1.0]);
+ }
+ else {
+ this.renderTriangle_pAsVec2WithColor(
+ corners[(0 + quadSubAngleNdx) % 4],
+ corners[(2 + quadSubAngleNdx) % 4],
+ corners[(3 + quadSubAngleNdx) % 4],
+ [0.5, 0.5, 0.5, 1.0]);
+ }
+
+ unicoloredRegions.push(new es3fMultisampleTests.QuadCorners(corners[0], corners[1], corners[2], corners[3]));
+ }
+ else
+ throw new Error('CaseType not supported.');
+
+ // Read pixels and check unicolored regions.
+
+ /** @type {tcuSurface.Surface} */ var renderedImg = this.readImage();
+
+ errorImg.getAccess().clear([0.0, 1.0, 0.0, 1.0]);
+ tcuLogImage.logImage('RenderedImage', 'Rendered image', renderedImg.getAccess());
+
+ /** @type {boolean} */ var errorsDetected = false;
+ for (var i = 0; i < unicoloredRegions.length; i++) {
+ /** @type {es3fMultisampleTests.QuadCorners} */ var region = unicoloredRegions[i];
+ /** @type {Array<number>} */ var p0Win = deMath.scale(deMath.addScalar(region.p0, 1.0), 0.5 * (this.m_viewportSize - 1) + 0.5);
+ /** @type {Array<number>} */ var p1Win = deMath.scale(deMath.addScalar(region.p1, 1.0), 0.5 * (this.m_viewportSize - 1) + 0.5);
+ /** @type {Array<number>} */ var p2Win = deMath.scale(deMath.addScalar(region.p2, 1.0), 0.5 * (this.m_viewportSize - 1) + 0.5);
+ /** @type {Array<number>} */ var p3Win = deMath.scale(deMath.addScalar(region.p3, 1.0), 0.5 * (this.m_viewportSize - 1) + 0.5);
+ /** @type {boolean} */ var errorsInCurrentRegion = !es3fMultisampleTests.isPixelRegionUnicolored(renderedImg, p0Win, p1Win, p2Win, p3Win);
+
+ if (errorsInCurrentRegion)
+ es3fMultisampleTests.drawUnicolorTestErrors(renderedImg, errorImg.getAccess(), p0Win, p1Win, p2Win, p3Win);
+
+ errorsDetected = errorsDetected || errorsInCurrentRegion;
+ }
+
+ this.m_currentIteration++;
+
+ if (errorsDetected) {
+ bufferedLogToConsole('Failure: Not all quad interiors seem unicolored - common-edge artifacts?');
+ bufferedLogToConsole('Erroneous pixels are drawn red in the following image');
+ tcuLogImage.logImage('RenderedImageWithErrors', 'Rendered image with errors marked', renderedImg.getAccess());
+ tcuLogImage.logImage('ErrorsOnly', 'Image with error pixels only', errorImg.getAccess());
+ testFailedOptions('Failed: iteration ' + (this.m_currentIteration - 1), false);
+ return tcuTestCase.IterateResult.STOP;
+ }
+ else if (this.m_currentIteration < this.m_numIterations) {
+ bufferedLogToConsole('Quads seem OK - moving on to next pattern');
+ return tcuTestCase.IterateResult.CONTINUE;
+ }
+ else {
+ bufferedLogToConsole('Success: All quad interiors seem unicolored (no common-edge artifacts)');
+ testPassedOptions('Passed: iteration ' + (this.m_currentIteration - 1), true);
+ return tcuTestCase.IterateResult.STOP;
+ }
+ };
+
+ /**
+ * Test that depth values are per-sample.
+ *
+ * Draws intersecting, differently-colored polygons and checks that there
+ * are at least sample count+1 distinct colors present, due to some of the
+ * samples at the intersection line belonging to one and some to another
+ * polygon.
+ *
+ * @extends {es3fMultisampleTests.NumSamplesCase}
+ * @constructor
+ * @param {string} name
+ * @param {string} desc
+ * @param {number=} numFboSamples
+ */
+ es3fMultisampleTests.SampleDepthCase = function(name, desc, numFboSamples) {
+ numFboSamples = numFboSamples === undefined ? 0 : numFboSamples;
+ /** @type {es3fMultisampleTests.FboParams} */
+ var params = numFboSamples >= 0 ? new es3fMultisampleTests.FboParams(numFboSamples, true, false) : new es3fMultisampleTests.FboParams();
+ es3fMultisampleTests.NumSamplesCase.call(this, name, desc, params);
+ };
+
+ es3fMultisampleTests.SampleDepthCase.prototype = Object.create(es3fMultisampleTests.NumSamplesCase.prototype);
+
+ /** Copy the constructor */
+ es3fMultisampleTests.SampleDepthCase.prototype.constructor = es3fMultisampleTests.SampleDepthCase;
+
+ es3fMultisampleTests.SampleDepthCase.prototype.init = function() {
+ var inited = es3fMultisampleTests.MultisampleCase.prototype.init.call(this);
+ if (!inited) {
+ return false;
+ }
+
+ gl.enable(gl.DEPTH_TEST);
+ gl.depthFunc(gl.LESS);
+
+ bufferedLogToConsole('Depth test enabled, depth func is gl.LESS');
+ bufferedLogToConsole('Drawing several bigger-than-viewport black or white polygons intersecting each other');
+ };
+
+ es3fMultisampleTests.SampleDepthCase.prototype.renderPattern = function() {
+ gl.clearColor(0.0, 0.0, 0.0, 0.0);
+ gl.clearDepth(1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ /** @type {number} */ var numPolygons = 50;
+
+ for (var i = 0; i < numPolygons; i++) {
+ /** @type {Array<number>} */ var color = i % 2 == 0 ? [1.0, 1.0, 1.0, 1.0] : [0.0, 0.0, 0.0, 1.0];
+ /** @type {number} */ var angle = 2.0 * Math.PI * i / numPolygons + 0.001 * this.m_currentIteration;
+ /** @type {Array<number>} */ var pt0 = [3.0 * Math.cos(angle + 2.0 * Math.PI * 0.0 / 3.0), 3.0 * Math.sin(angle + 2.0 * Math.PI * 0.0 / 3.0), 1.0];
+ /** @type {Array<number>} */ var pt1 = [3.0 * Math.cos(angle + 2.0 * Math.PI * 1.0 / 3.0), 3.0 * Math.sin(angle + 2.0 * Math.PI * 1.0 / 3.0), 0.0];
+ /** @type {Array<number>} */ var pt2 = [3.0 * Math.cos(angle + 2.0 * Math.PI * 2.0 / 3.0), 3.0 * Math.sin(angle + 2.0 * Math.PI * 2.0 / 3.0), 0.0];
+
+ this.renderTriangle_pAsVec3WithColor(pt0, pt1, pt2, color);
+ }
+ };
+
+ /**
+ * Test that stencil buffer values are per-sample.
+ *
+ * Draws a unicolored pattern and marks drawn samples in stencil buffer;
+ * then clears and draws a viewport-size quad with that color and with
+ * proper stencil test such that the resulting image should be exactly the
+ * same as after the pattern was first drawn.
+ *
+ * @extends {es3fMultisampleTests.MultisampleCase}
+ * @constructor
+ * @param {string} name
+ * @param {string} desc
+ * @param {number=} numFboSamples
+ */
+ es3fMultisampleTests.SampleStencilCase = function(name, desc, numFboSamples) {
+ numFboSamples = numFboSamples === undefined ? 0 : numFboSamples;
+ /** @type {es3fMultisampleTests.FboParams} */
+ var params = numFboSamples >= 0 ? new es3fMultisampleTests.FboParams(numFboSamples, false, true) : new es3fMultisampleTests.FboParams();
+ es3fMultisampleTests.MultisampleCase.call(this, name, desc, 256, params);
+ };
+
+ es3fMultisampleTests.SampleStencilCase.prototype = Object.create(es3fMultisampleTests.MultisampleCase.prototype);
+
+ /** Copy the constructor */
+ es3fMultisampleTests.SampleStencilCase.prototype.constructor = es3fMultisampleTests.SampleStencilCase;
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fMultisampleTests.SampleStencilCase.prototype.iterate = function() {
+ this.randomizeViewport();
+
+ gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ gl.clearStencil(0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ gl.enable(gl.STENCIL_TEST);
+ gl.stencilFunc(gl.ALWAYS, 1, 1);
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
+
+ bufferedLogToConsole('Drawing a pattern with gl.stencilFunc(gl.ALWAYS, 1, 1) and gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE)');
+
+ /** @type {number} */ var numTriangles = 25;
+ for (var i = 0; i < numTriangles; i++) {
+ /** @type {number} */ var angle0 = 2.0 * Math.PI * i / numTriangles;
+ /** @type {number} */ var angle1 = 2.0 * Math.PI * (i + 0.5) / numTriangles;
+
+ this.renderTriangle_pAsVec2WithColor(
+ [0.0, 0.0],
+ [Math.cos(angle0) * 0.95, Math.sin(angle0) * 0.95],
+ [Math.cos(angle1) * 0.95, Math.sin(angle1) * 0.95],
+ [1.0, 1.0, 1.0, 1.0]);
+ }
+
+ /** @type {tcuSurface.Surface} */ var renderedImgFirst = this.readImage();
+ tcuLogImage.logImage('RenderedImgFirst', 'First image rendered', renderedImgFirst.getAccess());
+ bufferedLogToConsole('Clearing color buffer to black');
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.stencilFunc(gl.EQUAL, 1, 1);
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
+
+ bufferedLogToConsole('Checking that color buffer was actually cleared to black');
+
+ /** @type {tcuSurface.Surface} */ var clearedImg = this.readImage();
+
+ for (var y = 0; y < clearedImg.getHeight(); y++)
+ for (var x = 0; x < clearedImg.getWidth(); x++) {
+ /** @type {tcuRGBA.RGBA} */ var clr = new tcuRGBA.RGBA(clearedImg.getPixel(x, y));
+ if (!clr.equals(tcuRGBA.RGBA.black)) {
+ bufferedLogToConsole('Failure: first non-black pixel, color ' + clr.toString() + ', detected at coordinates (' + x + ', ' + y + ')');
+ tcuLogImage.logImage('ClearedImg', 'Image after clearing, erroneously non-black', clearedImg.getAccess());
+ testFailedOptions('Failed', false);
+ return tcuTestCase.IterateResult.STOP;
+ }
+ }
+
+ bufferedLogToConsole('Drawing a viewport-sized quad with gl.stencilFunc(gl.EQUAL, 1, 1) and gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP) - should result in same image as the first');
+
+ this.renderQuad_WithColor(
+ [-1.0, -1.0],
+ [1.0, -1.0],
+ [-1.0, 1.0],
+ [1.0, 1.0],
+ [1.0, 1.0, 1.0, 1.0]);
+
+ /** @type {tcuSurface.Surface} */ var renderedImgSecond = this.readImage();
+ tcuLogImage.logImage('RenderedImgSecond', 'Second image rendered', renderedImgSecond.getAccess());
+ /** @type {boolean} */
+ var passed = tcuImageCompare.pixelThresholdCompare(
+ 'ImageCompare',
+ 'Image comparison',
+ renderedImgFirst,
+ renderedImgSecond,
+ [0,0,0,0]);
+
+ if (passed) {
+ bufferedLogToConsole('Success: The two images rendered are identical');
+ testPassedOptions('Passed', true);
+ }
+ else
+ testFailedOptions('Failed', false);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * Tests coverage mask generation proportionality property.
+ *
+ * Tests that the number of coverage bits in a coverage mask created by
+ * gl.SAMPLE_ALPHA_TO_COVERAGE or gl.SAMPLE_COVERAGE is, on average,
+ * proportional to the alpha or coverage value, respectively. Draws
+ * multiple frames, each time increasing the alpha or coverage value used,
+ * and checks that the average color is changing appropriately.
+ *
+ * @extends {es3fMultisampleTests.MultisampleCase}
+ * @constructor
+ * @param {string} name
+ * @param {string} desc
+ * @param {es3fMultisampleTests.MaskProportionalityCase.CaseType} type
+ * @param {number=} numFboSamples
+ */
+ es3fMultisampleTests.MaskProportionalityCase = function(name, desc, type, numFboSamples) {
+ numFboSamples = numFboSamples === undefined ? 0 : numFboSamples;
+ /** @type {es3fMultisampleTests.FboParams} */
+ var params = numFboSamples >= 0 ? new es3fMultisampleTests.FboParams(numFboSamples, false, false) : new es3fMultisampleTests.FboParams();
+ es3fMultisampleTests.MultisampleCase.call(this, name, desc, 32, params);
+ /** @type {es3fMultisampleTests.MaskProportionalityCase.CaseType} */ this.m_type = type;
+ /** @type {number} */ this.m_numIterations;
+ /** @type {number} */ this.m_currentIteration = 0;
+ /** @type {number} */ this.m_previousIterationColorSum = -1;
+ };
+
+ es3fMultisampleTests.MaskProportionalityCase.prototype = Object.create(es3fMultisampleTests.MultisampleCase.prototype);
+
+ /** Copy the constructor */
+ es3fMultisampleTests.MaskProportionalityCase.prototype.constructor = es3fMultisampleTests.MaskProportionalityCase;
+
+ /**
+ * @enum {number}
+ */
+ es3fMultisampleTests.MaskProportionalityCase.CaseType = {
+ ALPHA_TO_COVERAGE: 0,
+ SAMPLE_COVERAGE: 1,
+ SAMPLE_COVERAGE_INVERTED: 2
+ };
+
+ es3fMultisampleTests.MaskProportionalityCase.prototype.init = function() {
+ var inited = es3fMultisampleTests.MultisampleCase.prototype.init.call(this);
+ if (!inited) {
+ return false;
+ }
+
+ if (this.m_type == es3fMultisampleTests.MaskProportionalityCase.CaseType.ALPHA_TO_COVERAGE) {
+ gl.enable(gl.SAMPLE_ALPHA_TO_COVERAGE);
+ bufferedLogToConsole('gl.SAMPLE_ALPHA_TO_COVERAGE is enabled');
+ }
+ else {
+ assertMsgOptions(
+ this.m_type == es3fMultisampleTests.MaskProportionalityCase.CaseType.SAMPLE_COVERAGE ||
+ this.m_type == es3fMultisampleTests.MaskProportionalityCase.CaseType.SAMPLE_COVERAGE_INVERTED,
+ 'CaseType should be SAMPLE_COVERAGE or SAMPLE_COVERAGE_INVERTED', false, true);
+
+ gl.enable(gl.SAMPLE_COVERAGE);
+ bufferedLogToConsole('gl.SAMPLE_COVERAGE is enabled');
+ }
+
+ this.m_numIterations = Math.max(2, es3fMultisampleTests.getIterationCount(this.m_numSamples * 5));
+
+ this.randomizeViewport(); // \note Using the same viewport for every iteration since coverage mask may depend on window-relative pixel coordinate.
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fMultisampleTests.MaskProportionalityCase.prototype.iterate = function() {
+ bufferedLogToConsole('Clearing color to black');
+ gl.colorMask(true, true, true, true);
+ gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ if (this.m_type === es3fMultisampleTests.MaskProportionalityCase.CaseType.ALPHA_TO_COVERAGE) {
+ gl.colorMask(true, true, true, false);
+ bufferedLogToConsole('Using color mask TRUE, TRUE, TRUE, FALSE');
+ }
+
+ // Draw quad.
+
+ /** @type {Array<number>} */ var pt0 = [-1.0, -1.0];
+ /** @type {Array<number>} */ var pt1 = [1.0, -1.0];
+ /** @type {Array<number>} */ var pt2 = [-1.0, 1.0];
+ /** @type {Array<number>} */ var pt3 = [1.0, 1.0];
+ /** @type {Array<number>} */ var quadColor = [1.0, 0.0, 0.0, 1.0];
+ /** @type {number} */ var alphaOrCoverageValue = this.m_currentIteration / (this.m_numIterations-1);
+
+ if (this.m_type === es3fMultisampleTests.MaskProportionalityCase.CaseType.ALPHA_TO_COVERAGE) {
+ bufferedLogToConsole('Drawing a red quad using alpha value ' + alphaOrCoverageValue);
+ quadColor[3] = alphaOrCoverageValue;
+ }
+ else {
+ assertMsgOptions(
+ this.m_type === es3fMultisampleTests.MaskProportionalityCase.CaseType.SAMPLE_COVERAGE ||
+ this.m_type === es3fMultisampleTests.MaskProportionalityCase.CaseType.SAMPLE_COVERAGE_INVERTED,
+ 'CaseType should be SAMPLE_COVERAGE or SAMPLE_COVERAGE_INVERTED', false, true);
+
+ /** @type {boolean} */ var isInverted = (this.m_type === es3fMultisampleTests.MaskProportionalityCase.CaseType.SAMPLE_COVERAGE_INVERTED);
+ /** @type {number} */ var coverageValue = isInverted ? 1.0 - alphaOrCoverageValue : alphaOrCoverageValue;
+ bufferedLogToConsole('Drawing a red quad using sample coverage value ' + coverageValue + (isInverted ? ' (inverted)' : ''));
+ gl.sampleCoverage(coverageValue, isInverted ? true : false);
+ }
+
+ this.renderQuad_WithColor(pt0, pt1, pt2, pt3, quadColor);
+
+ // Read and log image.
+ /** @type {tcuSurface.Surface} */ var renderedImg = this.readImage();
+ /** @type {number} */ var numPixels = renderedImg.getWidth() * renderedImg.getHeight();
+
+ tcuLogImage.logImage('RenderedImage', 'Rendered image', renderedImg.getAccess());
+ // Compute average red component in rendered image.
+
+ /** @type {number} */ var sumRed = 0;
+
+ for (var y = 0; y < renderedImg.getHeight(); y++)
+ for (var x = 0; x < renderedImg.getWidth(); x++)
+ sumRed += new tcuRGBA.RGBA(renderedImg.getPixel(x, y)).getRed();
+
+ bufferedLogToConsole('Average red color component: ' + (sumRed / 255.0 / numPixels));
+
+ // Check if average color has decreased from previous frame's color.
+
+ if (sumRed < this.m_previousIterationColorSum) {
+ bufferedLogToConsole('Failure: Current average red color component is lower than previous');
+ testFailedOptions('Failed', false);
+ return tcuTestCase.IterateResult.STOP;
+ }
+
+ // Check if coverage mask is not all-zeros if alpha or coverage value is 0 (or 1, if inverted).
+
+ if (this.m_currentIteration == 0 && sumRed != 0)
+ {
+ bufferedLogToConsole('Failure: Image should be completely black');
+ testFailedOptions('Failed', false);
+ return tcuTestCase.IterateResult.STOP;
+ }
+
+ if (this.m_currentIteration == this.m_numIterations-1 && sumRed != 0xff*numPixels)
+ {
+ bufferedLogToConsole('Failure: Image should be completely red');
+
+ testFailedOptions('Failed', false);
+ return tcuTestCase.IterateResult.STOP;
+ }
+
+ this.m_previousIterationColorSum = sumRed;
+
+ this.m_currentIteration++;
+
+ if (this.m_currentIteration >= this.m_numIterations)
+ {
+ bufferedLogToConsole('Success: Number of coverage mask bits set appears to be, on average, proportional to ' +
+ (this.m_type == es3fMultisampleTests.MaskProportionalityCase.CaseType.ALPHA_TO_COVERAGE ? 'alpha' :
+ this.m_type == es3fMultisampleTests.MaskProportionalityCase.CaseType.SAMPLE_COVERAGE ? 'sample coverage value' :
+ 'inverted sample coverage value'));
+
+ testPassedOptions('Passed', true);
+ return tcuTestCase.IterateResult.STOP;
+ }
+ else
+ return tcuTestCase.IterateResult.CONTINUE;
+ };
+
+ /**
+ * Tests coverage mask generation constancy property.
+ *
+ * Tests that the coverage mask created by gl.SAMPLE_ALPHA_TO_COVERAGE or
+ * gl.SAMPLE_COVERAGE is constant at given pixel coordinates, with a given
+ * alpha component or coverage value, respectively. Draws two quads, with
+ * the second one fully overlapping the first one such that at any given
+ * pixel, both quads have the same alpha or coverage value. This way, if
+ * the constancy property is fulfilled, only the second quad should be
+ * visible.
+ * @extends {es3fMultisampleTests.MultisampleCase}
+ * @constructor
+ * @param {string} name
+ * @param {string} desc
+ * @param {es3fMultisampleTests.MaskConstancyCase.CaseType} type
+ * @param {number=} numFboSamples
+ */
+ es3fMultisampleTests.MaskConstancyCase = function(name, desc, type, numFboSamples) {
+ numFboSamples = numFboSamples === undefined ? 0 : numFboSamples;
+ /** @type {es3fMultisampleTests.FboParams} */
+ var params = numFboSamples >= 0 ? new es3fMultisampleTests.FboParams(numFboSamples, false, false) : new es3fMultisampleTests.FboParams();
+ es3fMultisampleTests.MultisampleCase.call(this, name, desc, 256, params);
+ var CaseType = es3fMultisampleTests.MaskConstancyCase.CaseType;
+ /** @type {boolean} */ this.m_isAlphaToCoverageCase = (type === CaseType.ALPHA_TO_COVERAGE || type === CaseType.BOTH || type === CaseType.BOTH_INVERTED);
+ /** @type {boolean} */ this.m_isSampleCoverageCase = (type === CaseType.SAMPLE_COVERAGE || type === CaseType.SAMPLE_COVERAGE_INVERTED || type === CaseType.BOTH || type === CaseType.BOTH_INVERTED);
+ /** @type {boolean} */ this.m_isInvertedSampleCoverageCase = (type === CaseType.SAMPLE_COVERAGE_INVERTED || type === CaseType.BOTH_INVERTED);
+ };
+
+ es3fMultisampleTests.MaskConstancyCase.prototype = Object.create(es3fMultisampleTests.MultisampleCase.prototype);
+
+ /** Copy the constructor */
+ es3fMultisampleTests.MaskConstancyCase.prototype.constructor = es3fMultisampleTests.MaskConstancyCase;
+
+ /**
+ * @enum {number}
+ */
+ es3fMultisampleTests.MaskConstancyCase.CaseType = {
+ ALPHA_TO_COVERAGE: 0, //!< Use only alpha-to-coverage.
+ SAMPLE_COVERAGE: 1, //!< Use only sample coverage.
+ SAMPLE_COVERAGE_INVERTED: 2, //!< Use only inverted sample coverage.
+ BOTH: 3, //!< Use both alpha-to-coverage and sample coverage.
+ BOTH_INVERTED: 4 //!< Use both alpha-to-coverage and inverted sample coverage.
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fMultisampleTests.MaskConstancyCase.prototype.iterate = function() {
+ this.randomizeViewport();
+
+ bufferedLogToConsole('Clearing color to black');
+ gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ if (this.m_isAlphaToCoverageCase) {
+ gl.enable(gl.SAMPLE_ALPHA_TO_COVERAGE);
+ gl.colorMask(true, true, true, false);
+ bufferedLogToConsole('gl.SAMPLE_ALPHA_TO_COVERAGE is enabled');
+ bufferedLogToConsole('Color mask is TRUE, TRUE, TRUE, FALSE');
+ }
+
+ if (this.m_isSampleCoverageCase) {
+ gl.enable(gl.SAMPLE_COVERAGE);
+ bufferedLogToConsole('gl.SAMPLE_COVERAGE is enabled');
+ }
+
+ bufferedLogToConsole('Drawing several green quads, each fully overlapped by a red quad with the same ' +
+ (this.m_isAlphaToCoverageCase ? 'alpha' : '') +
+ (this.m_isAlphaToCoverageCase && this.m_isSampleCoverageCase ? ' and ' : '') +
+ (this.m_isInvertedSampleCoverageCase ? 'inverted ' : '') +
+ (this.m_isSampleCoverageCase ? 'sample coverage' : '') +
+ ' values');
+
+ /** @type {number} */ var numQuadRowsCols = this.m_numSamples * 4;
+
+ for (var row = 0; row < numQuadRowsCols; row++) {
+ for (var col = 0; col < numQuadRowsCols; col++) {
+ /** @type {number} */ var x0 = (col + 0) / numQuadRowsCols * 2.0 - 1.0;
+ /** @type {number} */ var x1 = (col + 1) / numQuadRowsCols * 2.0 - 1.0;
+ /** @type {number} */ var y0 = (row + 0) / numQuadRowsCols * 2.0 - 1.0;
+ /** @type {number} */ var y1 = (row + 1) / numQuadRowsCols * 2.0 - 1.0;
+ /** @type {Array<number>} */ var baseGreen = [0.0, 1.0, 0.0, 0.0];
+ /** @type {Array<number>} */ var baseRed = [1.0, 0.0, 0.0, 0.0];
+ /** @type {Array<number>} */ var alpha0 = [0.0, 0.0, 0.0, this.m_isAlphaToCoverageCase ? col / (numQuadRowsCols - 1) : 1.0];
+ /** @type {Array<number>} */ var alpha1 = [0.0, 0.0, 0.0, this.m_isAlphaToCoverageCase ? row / (numQuadRowsCols - 1) : 1.0];
+
+ if (this.m_isSampleCoverageCase) {
+ /** @type {number} */ var value = (row*numQuadRowsCols + col) / (numQuadRowsCols*numQuadRowsCols - 1);
+ gl.sampleCoverage(this.m_isInvertedSampleCoverageCase ? 1.0 - value : value, this.m_isInvertedSampleCoverageCase ? true : false);
+ }
+
+ this.renderQuad([x0, y0], [x1, y0], [x0, y1], [x1, y1],
+ deMath.add(baseGreen, alpha0), deMath.add(baseGreen, alpha1),
+ deMath.add(baseGreen, alpha0), deMath.add(baseGreen, alpha1));
+ this.renderQuad([x0, y0], [x1, y0], [x0, y1], [x1, y1],
+ deMath.add(baseRed, alpha0), deMath.add(baseRed, alpha1),
+ deMath.add(baseRed, alpha0), deMath.add(baseRed, alpha1));
+ }
+ }
+
+ /** @type {tcuSurface.Surface} */ var renderedImg = this.readImage();
+
+ tcuLogImage.logImage('RenderedImage', 'Rendered image', renderedImg.getAccess());
+ for (var y = 0; y < renderedImg.getHeight(); y++)
+ for (var x = 0; x < renderedImg.getWidth(); x++) {
+ if (new tcuRGBA.RGBA(renderedImg.getPixel(x, y)).getGreen() > 0) {
+ bufferedLogToConsole('Failure: Non-zero green color component detected - should have been completely overwritten by red quad');
+ testFailedOptions('Failed', false);
+ return tcuTestCase.IterateResult.STOP;
+ }
+ }
+
+ bufferedLogToConsole('Success: Coverage mask appears to be constant at a given pixel coordinate with a given ' +
+ (this.m_isAlphaToCoverageCase ? 'alpha' : '') +
+ (this.m_isAlphaToCoverageCase && this.m_isSampleCoverageCase ? ' and ' : '') +
+ (this.m_isSampleCoverageCase ? 'coverage value' : ''));
+
+ testPassedOptions('Passed', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ }
+
+
+ /**
+ * Tests coverage mask inversion validity.
+ *
+ * Tests that the coverage masks obtained by glSampleCoverage(..., true)
+ * and glSampleCoverage(..., false) are indeed each others' inverses.
+ * This is done by drawing a pattern, with varying coverage values,
+ * overlapped by a pattern that has inverted masks and is otherwise
+ * identical. The resulting image is compared to one obtained by drawing
+ * the same pattern but with all-ones coverage masks.
+ * @extends {es3fMultisampleTests.MultisampleCase}
+ * @constructor
+ * @param {string} name
+ * @param {string} desc
+ * @param {number=} numFboSamples
+ */
+ es3fMultisampleTests.CoverageMaskInvertCase = function(name, desc, numFboSamples) {
+ numFboSamples = numFboSamples === undefined ? 0 : numFboSamples;
+ /** @type {es3fMultisampleTests.FboParams} */
+ var params = numFboSamples >= 0 ? new es3fMultisampleTests.FboParams(numFboSamples, false, false) : new es3fMultisampleTests.FboParams();
+ es3fMultisampleTests.MultisampleCase.call(this, name, desc, 256, params);
+ };
+
+ es3fMultisampleTests.CoverageMaskInvertCase.prototype = Object.create(es3fMultisampleTests.MultisampleCase.prototype);
+
+ /** Copy the constructor */
+ es3fMultisampleTests.CoverageMaskInvertCase.prototype.constructor = es3fMultisampleTests.CoverageMaskInvertCase;
+
+ /**
+ * @param {boolean} invertSampleCoverage
+ */
+ es3fMultisampleTests.CoverageMaskInvertCase.prototype.drawPattern = function(invertSampleCoverage) {
+ /** @type {number} */ var numTriangles = 25;
+ for (var i = 0; i < numTriangles; i++) {
+ gl.sampleCoverage(i / (numTriangles - 1), invertSampleCoverage ? true : false);
+
+ /** @type {number} */ var angle0 = 2.0 * Math.PI * i / numTriangles;
+ /** @type {number} */ var angle1 = 2.0 * Math.PI * (i + 0.5) / numTriangles;
+
+ this.renderTriangle_pAsVec2WithColor(
+ [0.0, 0.0],
+ [Math.cos(angle0) * 0.95, Math.sin(angle0) * 0.95],
+ [Math.cos(angle1) * 0.95, Math.sin(angle1) * 0.95],
+ [0.4 + i / numTriangles * 0.6,
+ 0.5 + i / numTriangles * 0.3,
+ 0.6 - i / numTriangles * 0.5,
+ 0.7 - i / numTriangles * 0.7]);
+ }
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fMultisampleTests.CoverageMaskInvertCase.prototype.iterate = function() {
+ this.randomizeViewport();
+
+ gl.enable(gl.BLEND);
+ gl.blendEquation(gl.FUNC_ADD);
+ gl.blendFunc(gl.ONE, gl.ONE);
+ bufferedLogToConsole('Additive blending enabled in order to detect (erroneously) overlapping samples');
+
+ bufferedLogToConsole('Clearing color to all-zeros');
+ gl.clearColor(0.0, 0.0, 0.0, 0.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ bufferedLogToConsole('Drawing the pattern with gl.SAMPLE_COVERAGE disabled');
+ this.drawPattern(false);
+ /** @type {tcuSurface.Surface} */ var renderedImgNoSampleCoverage = this.readImage();
+
+ tcuLogImage.logImage('RenderedImageNoSampleCoverage', 'Rendered image with gl.SAMPLE_COVERAGE disabled', renderedImgNoSampleCoverage.getAccess());
+ bufferedLogToConsole('Clearing color to all-zeros');
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.enable(gl.SAMPLE_COVERAGE);
+ bufferedLogToConsole('Drawing the pattern with gl.SAMPLE_COVERAGE enabled, using non-inverted masks');
+ this.drawPattern(false);
+ bufferedLogToConsole('Drawing the pattern with gl.SAMPLE_COVERAGE enabled, using same sample coverage values but inverted masks');
+ this.drawPattern(true);
+ /** @type {tcuSurface.Surface} */ var renderedImgSampleCoverage = this.readImage();
+
+ tcuLogImage.logImage('RenderedImageSampleCoverage', 'Rendered image with gl.SAMPLE_COVERAGE enabled', renderedImgSampleCoverage.getAccess());
+ /** @type {boolean} */ var passed = tcuImageCompare.pixelThresholdCompare(
+ 'CoverageVsNoCoverage',
+ 'Comparison of same pattern with gl.SAMPLE_COVERAGE disabled and enabled',
+ renderedImgNoSampleCoverage,
+ renderedImgSampleCoverage,
+ [0, 0, 0, 0]);
+
+ if (passed) {
+ bufferedLogToConsole('Success: The two images rendered are identical');
+ testPassedOptions('Passed', true);
+ }
+ else {
+ testFailedOptions('Failed', false);
+ }
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ es3fMultisampleTests.init = function() {
+ var testGroup = tcuTestCase.runner.testCases;
+ /**
+ * @enum {number}
+ */
+ var CaseType = {
+ DEFAULT_FRAMEBUFFER: 0,
+ FBO_4_SAMPLES: 1,
+ FBO_8_SAMPLES: 2,
+ FBO_MAX_SAMPLES: 3
+ };
+
+ for (var caseTypeI in CaseType) {
+ /** @type {CaseType} */ var caseType = CaseType[caseTypeI];
+ /** @type {number} */
+ var numFboSamples = caseType === CaseType.DEFAULT_FRAMEBUFFER ? -1 :
+ caseType === CaseType.FBO_4_SAMPLES ? 4 :
+ caseType === CaseType.FBO_8_SAMPLES ? 8 :
+ caseType === CaseType.FBO_MAX_SAMPLES ? 0 :
+ -2;
+
+ /** @type {?string} */
+ var name = caseType === CaseType.DEFAULT_FRAMEBUFFER ? 'default_framebuffer' :
+ caseType === CaseType.FBO_4_SAMPLES ? 'fbo_4_samples' :
+ caseType === CaseType.FBO_8_SAMPLES ? 'fbo_8_samples' :
+ caseType === CaseType.FBO_MAX_SAMPLES ? 'fbo_max_samples' :
+ null;
+ /** @type {?string} */
+ var desc = caseType === CaseType.DEFAULT_FRAMEBUFFER ? 'Render into default framebuffer' :
+ caseType === CaseType.FBO_4_SAMPLES ? 'Render into a framebuffer object with 4 samples' :
+ caseType === CaseType.FBO_8_SAMPLES ? 'Render into a framebuffer object with 8 samples' :
+ caseType === CaseType.FBO_MAX_SAMPLES ? 'Render into a framebuffer object with the maximum number of samples' :
+ null;
+
+ /** @type {tcuTestCase.DeqpTest} */ var group = tcuTestCase.newTest(name, desc);
+
+ assertMsgOptions(group.name != null, 'Error: No Test Name', false, true);
+ assertMsgOptions(group.description != null, 'Error: No Test Description', false, true);
+ assertMsgOptions(numFboSamples >= -1, 'Assert Failed: numFboSamples >= -1', false, true);
+ testGroup.addChild(group);
+
+ group.addChild(new es3fMultisampleTests.PolygonNumSamplesCase(
+ 'num_samples_polygon',
+ 'Test sanity of the sample count, with polygons',
+ numFboSamples));
+
+ group.addChild(new es3fMultisampleTests.LineNumSamplesCase(
+ 'num_samples_line',
+ 'Test sanity of the sample count, with lines',
+ numFboSamples));
+
+ group.addChild(new es3fMultisampleTests.CommonEdgeCase(
+ 'common_edge_small_quads',
+ 'Test polygons\'s common edges with small quads',
+ es3fMultisampleTests.CommonEdgeCase.CaseType.SMALL_QUADS,
+ numFboSamples));
+
+ group.addChild(new es3fMultisampleTests.CommonEdgeCase(
+ 'common_edge_big_quad',
+ 'Test polygon\'s common edges with bigger-than-viewport quads',
+ es3fMultisampleTests.CommonEdgeCase.CaseType.BIGGER_THAN_VIEWPORT_QUAD,
+ numFboSamples));
+
+ group.addChild(new es3fMultisampleTests.CommonEdgeCase(
+ 'common_edge_viewport_quad',
+ 'Test polygons\' common edges with exactly viewport-sized quads',
+ es3fMultisampleTests.CommonEdgeCase.CaseType.FIT_VIEWPORT_QUAD,
+ numFboSamples));
+
+ group.addChild(new es3fMultisampleTests.SampleDepthCase(
+ 'depth',
+ 'Test that depth values are per-sample',
+ numFboSamples));
+
+ group.addChild(new es3fMultisampleTests.SampleStencilCase(
+ 'stencil',
+ 'Test that stencil values are per-sample',
+ numFboSamples));
+
+ group.addChild(new es3fMultisampleTests.CoverageMaskInvertCase(
+ 'sample_coverage_invert',
+ 'Test that non-inverted and inverted sample coverage masks are each other\'s negations',
+ numFboSamples));
+
+
+ group.addChild(new es3fMultisampleTests.MaskProportionalityCase(
+ 'proportionality_alpha_to_coverage',
+ 'Test the proportionality property of GL_SAMPLE_ALPHA_TO_COVERAGE',
+ es3fMultisampleTests.MaskProportionalityCase.CaseType.ALPHA_TO_COVERAGE,
+ numFboSamples));
+ group.addChild(new es3fMultisampleTests.MaskProportionalityCase(
+ 'proportionality_sample_coverage',
+ 'Test the proportionality property of GL_SAMPLE_COVERAGE',
+ es3fMultisampleTests.MaskProportionalityCase.CaseType.SAMPLE_COVERAGE,
+ numFboSamples));
+ group.addChild(new es3fMultisampleTests.MaskProportionalityCase(
+ 'proportionality_sample_coverage_inverted',
+ 'Test the proportionality property of inverted-mask GL_SAMPLE_COVERAGE',
+ es3fMultisampleTests.MaskProportionalityCase.CaseType.SAMPLE_COVERAGE_INVERTED,
+ numFboSamples));
+
+ group.addChild(new es3fMultisampleTests.MaskConstancyCase(
+ 'constancy_alpha_to_coverage',
+ 'Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE',
+ es3fMultisampleTests.MaskConstancyCase.CaseType.ALPHA_TO_COVERAGE,
+ numFboSamples));
+ group.addChild(new es3fMultisampleTests.MaskConstancyCase(
+ 'constancy_sample_coverage',
+ 'Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_COVERAGE',
+ es3fMultisampleTests.MaskConstancyCase.CaseType.SAMPLE_COVERAGE,
+ numFboSamples));
+ group.addChild(new es3fMultisampleTests.MaskConstancyCase(
+ 'constancy_sample_coverage_inverted',
+ 'Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using inverted-mask GL_SAMPLE_COVERAGE',
+ es3fMultisampleTests.MaskConstancyCase.CaseType.SAMPLE_COVERAGE_INVERTED,
+ numFboSamples));
+ group.addChild(new es3fMultisampleTests.MaskConstancyCase(
+ 'constancy_both',
+ 'Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE and GL_SAMPLE_COVERAGE',
+ es3fMultisampleTests.MaskConstancyCase.CaseType.BOTH,
+ numFboSamples));
+ group.addChild(new es3fMultisampleTests.MaskConstancyCase(
+ 'constancy_both_inverted',
+ 'Test that coverage mask is constant at given coordinates with a given alpha or coverage value, using GL_SAMPLE_ALPHA_TO_COVERAGE and inverted-mask GL_SAMPLE_COVERAGE',
+ es3fMultisampleTests.MaskConstancyCase.CaseType.BOTH_INVERTED,
+ numFboSamples));
+ }
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fMultisampleTests.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var testName = 'multisample';
+ var testDescription = 'Multisample Tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.setRoot(tcuTestCase.newTest(testName, testDescription, null));
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ es3fMultisampleTests.init();
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fMultisampleTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeBufferApiTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeBufferApiTests.js
new file mode 100644
index 0000000000..2a8910eb0d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeBufferApiTests.js
@@ -0,0 +1,1104 @@
+'use strict';
+goog.provide('functional.gles3.es3fNegativeBufferApiTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.opengl.gluStrUtil');
+goog.require('functional.gles3.es3fApiCase');
+
+goog.scope(function() {
+
+ var es3fNegativeBufferApiTests = functional.gles3.es3fNegativeBufferApiTests;
+ var es3fApiCase = functional.gles3.es3fApiCase;
+ var gluStrUtil = framework.opengl.gluStrUtil;
+ var tcuTestCase = framework.common.tcuTestCase;
+
+ /**
+ * @param {WebGL2RenderingContext} gl
+ */
+ es3fNegativeBufferApiTests.init = function(gl) {
+
+ var testGroup = tcuTestCase.runner.testCases;
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'bind_buffer', 'Invalid gl.bindBuffer() usage', gl,
+ function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not one of the allowable values.');
+ gl.bindBuffer(-1, null);
+ this.expectError(gl.INVALID_ENUM);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'buffer_data', 'Invalid gl.bufferData() usage', gl,
+ function() {
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.ARRAY_BUFFER or gl.ELEMENT_ARRAY_BUFFER.');
+ gl.bufferData(-1, 0, gl.STREAM_DRAW);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if usage is not gl.STREAM_DRAW, gl.STATIC_DRAW, or gl.DYNAMIC_DRAW.');
+ gl.bufferData(gl.ARRAY_BUFFER, 0, -1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if size is negative.');
+ gl.bufferData(gl.ARRAY_BUFFER, -1, gl.STREAM_DRAW);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the reserved buffer object name 0 is bound to target.');
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.bufferData(gl.ARRAY_BUFFER, 0, gl.STREAM_DRAW);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteBuffer(buffer);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'buffer_sub_data', 'Invalid gl.bufferSubData() usage', gl,
+ function() {
+ var buffer = gl.createBuffer();
+ var data = new ArrayBuffer(5);
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, 10, gl.STREAM_DRAW);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.ARRAY_BUFFER or gl.ELEMENT_ARRAY_BUFFER.');
+ gl.bufferSubData(-1, 1, data);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the reserved buffer object name 0 is bound to target.');
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, data);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteBuffer(buffer);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'buffer_sub_data_size_offset', 'Invalid gl.bufferSubData() usage', gl,
+ function() {
+ var buffer = gl.createBuffer();
+ var data = new ArrayBuffer(5);
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, 10, gl.STREAM_DRAW);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if offset is negative');
+ gl.bufferSubData(gl.ARRAY_BUFFER, -1, data);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if the data would be written past the end of the buffer.');
+ gl.bufferSubData(gl.ARRAY_BUFFER, 7, data);
+ this.expectError(gl.INVALID_VALUE);
+ gl.bufferSubData(gl.ARRAY_BUFFER, 15, data);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('An exception is thrown if data is null.');
+ this.expectThrowNoError(function() {
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, null);
+ });
+
+ gl.deleteBuffer(buffer);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'clear', 'Invalid gl.clear() usage', gl,
+ function() {
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if any bit other than the three defined bits is set in mask.');
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ this.expectError(gl.NO_ERROR);
+ gl.clear(0x0200);
+ this.expectError(gl.INVALID_VALUE);
+ gl.clear(0x1000);
+ this.expectError(gl.INVALID_VALUE);
+ gl.clear(0x0010);
+ this.expectError(gl.INVALID_VALUE);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'read_pixels', 'Invalid gl.readPixels() usage', gl,
+ function() {
+ var buffer = new ArrayBuffer(8);
+ var ubyteData = new Uint8Array(buffer);
+ var ushortData = new Uint16Array(buffer);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the combination of format and type is unsupported.');
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_SHORT_4_4_4_4, ushortData);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the ArrayBuffer type does not match the type parameter.');
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, ushortData);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if either width or height is negative.');
+ gl.readPixels(0, 0, -1, 1, gl.RGBA, gl.UNSIGNED_BYTE, ubyteData);
+ this.expectError(gl.INVALID_VALUE);
+ gl.readPixels(0, 0, 1, -1, gl.RGBA, gl.UNSIGNED_BYTE, ubyteData);
+ this.expectError(gl.INVALID_VALUE);
+ gl.readPixels(0, 0, -1, -1, gl.RGBA, gl.UNSIGNED_BYTE, ubyteData);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, ubyteData);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'read_pixels_format_mismatch', 'Invalid glReadPixels() usage', gl,
+ function() {
+ var buffer = new ArrayBuffer(8);
+ var ubyteData = new Uint8Array(buffer);
+ var ushortData = new Uint16Array(buffer);
+
+ bufferedLogToConsole('Unsupported combinations of format and type will generate a gl.INVALID_OPERATION error.');
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_SHORT_5_6_5, ushortData);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.readPixels(0, 0, 1, 1, gl.ALPHA, gl.UNSIGNED_SHORT_5_6_5, ushortData);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.readPixels(0, 0, 1, 1, gl.RGB, gl.UNSIGNED_SHORT_4_4_4_4, ushortData);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.readPixels(0, 0, 1, 1, gl.ALPHA, gl.UNSIGNED_SHORT_4_4_4_4, ushortData);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.readPixels(0, 0, 1, 1, gl.RGB, gl.UNSIGNED_SHORT_5_5_5_1, ushortData);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.readPixels(0, 0, 1, 1, gl.ALPHA, gl.UNSIGNED_SHORT_5_5_5_1, ushortData);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.RGBA/gl.UNSIGNED_BYTE is always accepted and the other acceptable pair can be discovered by querying gl.IMPLEMENTATION_COLOR_READ_FORMAT and gl.IMPLEMENTATION_COLOR_READ_TYPE.');
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, ubyteData);
+ this.expectError(gl.NO_ERROR);
+ var readFormat = /** @type {number} */ (gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT));
+ var readType = /** @type {number} */ (gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE));
+ gl.readPixels(0, 0, 1, 1, readFormat, readType, ubyteData);
+ this.expectError(gl.NO_ERROR);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'read_pixels_fbo_format_mismatch', 'Invalid gl.readPixels() usage', gl,
+ function() {
+ var ubyteData = new Uint8Array(4);
+ var floatData = new Float32Array(4);
+
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if currently bound framebuffer format is incompatible with format and type.');
+
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ this.expectError(gl.NO_ERROR);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT, floatData);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32I, 32, 32, 0, gl.RGBA_INTEGER, gl.INT, null);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ this.expectError(gl.NO_ERROR);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT, floatData);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32UI, 32, 32, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT, null);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ this.expectError(gl.NO_ERROR);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT, floatData);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.READ_FRAMEBUFFER_BINDING is non-zero, the read framebuffer is complete, and the value of gl.SAMPLE_BUFFERS for the read framebuffer is greater than zero.');
+
+ var rbo = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, gl.RGBA8, 32, 32);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
+
+ var binding = /** @type {WebGLFramebuffer} */ (gl.getParameter(gl.READ_FRAMEBUFFER_BINDING));
+ bufferedLogToConsole('gl.READ_FRAMEBUFFER_BINDING: ' + binding);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ var sampleBuffers = /** @type {number} */ (gl.getParameter(gl.SAMPLE_BUFFERS));
+ bufferedLogToConsole('gl.SAMPLE_BUFFERS: ' + sampleBuffers);
+ this.expectError(gl.NO_ERROR);
+
+ if (binding == null || sampleBuffers <= 0) {
+ this.testFailed('expected gl.READ_FRAMEBUFFER_BINDING to be non-zero and gl.SAMPLE_BUFFERS to be greater than zero');
+ } else {
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, ubyteData);
+ this.expectError(gl.INVALID_OPERATION);
+ }
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ gl.deleteRenderbuffer(rbo);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+ gl.bindTexture(gl.TEXTURE_2D, null);
+ gl.deleteTexture(texture);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'bind_buffer_range', 'Invalid glBindBufferRange() usage', gl,
+ function() {
+ var bufEmpty = new ArrayBuffer(16);
+
+ var bufUniform = gl.createBuffer();
+ gl.bindBuffer(gl.UNIFORM_BUFFER, bufUniform);
+ gl.bufferData(gl.UNIFORM_BUFFER, bufEmpty, gl.STREAM_DRAW);
+
+ var bufTF = gl.createBuffer();
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, bufTF);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, bufEmpty, gl.STREAM_DRAW);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.TRANSFORM_FEEDBACK_BUFFER or gl.UNIFORM_BUFFER.');
+ gl.bindBufferRange(gl.ARRAY_BUFFER, 0, bufUniform, 0, 4);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if target is gl.TRANSFORM_FEEDBACK_BUFFER and index is greater than or equal to gl.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS.');
+ var maxTFSize = /** @type {number} */ (gl.getParameter(gl.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS));
+ gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, maxTFSize, bufTF, 0, 4);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if target is gl.UNIFORM_BUFFER and index is greater than or equal to gl.MAX_UNIFORM_BUFFER_BINDINGS.');
+ var maxUSize = /** @type {number} */ (gl.getParameter(gl.MAX_UNIFORM_BUFFER_BINDINGS));
+ gl.bindBufferRange(gl.UNIFORM_BUFFER, maxUSize, bufUniform, 0, 4);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if size is less than or equal to zero.');
+ gl.bindBufferRange(gl.UNIFORM_BUFFER, 0, bufUniform, 0, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.bindBufferRange(gl.UNIFORM_BUFFER, 0, bufUniform, 0, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if target is gl.TRANSFORM_FEEDBACK_BUFFER and size or offset are not multiples of 4.');
+ gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, bufTF, 4, 5);
+ this.expectError(gl.INVALID_VALUE);
+ gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, bufTF, 5, 4);
+ this.expectError(gl.INVALID_VALUE);
+ gl.bindBufferRange(gl.TRANSFORM_FEEDBACK_BUFFER, 0, bufTF, 5, 7);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if target is gl.UNIFORM_BUFFER and offset is not a multiple of gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT.');
+ var alignment = /** @type {number} */ (gl.getParameter(gl.UNIFORM_BUFFER_OFFSET_ALIGNMENT));
+ gl.bindBufferRange(gl.UNIFORM_BUFFER, 0, bufUniform, alignment + 1, 4);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteBuffer(bufUniform);
+ gl.deleteBuffer(bufTF);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'bind_buffer_base', 'Invalid glBindBufferBase() usage', gl,
+ function() {
+ var bufEmpty = new ArrayBuffer(16);
+
+ var bufUniform = gl.createBuffer();
+ gl.bindBuffer(gl.UNIFORM_BUFFER, bufUniform);
+ gl.bufferData(gl.UNIFORM_BUFFER, bufEmpty, gl.STREAM_DRAW);
+
+ var bufTF = gl.createBuffer();
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, bufTF);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, bufEmpty, gl.STREAM_DRAW);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.TRANSFORM_FEEDBACK_BUFFER or gl.UNIFORM_BUFFER.');
+ gl.bindBufferBase(-1, 0, bufUniform);
+ this.expectError(gl.INVALID_ENUM);
+ gl.bindBufferBase(gl.ARRAY_BUFFER, 0, bufUniform);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if target is gl.UNIFORM_BUFFER and index is greater than or equal to gl.MAX_UNIFORM_BUFFER_BINDINGS.');
+ var maxUSize = /** @type {number} */ (gl.getParameter(gl.MAX_UNIFORM_BUFFER_BINDINGS));
+ gl.bindBufferBase(gl.UNIFORM_BUFFER, maxUSize, bufUniform);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if target is gl.TRANSFORM_FEEDBACK_BUFFER andindex is greater than or equal to gl.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS.');
+ var maxTFSize = /** @type {number} */ (gl.getParameter(gl.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS));
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, maxTFSize, bufTF);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteBuffer(bufUniform);
+ gl.deleteBuffer(bufTF);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'clear_bufferiv', 'Invalid gl.clearBufferiv() usage', gl,
+ function() {
+ var data = new Int32Array(32 * 32);
+
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32I, 32, 32, 0, gl.RGBA_INTEGER, gl.INT, null);
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if buffer is not an accepted value.');
+ gl.clearBufferiv(-1, 0, data);
+ this.expectError(gl.INVALID_ENUM);
+ gl.clearBufferiv(gl.FRAMEBUFFER, 0, data);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if buffer is gl.COLOR, gl.FRONT, gl.BACK, gl.LEFT, gl.RIGHT, or gl.FRONT_AND_BACK and drawBuffer is greater than or equal to gl.MAX_DRAW_BUFFERS.');
+ var maxDrawBuffers = /** @type {number} */ (gl.getParameter(gl.MAX_DRAW_BUFFERS));
+ gl.clearBufferiv(gl.COLOR, maxDrawBuffers, data);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if buffer is gl.DEPTH or gl.DEPTH_STENCIL.');
+ gl.clearBufferiv(gl.DEPTH, 1, data);
+ this.expectError(gl.INVALID_ENUM);
+ gl.clearBufferiv(gl.DEPTH_STENCIL, 1, data);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if buffer is gl.STENCIL and drawBuffer is not zero.');
+ gl.clearBufferiv(gl.STENCIL, 1, data);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(texture);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'clear_bufferuiv', 'Invalid gl.clearBufferuiv() usage', gl,
+ function() {
+ var data = new Uint32Array(32 * 32);
+
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32UI, 32, 32, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT, null);
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if buffer is not an accepted value.');
+ gl.clearBufferuiv(-1, 0, data);
+ this.expectError(gl.INVALID_ENUM);
+ gl.clearBufferuiv(gl.FRAMEBUFFER, 0, data);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if buffer is gl.COLOR, gl.FRONT, gl.BACK, gl.LEFT, gl.RIGHT, or gl.FRONT_AND_BACK and drawBuffer is greater than or equal to gl.MAX_DRAW_BUFFERS.');
+ var maxDrawBuffers = /** @type {number} */ (gl.getParameter(gl.MAX_DRAW_BUFFERS));
+ gl.clearBufferuiv(gl.COLOR, maxDrawBuffers, data);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if buffer is gl.DEPTH, gl.STENCIL or gl.DEPTH_STENCIL.');
+ gl.clearBufferuiv(gl.DEPTH, 1, data);
+ this.expectError(gl.INVALID_ENUM);
+ gl.clearBufferuiv(gl.STENCIL, 1, data);
+ this.expectError(gl.INVALID_ENUM);
+ gl.clearBufferuiv(gl.DEPTH_STENCIL, 1, data);
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(texture);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'clear_bufferfv', 'Invalid gl.clearBufferfv() usage', gl,
+ function() {
+ var data = new Float32Array(32 * 32);
+
+ var texture = gl.createTexture();
+ // Float type texture isn't color-renderable without EXT_color_buffer_float extension.
+ if (gl.getExtension('EXT_color_buffer_float')) {
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, 32, 32, 0, gl.RGBA, gl.FLOAT, null);
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if buffer is not an accepted value.');
+ gl.clearBufferfv(-1, 0, data);
+ this.expectError(gl.INVALID_ENUM);
+ gl.clearBufferfv(gl.FRAMEBUFFER, 0, data);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if buffer is gl.COLOR, gl.FRONT, gl.BACK, gl.LEFT, gl.RIGHT, or gl.FRONT_AND_BACK and drawBuffer is greater than or equal to gl.MAX_DRAW_BUFFERS.');
+ var maxDrawBuffers = /** @type {number} */ (gl.getParameter(gl.MAX_DRAW_BUFFERS));
+ gl.clearBufferfv(gl.COLOR, maxDrawBuffers, data);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if buffer is gl.STENCIL or gl.DEPTH_STENCIL.');
+ gl.clearBufferfv(gl.STENCIL, 1, data);
+ this.expectError(gl.INVALID_ENUM);
+ gl.clearBufferfv(gl.DEPTH_STENCIL, 1, data);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if buffer is gl.DEPTH and drawBuffer is not zero.');
+ gl.clearBufferfv(gl.DEPTH, 1, data);
+ this.expectError(gl.INVALID_VALUE);
+ }
+
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(texture);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'clear_bufferfi', 'Invalid gl.clearBufferfi() usage', gl,
+ function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if buffer is not an accepted value.');
+ gl.clearBufferfi(-1, 0, 1.0, 1);
+ this.expectError(gl.INVALID_ENUM);
+ gl.clearBufferfi(gl.FRAMEBUFFER, 0, 1.0, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if buffer is not gl.DEPTH_STENCIL.');
+ gl.clearBufferfi(gl.DEPTH, 0, 1.0, 1);
+ this.expectError(gl.INVALID_ENUM);
+ gl.clearBufferfi(gl.STENCIL, 0, 1.0, 1);
+ this.expectError(gl.INVALID_ENUM);
+ gl.clearBufferfi(gl.COLOR, 0, 1.0, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if buffer is gl.DEPTH_STENCIL and drawBuffer is not zero.');
+ gl.clearBufferfi(gl.DEPTH_STENCIL, 1, 1.0, 1);
+ this.expectError(gl.INVALID_VALUE);
+
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'copy_buffer_sub_data', 'Invalid gl.copyBufferSubData() usage', gl,
+ function() {
+ var buf = {
+ r: gl.createBuffer(),
+ w: gl.createBuffer()
+ };
+
+ gl.bindBuffer(gl.COPY_READ_BUFFER, buf.r);
+ gl.bufferData(gl.COPY_READ_BUFFER, 32, gl.DYNAMIC_COPY);
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, buf.w);
+ gl.bufferData(gl.COPY_WRITE_BUFFER, 32, gl.DYNAMIC_COPY);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if any of readoffset, writeoffset or size is negative.');
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, -4);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, -1, 0, 4);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, -1, 4);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if readoffset + size exceeds the size of the buffer object bound to readtarget.');
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 36);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 24, 0, 16);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 36, 0, 4);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if writeoffset + size exceeds the size of the buffer object bound to writetarget.');
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 36);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 24, 16);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 36, 4);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if the same buffer object is bound to both readtarget and writetarget and the ranges [readoffset, readoffset + size) and [writeoffset, writeoffset + size) overlap.');
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, buf.r);
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 16, 4);
+ this.expectError(gl.NO_ERROR);
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 4);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 16, 18);
+ this.expectError(gl.INVALID_VALUE);
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, buf.w);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if null is bound to readtarget or writetarget.');
+ gl.bindBuffer(gl.COPY_READ_BUFFER, null);
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 16);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.bindBuffer(gl.COPY_READ_BUFFER, buf.r);
+
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, null);
+ gl.copyBufferSubData(gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, 16);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.bindBuffer(gl.COPY_WRITE_BUFFER, buf.w);
+
+ gl.deleteBuffer(buf.w);
+ gl.deleteBuffer(buf.r);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'draw_buffers', 'Invalid glDrawBuffers() usage', gl,
+ function() {
+ var maxDrawBuffers = /** @type {number} */ (gl.getParameter(gl.MAX_DRAW_BUFFERS));
+ var values = [
+ gl.NONE,
+ gl.BACK,
+ gl.COLOR_ATTACHMENT0,
+ gl.DEPTH_ATTACHMENT
+ ];
+
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if one of the values in bufs is not an accepted value.');
+ gl.drawBuffers(values.slice(2, 4));
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the GL is bound to the default framebuffer and the number of queried buffers is not 1.');
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.drawBuffers(values.slice(0, 2));
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the GL is bound to the default framebuffer and the value in bufs is one of the gl.COLOR_ATTACHMENTn tokens.');
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.drawBuffers(values.slice(2, 3));
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the GL is bound to a framebuffer object and the ith buffer listed in bufs is anything other than gl.NONE or gl.COLOR_ATTACHMENTSi.');
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.drawBuffers(values.slice(1, 2));
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteTexture(texture);
+ gl.deleteFramebuffer(fbo);
+ }
+ ));
+
+ // Framebuffer Objects
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'bind_framebuffer', 'Invalid glBindFramebuffer() usage', gl,
+ function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.FRAMEBUFFER.');
+ gl.bindFramebuffer(-1, null);
+ this.expectError(gl.INVALID_ENUM);
+ gl.bindFramebuffer(gl.RENDERBUFFER, null);
+ this.expectError(gl.INVALID_ENUM);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'bind_renderbuffer', 'Invalid glBindRenderbuffer() usage', gl,
+ function() {
+ bufferedLogToConsole('glINVALID_ENUM is generated if target is not gl.RENDERBUFFER.');
+ gl.bindRenderbuffer(-1, null);
+ this.expectError(gl.INVALID_ENUM);
+ gl.bindRenderbuffer(gl.FRAMEBUFFER, null);
+ this.expectError(gl.INVALID_ENUM);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'check_framebuffer_status', 'Invalid glCheckFramebufferStatus() usage', gl,
+ function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.FRAMEBUFFER.');
+ gl.checkFramebufferStatus(-1);
+ this.expectError(gl.INVALID_ENUM);
+ gl.checkFramebufferStatus(gl.RENDERBUFFER);
+ this.expectError(gl.INVALID_ENUM);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'framebuffer_renderbuffer', 'Invalid glFramebufferRenderbuffer() usage', gl,
+ function() {
+ var rbo = gl.createRenderbuffer();
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not one of the accepted tokens.');
+ gl.framebufferRenderbuffer(-1, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if renderbuffertarget is not gl.RENDERBUFFER.');
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, -1, rbo);
+ this.expectError(gl.INVALID_ENUM);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if zero is bound to target.');
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, null);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteRenderbuffer(rbo);
+ gl.deleteFramebuffer(fbo);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'framebuffer_texture2d', 'Invalid glFramebufferTexture2D() usage', gl,
+ function() {
+
+ var fbo = gl.createFramebuffer();
+ var tex2D = gl.createTexture();
+ var texCube = gl.createTexture();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.bindTexture(gl.TEXTURE_2D, tex2D);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texCube);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not one of the accepted tokens.');
+ gl.framebufferTexture2D(-1, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if textarget is not an accepted texture target.');
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, -1, tex2D, 0);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is less than 0 or larger than log_2 of maximum texture size.');
+ var maxTexSize = /** @type {number} */ (gl.getParameter(gl.MAX_TEXTURE_SIZE));
+ var maxCubeTexSize = /** @type {number} */ (gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE));
+ var maxSizePlane = Math.floor(Math.log2(maxTexSize)) + 1;
+ var maxSizeCube = Math.floor(Math.log2(maxCubeTexSize)) + 1;
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex2D, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex2D, maxSizePlane);
+ this.expectError(gl.INVALID_VALUE);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X, texCube, maxSizeCube);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if textarget and texture are not compatible.');
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X, tex2D, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.deleteTexture(tex2D);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texCube, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.deleteTexture(texCube);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if zero is bound to target.');
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteFramebuffer(fbo);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'renderbuffer_storage', 'Invalid glRenderbufferStorage() usage', gl,
+ function() {
+ var rbo = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.RENDERBUFFER.');
+ gl.renderbufferStorage(-1, gl.RGBA4, 1, 1);
+ this.expectError(gl.INVALID_ENUM);
+ gl.renderbufferStorage(gl.FRAMEBUFFER, gl.RGBA4, 1, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if internalformat is not a color-renderable, depth-renderable, or stencil-renderable format.');
+ gl.renderbufferStorage(gl.RENDERBUFFER, -1, 1, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ // EXT_color_buffer_half_float disables error
+ if (gl.getExtension('EXT_color_buffer_half_float') === null) {
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB16F, 1, 1);
+ this.expectError(gl.INVALID_ENUM);
+ }
+
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8_SNORM, 1, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width or height is less than zero.');
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, -1, 1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 1, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, -1, -1);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width or height is greater than gl.MAX_RENDERBUFFER_SIZE.');
+ var maxSize = /** @type {number} */ (gl.getParameter(gl.MAX_RENDERBUFFER_SIZE));
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 1, maxSize + 1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, maxSize + 1, 1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, maxSize + 1, maxSize + 1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.deleteRenderbuffer(rbo);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'blit_framebuffer', 'Invalid glBlitFramebuffer() usage', gl,
+ function() {
+
+ /** @type {Array<WebGLTexture>} */
+ var texture = [
+ gl.createTexture(), gl.createTexture()
+ ];
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+
+ /** @type {Array<WebGLRenderbuffer>} */
+ var rbo = [
+ gl.createRenderbuffer(), gl.createRenderbuffer()
+ ];
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo[0]);
+
+ /** @type {Array<WebGLFramebuffer>} */
+ var fbo = [
+ gl.createFramebuffer(), gl.createFramebuffer()
+ ];
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo[0]);
+
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH24_STENCIL8, 32, 32);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture[0], 0);
+ gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo[0]);
+ gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER);
+ gl.bindTexture(gl.TEXTURE_2D, texture[1]);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo[1]);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo[1]);
+
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH24_STENCIL8, 32, 32);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture[1], 0);
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo[1]);
+ gl.checkFramebufferStatus(gl.DRAW_FRAMEBUFFER);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if mask contains any of the gl.DEPTH_BUFFER_BIT or gl.STENCIL_BUFFER_BIT and filter is not gl.NEAREST.');
+ gl.blitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT, gl.LINEAR);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.blitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT, gl.LINEAR);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.blitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT, gl.LINEAR);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if mask contains gl.COLOR_BUFFER_BIT and read buffer format is incompatible with draw buffer format.');
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32UI, 32, 32, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT, null);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture[0], 0);
+ bufferedLogToConsole('// Read buffer: gl.RGBA32UI, draw buffer: gl.RGBA');
+ gl.blitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32I, 32, 32, 0, gl.RGBA_INTEGER, gl.INT, null);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture[0], 0);
+ bufferedLogToConsole('// Read buffer: gl.RGBA32I, draw buffer: gl.RGBA');
+ gl.blitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture[0], 0);
+ gl.bindTexture(gl.TEXTURE_2D, texture[1]);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32I, 32, 32, 0, gl.RGBA_INTEGER, gl.INT, null);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture[1], 0);
+ bufferedLogToConsole('// Read buffer: gl.RGBA8, draw buffer: gl.RGBA32I');
+ gl.blitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if filter is gl.LINEAR and the read buffer contains integer data.');
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32UI, 32, 32, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT, null);
+ gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture[0], 0);
+ gl.bindTexture(gl.TEXTURE_2D, texture[1]);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32UI, 32, 32, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT, null);
+ gl.framebufferTexture2D(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture[1], 0);
+ bufferedLogToConsole('// Read buffer: gl.RGBA32UI, filter: gl.LINEAR');
+ gl.blitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, gl.COLOR_BUFFER_BIT, gl.LINEAR);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if mask contains gl.DEPTH_BUFFER_BIT or gl.STENCIL_BUFFER_BIT and the source and destination depth and stencil formats do not match.');
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo[0]);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH32F_STENCIL8, 32, 32);
+ gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo[0]);
+ gl.blitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, gl.DEPTH_BUFFER_BIT, gl.NEAREST);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.blitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, gl.STENCIL_BUFFER_BIT, gl.NEAREST);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo[1]);
+ gl.deleteFramebuffer(fbo[0]);
+ gl.deleteTexture(texture[1]);
+ gl.deleteTexture(texture[0]);
+ gl.deleteRenderbuffer(rbo[1]);
+ gl.deleteRenderbuffer(rbo[0]);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'blit_framebuffer_multisample', 'Invalid glBlitFramebuffer() usage', gl,
+ function() {
+
+ /** @type {Array<WebGLRenderbuffer>} */
+ var rbo = [
+ gl.createRenderbuffer(), gl.createRenderbuffer()
+ ];
+ /** @type {Array<WebGLFramebuffer>} */
+ var fbo = [
+ gl.createFramebuffer(), gl.createFramebuffer()
+ ];
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo[0]);
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo[0]);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, gl.RGBA8, 32, 32);
+ gl.framebufferRenderbuffer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo[0]);
+ gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER);
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo[1]);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, fbo[1]);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the value of gl.SAMPLE_BUFFERS for the draw buffer is greater than zero.');
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, gl.RGBA8, 32, 32);
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo[1]);
+ gl.blitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.SAMPLE_BUFFERS for the read buffer is greater than zero and the formats of draw and read buffers are not identical.');
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 32, 32);
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo[1]);
+ gl.blitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.SAMPLE_BUFFERS for the read buffer is greater than zero and the source and destination rectangles are not defined with the same (X0, Y0) and (X1, Y1) bounds.');
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, 32, 32);
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo[1]);
+ gl.blitFramebuffer(0, 0, 16, 16, 2, 2, 18, 18, gl.COLOR_BUFFER_BIT, gl.NEAREST);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteRenderbuffer(rbo[0]);
+ gl.deleteRenderbuffer(rbo[1]);
+ gl.deleteFramebuffer(fbo[0]);
+ gl.deleteFramebuffer(fbo[1]);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'framebuffer_texture_layer', 'Invalid glFramebufferTextureLayer() usage', gl,
+ function() {
+
+ var fbo = gl.createFramebuffer();
+ var tex3D = gl.createTexture();
+ var tex2DArray = gl.createTexture();
+ var tex2D = gl.createTexture();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ gl.bindTexture(gl.TEXTURE_3D, tex3D);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, tex2DArray);
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture(gl.TEXTURE_2D, tex2D);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not one of the accepted tokens.');
+ gl.framebufferTextureLayer(-1, gl.COLOR_ATTACHMENT0, tex3D, 0, 1);
+ this.expectError(gl.INVALID_ENUM);
+ gl.framebufferTextureLayer(gl.RENDERBUFFER, gl.COLOR_ATTACHMENT0, tex3D, 0, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if attachment is not one of the accepted tokens.');
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, -1, tex3D, 0, 1);
+ this.expectError(gl.INVALID_ENUM);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.BACK, tex3D, 0, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if texture is non-zero and not the name of a 3D texture or 2D array texture.');
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex2D, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if texture is not zero and layer is negative.');
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3D, 0, -1);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if texture is not zero and layer is greater than gl.MAX_3D_TEXTURE_SIZE-1 for a 3D texture.');
+ var max3DTexSize = /** @type {number} */ (gl.getParameter(gl.MAX_3D_TEXTURE_SIZE));
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3D, 0, max3DTexSize);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if texture is not zero and layer is greater than gl.MAX_ARRAY_TEXTURE_LAYERS-1 for a 2D array texture.');
+ var maxArrayTexLayers = /** @type {number} */ (gl.getParameter(gl.MAX_ARRAY_TEXTURE_LAYERS));
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex2DArray, 0, maxArrayTexLayers);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if zero is bound to target.');
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.framebufferTextureLayer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, tex3D, 0, 1);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteTexture(tex3D);
+ gl.deleteTexture(tex2DArray);
+ gl.deleteTexture(tex2D);
+ gl.deleteFramebuffer(fbo);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'invalidate_framebuffer', 'Invalid gl.invalidateFramebuffer() usage', gl,
+ function() {
+ var maxColorAttachments = /** @type {number} */ (gl.getParameter(gl.MAX_COLOR_ATTACHMENTS));
+ var attachments = [
+ gl.COLOR_ATTACHMENT0
+ ];
+
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.FRAMEBUFFER, gl.READ_FRAMEBUFFER or gl.DRAW_FRAMEBUFFER.');
+ gl.invalidateFramebuffer(-1, attachments);
+ this.expectError(gl.INVALID_ENUM);
+ gl.invalidateFramebuffer(gl.BACK, attachments);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if attachments contains gl.COLOR_ATTACHMENTm and m is greater than or equal to the value of gl.MAX_COLOR_ATTACHMENTS.');
+ gl.invalidateFramebuffer(gl.FRAMEBUFFER, [gl.COLOR_ATTACHMENT0 + maxColorAttachments]);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteTexture(texture);
+ gl.deleteFramebuffer(fbo);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'invalidate_sub_framebuffer', 'Invalid gl.invalidateSubFramebuffer() usage', gl,
+ function() {
+ var fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ this.expectError(gl.NO_ERROR);
+
+ var maxColorAttachments = /** @type {number} */ (gl.getParameter(gl.MAX_COLOR_ATTACHMENTS));
+ var att0 = [gl.COLOR_ATTACHMENT0];
+ var attm = [gl.COLOR_ATTACHMENT0 + maxColorAttachments];
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.FRAMEBUFFER, gl.READ_FRAMEBUFFER or gl.DRAW_FRAMEBUFFER.');
+ gl.invalidateSubFramebuffer(-1, att0, 0, 0, 16, 16);
+ this.expectError(gl.INVALID_ENUM);
+ gl.invalidateSubFramebuffer(gl.BACK, att0, 0, 0, 16, 16);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if attachments contains gl.COLOR_ATTACHMENTm and m is greater than or equal to the value of gl.MAX_COLOR_ATTACHMENTS.');
+ gl.invalidateSubFramebuffer(gl.FRAMEBUFFER, attm, 0, 0, 16, 16);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteFramebuffer(fbo);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'renderbuffer_storage_multisample', 'Invalid glRenderbufferStorageMultisample() usage', gl,
+ function() {
+
+ var rbo = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+ /** @type {Int32Array} */ var samplesSupportedRGBA4 = /** @type {Int32Array} */ gl.getInternalformatParameter(gl.RENDERBUFFER, gl.RGBA4, gl.SAMPLES);
+ // supported samples are written in descending numeric order, so the first one is the max samples
+ var maxSamplesSupportedRGBA4 = samplesSupportedRGBA4[0];
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.RENDERBUFFER.');
+ gl.renderbufferStorageMultisample(-1, 2, gl.RGBA4, 1, 1);
+ this.expectError(gl.INVALID_ENUM);
+ gl.renderbufferStorageMultisample(gl.FRAMEBUFFER, 2, gl.RGBA4, 1, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if samples is greater than the maximum number of samples supported for internalformat.');
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, maxSamplesSupportedRGBA4 + 1, gl.RGBA4, 1, 1);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if internalformat is not a color-renderable, depth-renderable, or stencil-renderable format.');
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 2, -1, 1, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ // EXT_color_buffer_half_float disables error
+ if (gl.getExtension('EXT_color_buffer_half_float') === null) {
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 2, gl.RGB16F, 1, 1);
+ this.expectError(gl.INVALID_ENUM);
+ }
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 2, gl.RGBA8_SNORM, 1, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width or height is less than zero.');
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 2, gl.RGBA4, -1, 1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 2, gl.RGBA4, 1, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 2, gl.RGBA4, -1, -1);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width or height is greater than gl.MAX_RENDERBUFFER_SIZE.');
+ var maxSize = /** @type {number} */ (gl.getParameter(gl.MAX_RENDERBUFFER_SIZE));
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, gl.RGBA4, 1, maxSize + 1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, gl.RGBA4, maxSize + 1, 1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, gl.RGBA4, maxSize + 1, maxSize + 1);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteRenderbuffer(rbo);
+ }
+ ));
+
+ };
+
+ /**
+ * @param {WebGL2RenderingContext} gl
+ */
+ es3fNegativeBufferApiTests.run = function(gl) {
+ var testName = 'negativeBufferApi';
+ var testDescription = 'Negative Buffer API tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.testCases = tcuTestCase.newTest(testName, testDescription, null);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+ try {
+ es3fNegativeBufferApiTests.init(gl);
+ tcuTestCase.runner.runCallback(tcuTestCase.runTestCases);
+ } catch (err) {
+ bufferedLogToConsole(err);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeFragmentApiTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeFragmentApiTests.js
new file mode 100644
index 0000000000..c3675d436f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeFragmentApiTests.js
@@ -0,0 +1,339 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.0 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Negative Fragment Pipe API tests.
+ *//*--------------------------------------------------------------------*/
+'use strict';
+goog.provide('functional.gles3.es3fNegativeFragmentApiTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('functional.gles3.es3fApiCase');
+
+goog.scope(function() {
+
+ var es3fNegativeFragmentApiTests = functional.gles3.es3fNegativeFragmentApiTests;
+ var es3fApiCase = functional.gles3.es3fApiCase;
+ var tcuTestCase = framework.common.tcuTestCase;
+
+ /**
+ * @param {WebGL2RenderingContext} gl
+ */
+ es3fNegativeFragmentApiTests.init = function(gl) {
+
+ var testGroup = tcuTestCase.runner.testCases;
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('scissor', 'Invalid gl.scissor() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if either width or height is negative.');
+ gl.scissor(0, 0, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.scissor(0, 0, 0, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.scissor(0, 0, -1, -1);
+ this.expectError(gl.INVALID_VALUE);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('depth_func', 'Invalid gl.depthFunc() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if func is not an accepted value.');
+ gl.depthFunc(-1);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('viewport', 'Invalid gl.viewport() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if either width or height is negative.');
+ gl.viewport(0, 0, -1, 1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.viewport(0, 0, 1, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.viewport(0, 0, -1, -1);
+ this.expectError(gl.INVALID_VALUE);
+
+ }));
+
+ // Stencil functions
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('stencil_func', 'Invalid gl.stencilFunc() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if func is not one of the eight accepted values.');
+ gl.stencilFunc(-1, 0, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('stencil_func_separate', 'Invalid gl.stencilFuncSeparate() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if face is not gl.FRONT, gl.BACK, or gl.FRONT_AND_BACK.');
+ gl.stencilFuncSeparate(-1, gl.NEVER, 0, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if func is not one of the eight accepted values.');
+ gl.stencilFuncSeparate(gl.FRONT, -1, 0, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('stencil_op', 'Invalid gl.stencilOp() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if sfail, dpfail, or dppass is any value other than the defined symbolic constant values.');
+ gl.stencilOp(-1, gl.ZERO, gl.REPLACE);
+ this.expectError(gl.INVALID_ENUM);
+ gl.stencilOp(gl.KEEP, -1, gl.REPLACE);
+ this.expectError(gl.INVALID_ENUM);
+ gl.stencilOp(gl.KEEP, gl.ZERO, -1);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('stencil_op_separate', 'Invalid gl.stencilOpSeparate() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if face is any value other than gl.FRONT, gl.BACK, or gl.FRONT_AND_BACK.');
+ gl.stencilOpSeparate(-1, gl.KEEP, gl.ZERO, gl.REPLACE);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if sfail, dpfail, or dppass is any value other than the eight defined symbolic constant values.');
+ gl.stencilOpSeparate(gl.FRONT, -1, gl.ZERO, gl.REPLACE);
+ this.expectError(gl.INVALID_ENUM);
+ gl.stencilOpSeparate(gl.FRONT, gl.KEEP, -1, gl.REPLACE);
+ this.expectError(gl.INVALID_ENUM);
+ gl.stencilOpSeparate(gl.FRONT, gl.KEEP, gl.ZERO, -1);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('stencil_mask_separate', 'Invalid gl.stencilMaskSeparate() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if face is not gl.FRONT, gl.BACK, or gl.FRONT_AND_BACK.');
+ gl.stencilMaskSeparate(-1, 0);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ // Blend functions
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('blend_equation', 'Invalid gl.blendEquation() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not gl.FUNC_ADD, gl.FUNC_SUBTRACT, gl.FUNC_REVERSE_SUBTRACT, gl.MAX or gl.MIN.');
+ gl.blendEquation(-1);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('blend_equation_separate', 'Invalid gl.blendEquationSeparate() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if modeRGB is not gl.FUNC_ADD, gl.FUNC_SUBTRACT, gl.FUNC_REVERSE_SUBTRACT, gl.MAX or gl.MIN.');
+ gl.blendEquationSeparate(-1, gl.FUNC_ADD);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if modeAlpha is not gl.FUNC_ADD, gl.FUNC_SUBTRACT, gl.FUNC_REVERSE_SUBTRACT, gl.MAX or gl.MIN.');
+ gl.blendEquationSeparate(gl.FUNC_ADD, -1);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('blend_func', 'Invalid gl.blendFunc() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if either sfactor or dfactor is not an accepted value.');
+ gl.blendFunc(-1, gl.ONE);
+ this.expectError(gl.INVALID_ENUM);
+ gl.blendFunc(gl.ONE, -1);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('blend_func_separate', 'Invalid gl.blendFuncSeparate() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if srcRGB, dstRGB, srcAlpha, or dstAlpha is not an accepted value.');
+ gl.blendFuncSeparate(-1, gl.ONE, gl.SRC_COLOR, gl.ONE_MINUS_SRC_COLOR);
+ this.expectError(gl.INVALID_ENUM);
+ gl.blendFuncSeparate(gl.ZERO, -1, gl.SRC_COLOR, gl.ONE_MINUS_SRC_COLOR);
+ this.expectError(gl.INVALID_ENUM);
+ gl.blendFuncSeparate(gl.ZERO, gl.ONE, -1, gl.ONE_MINUS_SRC_COLOR);
+ this.expectError(gl.INVALID_ENUM);
+ gl.blendFuncSeparate(gl.ZERO, gl.ONE, gl.SRC_COLOR, -1);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ // Rasterization API functions
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('cull_face', 'Invalid gl.cullFace() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
+ gl.cullFace(-1);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('front_face', 'Invalid gl.frontFace() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
+ gl.frontFace(-1);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('line_width', 'Invalid gl.lineWidth() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width is less than or equal to 0.');
+ gl.lineWidth(0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.lineWidth(-1);
+ this.expectError(gl.INVALID_VALUE);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('begin_query', 'Invalid gl.beginQuery() usage', gl, function() {
+ /** @type{Array<WebGLQuery>} */ var ids = [];
+ ids[0] = gl.createQuery();
+ ids[1] = gl.createQuery();
+ ids[2] = gl.createQuery();
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not one of the accepted tokens.');
+ gl.beginQuery(-1, ids[0]);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.beginQuery is executed while a query object of the same target is already active.');
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED, ids[0]);
+ this.expectError(gl.NO_ERROR);
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED, ids[1]);
+ this.expectError(gl.INVALID_OPERATION);
+ // \note gl.ANY_SAMPLES_PASSED and gl.ANY_SAMPLES_PASSED_CONSERVATIVE alias to the same target for the purposes of this error.
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED_CONSERVATIVE, ids[1]);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, ids[1]);
+ this.expectError(gl.NO_ERROR);
+ gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, ids[2]);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.endQuery(gl.ANY_SAMPLES_PASSED);
+ gl.endQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('An exception is thrown if the name is null.');
+ this.expectThrowNoError(function() {
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED, null);
+ });
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the name has since been deleted with gl.deleteQuery.');
+ gl.deleteQuery(ids[2]);
+ this.expectError(gl.NO_ERROR);
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED, ids[2]);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if id is the name of an already active query object.');
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED, ids[0]);
+ this.expectError(gl.NO_ERROR);
+ gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, ids[0]);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if id refers to an existing query object whose type does not does not match target.');
+ gl.endQuery(gl.ANY_SAMPLES_PASSED);
+ this.expectError(gl.NO_ERROR);
+ gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, ids[0]);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteQuery(ids[0]);
+ gl.deleteQuery(ids[1]);
+ gl.deleteQuery(ids[2]);
+ this.expectError(gl.NO_ERROR);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('end_query', 'Invalid gl.endQuery() usage', gl, function() {
+ /** @type{WebGLQuery} */ var id;
+ id = gl.createQuery();
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not one of the accepted tokens.');
+ gl.endQuery(-1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.endQuery is executed when a query object of the same target is not active.');
+ gl.endQuery(gl.ANY_SAMPLES_PASSED);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.beginQuery(gl.ANY_SAMPLES_PASSED, id);
+ this.expectError(gl.NO_ERROR);
+ gl.endQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.endQuery(gl.ANY_SAMPLES_PASSED);
+ this.expectError(gl.NO_ERROR);
+
+ gl.deleteQuery(id);
+ this.expectError(gl.NO_ERROR);
+ }));
+
+ // Sync objects
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('fence_sync', 'Invalid gl.fenceSync() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if condition is not gl.SYNC_GPU_COMMANDS_COMPLETE.');
+ gl.fenceSync(-1, 0);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if flags is not zero.');
+ gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0x0010);
+ this.expectError(gl.INVALID_VALUE);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('wait_sync', 'Invalid gl.waitSync() usage', gl, function() {
+ /** @type{WebGLSync} */ var sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
+
+ bufferedLogToConsole('An exception is thrown if sync is null.');
+ this.expectThrowNoError(function() {
+ gl.waitSync(null, 0, gl.TIMEOUT_IGNORED);
+ });
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if flags is not zero.');
+ gl.waitSync(sync, 0x0010, gl.TIMEOUT_IGNORED);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if timeout is not gl.TIMEOUT_IGNORED.');
+ gl.waitSync(sync, 0, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteSync(sync);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('client_wait_sync', 'Invalid gl.clientWaitSync() usage', gl, function() {
+ /** @type{WebGLSync} */ var sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
+
+ bufferedLogToConsole('An exception is thrown if sync is null.');
+ this.expectThrowNoError(function() {
+ gl.clientWaitSync (null, 0, 0);
+ });
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if flags contains any unsupported flag.');
+ gl.clientWaitSync(sync, 0x00000004, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteSync(sync);
+ }));
+
+ };
+
+ /**
+ * @param {WebGL2RenderingContext} gl
+ */
+ es3fNegativeFragmentApiTests.run = function(gl) {
+ var testName = 'negativeFragmentApi';
+ var testDescription = 'Negative Fragment API tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.testCases = tcuTestCase.newTest(testName, testDescription, null);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+ try {
+ es3fNegativeFragmentApiTests.init(gl);
+ tcuTestCase.runner.runCallback(tcuTestCase.runTestCases);
+ } catch (err) {
+ bufferedLogToConsole(err);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeShaderApiTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeShaderApiTests.js
new file mode 100644
index 0000000000..6e48dab60d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeShaderApiTests.js
@@ -0,0 +1,1195 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fNegativeShaderApiTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('functional.gles3.es3fApiCase');
+
+goog.scope(function() {
+
+ var es3fNegativeShaderApiTests = functional.gles3.es3fNegativeShaderApiTests;
+ var es3fApiCase = functional.gles3.es3fApiCase;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+
+ /**
+ * @type {string}
+ * @const
+ */
+ var vertexShaderSource = '#version 300 es\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(0.0);\n' +
+ '}\n';
+
+ /**
+ * @type {string}
+ * @const
+ */
+ var fragmentShaderSource = '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ /**
+ * @type {string}
+ * @const
+ */
+ var uniformTestVertSource = '#version 300 es\n' +
+ 'uniform mediump vec4 vec4_v;\n' +
+ 'uniform mediump mat4 mat4_v;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = mat4_v * vec4_v;\n' +
+ '}\n';
+
+ /**
+ * @type {string}
+ * @const
+ */
+ var uniformTestFragSource = '#version 300 es\n' +
+ 'uniform mediump ivec4 ivec4_f;\n' +
+ 'uniform mediump uvec4 uvec4_f;\n' +
+ 'uniform sampler2D sampler_f;\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor.xy = (vec4(uvec4_f) + vec4(ivec4_f)).xy;\n' +
+ ' fragColor.zw = texture(sampler_f, vec2(0.0, 0.0)).zw;\n' +
+ '}\n';
+
+ /**
+ * @type {string}
+ * @const
+ */
+ var uniformBlockVertSource = '#version 300 es\n' +
+ 'layout(std140) uniform Block { lowp float var; };\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(var);\n' +
+ '}\n';
+
+ /**
+ * @param {WebGL2RenderingContext} gl
+ */
+ es3fNegativeShaderApiTests.init = function(gl) {
+ var testGroup = tcuTestCase.runner.testCases;
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'create_shader', 'Invalid gl.createShader() usage', gl,
+ function() {
+ bufferedLogToConsole('INVALID_ENUM is generated if shaderType is not an accepted value.');
+ gl.createShader(-1);
+ this.expectError(gl.INVALID_ENUM);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('attach_shader', 'Invalid gl.attachShader() usage', gl,
+ function() {
+ /** @type {WebGLShader} */ var shader1 = gl.createShader(gl.VERTEX_SHADER);
+ /** @type {WebGLShader} */ var shader2 = gl.createShader(gl.VERTEX_SHADER);
+ /** @type {WebGLProgram} */ var program = gl.createProgram();
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if shader is already attached to program.');
+ gl.attachShader(program, shader1);
+ this.expectError(gl.NO_ERROR);
+ gl.attachShader(program, shader1);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if a shader of the same type as shader is already attached to program.');
+ gl.attachShader(program, shader2);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteProgram(program);
+ gl.deleteShader(shader1);
+ gl.deleteShader(shader2);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('detach_shader', 'Invalid gl.detachShader() usage', gl,
+ function() {
+ /** @type {WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
+ /** @type {WebGLProgram} */ var program = gl.createProgram();
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if shader is not attached to program.');
+ gl.detachShader(program, shader);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteProgram(program);
+ gl.deleteShader(shader);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('link_program', 'Invalid gl.linkProgram() usage', gl,
+ function() {
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if program is the currently active program object and transform feedback mode is active.');
+
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ /** @type {WebGLBuffer} */ var buf;
+ /** @type {WebGLTransformFeedback} */ var tfID;
+ /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
+
+ tfID = gl.createTransformFeedback();
+ buf = gl.createBuffer();
+
+ gl.useProgram(program.getProgram());
+ gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram(program.getProgram());
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buf);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+ gl.beginTransformFeedback(gl.TRIANGLES);
+
+ this.expectError(gl.NO_ERROR);
+
+ gl.linkProgram(program.getProgram());
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.endTransformFeedback();
+ gl.deleteTransformFeedback(tfID);
+ gl.deleteBuffer(buf);
+ this.expectError(gl.NO_ERROR);
+
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('use_program', 'Invalid gl.useProgram() usage', gl,
+ function() {
+
+ /** @type {WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback mode is active and not paused.');
+ /** @type {gluShaderProgram.ShaderProgram} */ var program1 = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ /** @type {gluShaderProgram.ShaderProgram} */ var program2 = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ /** @type {WebGLBuffer} */ var buf;
+ /** @type {WebGLTransformFeedback} */ var tfID;
+ /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
+
+ tfID = gl.createTransformFeedback();
+ buf = gl.createBuffer();
+
+ gl.useProgram(program1.getProgram());
+ gl.transformFeedbackVaryings(program1.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram(program1.getProgram());
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buf);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+ gl.beginTransformFeedback(gl.TRIANGLES);
+ this.expectError(gl.NO_ERROR);
+
+ gl.useProgram(program2.getProgram());
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.pauseTransformFeedback();
+ gl.useProgram(program2.getProgram());
+ this.expectError(gl.NO_ERROR);
+
+ gl.endTransformFeedback();
+ gl.deleteTransformFeedback(tfID);
+ gl.deleteBuffer(buf);
+ this.expectError(gl.NO_ERROR);
+
+ gl.useProgram(null);
+ gl.deleteShader(shader);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('bind_sampler', 'Invalid gl.bindSampler() usage', gl,
+ function() {
+ /** @type {number} */ var maxTexImageUnits;
+ /** @type {WebGLSampler} */ var sampler;
+ /** @type {WebGLSampler} */ var buf;
+ maxTexImageUnits = /** @type {number} */ (gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS));
+ sampler = gl.createSampler();
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if unit is greater than or equal to the value of gl.MAX_COMBIED_TEXTURE_IMAGE_UNITS.');
+ gl.bindSampler(maxTexImageUnits, sampler);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if sampler has been deleted by a call to glDeleteSamplers.');
+ gl.deleteSampler(sampler);
+ gl.bindSampler(1, sampler);
+ this.expectError(gl.INVALID_OPERATION);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_sampler_parameteriv', 'Invalid gl.getSamplerParameter() usage', gl,
+ function() {
+ /** @type {number} */ var params;
+ /** @type {WebGLSampler} */ var sampler;
+ sampler = gl.createSampler();
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted value.');
+ params = /** @type {number} */ (gl.getSamplerParameter(sampler, -1));
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.deleteSampler(sampler);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_sampler_parameterfv', 'Invalid gl.getSamplerParameter() usage', gl,
+ function() {
+ /** @type {number} */ var params;
+ /** @type {WebGLSampler} */ var sampler;
+ sampler = gl.createSampler();
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted value.');
+ params = /** @type {number} */ (gl.getSamplerParameter(sampler, -1));
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.deleteSampler(sampler);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('sampler_parameteri', 'Invalid gl.samplerParameteri() usage', gl,
+ function() {
+ /** @type {WebGLSampler} */ var sampler;
+ sampler = gl.createSampler();
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if params should have a defined constant value (based on the value of pname) and does not.');
+ gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_S, -1);
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.deleteSampler(sampler);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'sampler_parameteriv', 'Invalid gl.samplerParameteri() usage', gl,
+ function() {
+ /** @type {number} */ var params;
+ /** @type {WebGLSampler} */ var sampler;
+ sampler = gl.createSampler();
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if params should have a defined constant value (based on the value of pname) and does not.');
+ params = -1;
+ gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_S, params);
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.deleteSampler(sampler);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'sampler_parameterf', 'Invalid glSamplerParameterf() usage', gl,
+ function() {
+ /** @type {WebGLSampler} */ var sampler;
+ sampler = gl.createSampler();
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if params should have a defined constant value (based on the value of pname) and does not.');
+ gl.samplerParameterf(sampler, gl.TEXTURE_WRAP_S, -1.0);
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.deleteSampler(sampler);
+ }
+ ));
+
+ // Shader data commands
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'get_attrib_location', 'Invalid gl.getAttribLocation() usage', gl,
+ function() {
+ /** @type {WebGLProgram} */ var programEmpty = gl.createProgram();
+ /** @type {WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if program has not been successfully linked.');
+ gl.bindAttribLocation(programEmpty, 0, 'test');
+ gl.getAttribLocation(programEmpty, 'test');
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.useProgram(null);
+ gl.deleteShader(shader);
+ gl.deleteProgram(programEmpty);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'get_uniform_location', 'Invalid gl.getUniformLocation() usage', gl,
+ function() {
+ /** @type {WebGLProgram} */ var programEmpty = gl.createProgram();
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if program has not been successfully linked.');
+ gl.getUniformLocation(programEmpty, 'test');
+ this.expectError(gl.INVALID_OPERATION);
+ gl.deleteProgram(programEmpty);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback(
+ 'bind_attrib_location', 'Invalid gl.bindAttribLocation() usage', gl,
+ function() {
+ /** @type {WebGLProgram} */ var program = gl.createProgram();
+ var maxIndex = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
+ gl.bindAttribLocation(program, maxIndex, 'test');
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if name starts with the reserved prefix \'gl.\'.');
+ gl.bindAttribLocation(program, maxIndex-1, 'gl_test');
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteProgram(program);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniform_block_binding', 'Invalid gl.uniformBlockBinding() usage', gl,
+ function() {
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformBlockVertSource, uniformTestFragSource));
+
+ gl.useProgram(program.getProgram());
+
+ /** @type {number} */ var maxUniformBufferBindings;
+ /** @type {number} */ var numActiveUniforms = -1;
+ /** @type {number} */ var numActiveBlocks = -1;
+ maxUniformBufferBindings = /** @type {number} */ (gl.getParameter(gl.MAX_UNIFORM_BUFFER_BINDINGS));
+ numActiveUniforms = /** @type {number} */ (gl.getProgramParameter(program.getProgram(), gl.ACTIVE_UNIFORMS));
+ numActiveBlocks = /** @type {number} */ (gl.getProgramParameter(program.getProgram(), gl.ACTIVE_UNIFORM_BLOCKS));
+ bufferedLogToConsole('// gl.MAX_UNIFORM_BUFFER_BINDINGS = ' + maxUniformBufferBindings);
+ bufferedLogToConsole('// gl.ACTIVE_UNIFORMS = ' + numActiveUniforms);
+ bufferedLogToConsole('// gl.ACTIVE_UNIFORM_BLOCKS = ' + numActiveBlocks);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if uniformBlockIndex is not an active uniform block index of program.');
+ gl.uniformBlockBinding(program.getProgram(), -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.uniformBlockBinding(program.getProgram(), 5, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if uniformBlockBinding is greater than or equal to the value of gl.MAX_UNIFORM_BUFFER_BINDINGS.');
+ gl.uniformBlockBinding(program.getProgram(), maxUniformBufferBindings, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('An exception is thrown if program is null.');
+ this.expectThrowNoError(function() {
+ gl.uniformBlockBinding(null, 0, 0);
+ });
+ }
+ ));
+
+ // glUniform*f
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformf_incompatible_type', 'Invalid glUniform{1234}f() usage', gl,
+ function() {
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+
+ gl.useProgram(program.getProgram());
+ /** @type {WebGLUniformLocation} */ var vec4_v = gl.getUniformLocation(program.getProgram(), 'vec4_v'); // vec4
+ /** @type {WebGLUniformLocation} */ var ivec4_f = gl.getUniformLocation(program.getProgram(), 'ivec4_f'); // ivec4
+ /** @type {WebGLUniformLocation} */ var uvec4_f = gl.getUniformLocation(program.getProgram(), 'uvec4_f'); // uvec4
+ /** @type {WebGLUniformLocation} */ var sampler_f = gl.getUniformLocation(program.getProgram(), 'sampler_f'); // sampler2D
+ this.expectError(gl.NO_ERROR);
+
+ if (vec4_v == null || ivec4_f == null || uvec4_f == null || sampler_f == null) {
+ assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
+ }
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1f(vec4_v, 0.0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2f(vec4_v, 0.0, 0.0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3f(vec4_v, 0.0, 0.0, 0.0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4f(vec4_v, 0.0, 0.0, 0.0, 0.0);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}f is used to load a uniform variable of type int, ivec2, ivec3, ivec4, unsigned int, uvec2, uvec3, uvec4.');
+ gl.useProgram(program.getProgram());
+ gl.uniform4f(ivec4_f, 0.0, 0.0, 0.0, 0.0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4f(uvec4_f, 0.0, 0.0, 0.0, 0.0);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1f(sampler_f, 0.0);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.useProgram(null);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformfv_incompatible_type', 'Invalid glUniform{1234}fv() usage', gl,
+ function() {
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+
+ gl.useProgram(program.getProgram());
+ /** @type {WebGLUniformLocation} */ var vec4_v = gl.getUniformLocation(program.getProgram(), 'vec4_v'); // vec4
+ /** @type {WebGLUniformLocation} */ var ivec4_f = gl.getUniformLocation(program.getProgram(), 'ivec4_f'); // ivec4
+ /** @type {WebGLUniformLocation} */ var uvec4_f = gl.getUniformLocation(program.getProgram(), 'uvec4_f'); // uvec4
+ /** @type {WebGLUniformLocation} */ var sampler_f = gl.getUniformLocation(program.getProgram(), 'sampler_f'); // sampler2D
+ this.expectError(gl.NO_ERROR);
+
+ if (vec4_v == null || ivec4_f == null || uvec4_f == null || sampler_f == null)
+ assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
+
+ /** @type {Float32Array} */ var data = new Float32Array(4);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1fv(vec4_v, new Float32Array(1));
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2fv(vec4_v, new Float32Array(2));
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3fv(vec4_v, new Float32Array(3));
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4fv(vec4_v, new Float32Array(4));
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}fv is used to load a uniform variable of type /** @type {number} */ var , ivec2, ivec3, ivec4, unsigned /** @type {number} */ var , uvec2, uvec3, uvec4.');
+ gl.useProgram(program.getProgram());
+ gl.uniform4fv(ivec4_f, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4fv(uvec4_f, data);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1fv(sampler_f, new Float32Array(1));
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.useProgram(null);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformfv_invalid_count', 'Invalid glUniform{1234}fv() usage', gl,
+ function() {
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+
+ gl.useProgram(program.getProgram());
+ /** @type {WebGLUniformLocation} */ var vec4_v = gl.getUniformLocation(program.getProgram(), 'vec4_v'); // vec4
+ this.expectError(gl.NO_ERROR);
+
+ if (vec4_v == null)
+ assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
+
+ /** @type {Float32Array} */ var data = new Float32Array(12);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if count is greater than 1 and the indicated uniform variable is not an array variable.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1fv(vec4_v, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2fv(vec4_v, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3fv(vec4_v, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4fv(vec4_v, data);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.useProgram(null);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformi_incompatible_type', 'Invalid glUniform{1234}i() usage', gl,
+ function() {
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+
+ gl.useProgram(program.getProgram());
+ /** @type {WebGLUniformLocation} */ var vec4_v = gl.getUniformLocation(program.getProgram(), 'vec4_v'); // vec4
+ /** @type {WebGLUniformLocation} */ var ivec4_f = gl.getUniformLocation(program.getProgram(), 'ivec4_f'); // ivec4
+ /** @type {WebGLUniformLocation} */ var uvec4_f = gl.getUniformLocation(program.getProgram(), 'uvec4_f'); // uvec4
+ /** @type {WebGLUniformLocation} */ var sampler_f = gl.getUniformLocation(program.getProgram(), 'sampler_f'); // sampler2D
+ this.expectError(gl.NO_ERROR);
+
+ if (vec4_v == null || ivec4_f == null || uvec4_f == null || sampler_f == null)
+ assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1i(ivec4_f, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2i(ivec4_f, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3i(ivec4_f, 0, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4i(ivec4_f, 0, 0, 0, 0);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}i is used to load a uniform variable of type unsigned /** @type {number} */ var , uvec2, uvec3, uvec4, or an array of these.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1i(uvec4_f, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2i(uvec4_f, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3i(uvec4_f, 0, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4i(uvec4_f, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}i is used to load a uniform variable of type /** @type {number} */ var , vec2, vec3, or vec4.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1i(vec4_v, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2i(vec4_v, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3i(vec4_v, 0, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4i(vec4_v, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.useProgram(null);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformiv_incompatible_type', 'Invalid glUniform{1234}iv() usage', gl,
+ function() {
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+
+ gl.useProgram(program.getProgram());
+ /** @type {WebGLUniformLocation} */ var vec4_v = gl.getUniformLocation(program.getProgram(), 'vec4_v'); // vec4
+ /** @type {WebGLUniformLocation} */ var ivec4_f = gl.getUniformLocation(program.getProgram(), 'ivec4_f'); // ivec4
+ /** @type {WebGLUniformLocation} */ var uvec4_f = gl.getUniformLocation(program.getProgram(), 'uvec4_f'); // uvec4
+ /** @type {WebGLUniformLocation} */ var sampler_f = gl.getUniformLocation(program.getProgram(), 'sampler_f'); // sampler2D
+ this.expectError(gl.NO_ERROR);
+
+ if (vec4_v == null || ivec4_f == null || uvec4_f == null || sampler_f == null)
+ assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
+
+ /** @type {Int32Array} */ var data1 = new Int32Array(1);
+ /** @type {Int32Array} */ var data2 = new Int32Array(2);
+ /** @type {Int32Array} */ var data3 = new Int32Array(3);
+ /** @type {Int32Array} */ var data4 = new Int32Array(4);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1iv(ivec4_f, data1);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2iv(ivec4_f, data2);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3iv(ivec4_f, data3);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4iv(ivec4_f, data4);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}iv is used to load a uniform variable of type /** @type {number} */ var , vec2, vec3, or vec4.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1iv(vec4_v, data1);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2iv(vec4_v, data2);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3iv(vec4_v, data3);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4iv(vec4_v, data4);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}iv is used to load a uniform variable of type unsigned /** @type {number} */ var , uvec2, uvec3 or uvec4.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1iv(uvec4_f, data1);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2iv(uvec4_f, data2);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3iv(uvec4_f, data3);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4iv(uvec4_f, data4);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.useProgram(null);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformiv_invalid_count', 'Invalid glUniform{1234}iv() usage', gl,
+ function() {
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+
+ gl.useProgram(program.getProgram());
+ /** @type {WebGLUniformLocation} */ var ivec4_f = gl.getUniformLocation(program.getProgram(), 'ivec4_f'); // ivec4
+ this.expectError(gl.NO_ERROR);
+
+ if (ivec4_f == null)
+ assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
+
+ /** @type {Int32Array} */ var data = new Int32Array(12);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if count is greater than 1 and the indicated uniform variable is not an array variable.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1iv(ivec4_f, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2iv(ivec4_f, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3iv(ivec4_f, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4iv(ivec4_f, data);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.useProgram(null);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformui_incompatible_type', 'Invalid glUniform{1234}ui() usage', gl,
+ function() {
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+
+ gl.useProgram(program.getProgram());
+ /** @type {WebGLUniformLocation} */ var vec4_v = gl.getUniformLocation(program.getProgram(), 'vec4_v'); // vec4
+ /** @type {WebGLUniformLocation} */ var ivec4_f = gl.getUniformLocation(program.getProgram(), 'ivec4_f'); // ivec4
+ /** @type {WebGLUniformLocation} */ var uvec4_f = gl.getUniformLocation(program.getProgram(), 'uvec4_f'); // uvec4
+ /** @type {WebGLUniformLocation} */ var sampler_f = gl.getUniformLocation(program.getProgram(), 'sampler_f'); // sampler2D
+ this.expectError(gl.NO_ERROR);
+
+ if (vec4_v == null || ivec4_f == null || uvec4_f == null || sampler_f == null)
+ assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1ui(uvec4_f, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2ui(uvec4_f, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3ui(uvec4_f, 0, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4ui(uvec4_f, 0, 0, 0, 0);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}i is used to load a uniform variable of type /** @type {number} */ var , ivec2, ivec3, ivec4, or an array of these.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1ui(ivec4_f, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2ui(ivec4_f, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3ui(ivec4_f, 0, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4ui(ivec4_f, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}i is used to load a uniform variable of type /** @type {number} */ var , vec2, vec3, or vec4.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1ui(vec4_v, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2ui(vec4_v, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3ui(vec4_v, 0, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4ui(vec4_v, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1ui(sampler_f, 0);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.useProgram(null);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformuiv_incompatible_type', 'Invalid glUniform{1234}uiv() usage', gl,
+ function() {
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+
+ gl.useProgram(program.getProgram());
+ /** @type {WebGLUniformLocation} */ var vec4_v = gl.getUniformLocation(program.getProgram(), 'vec4_v'); // vec4
+ /** @type {WebGLUniformLocation} */ var ivec4_f = gl.getUniformLocation(program.getProgram(), 'ivec4_f'); // ivec4
+ /** @type {WebGLUniformLocation} */ var uvec4_f = gl.getUniformLocation(program.getProgram(), 'uvec4_f'); // uvec4
+ /** @type {WebGLUniformLocation} */ var sampler_f = gl.getUniformLocation(program.getProgram(), 'sampler_f'); // sampler2D
+ this.expectError(gl.NO_ERROR);
+
+ if (vec4_v == null || ivec4_f == null || uvec4_f == null || sampler_f == null)
+ assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
+
+ /** @type {Uint32Array} */ var data1 = new Uint32Array(1);
+ /** @type {Uint32Array} */ var data2 = new Uint32Array(2);
+ /** @type {Uint32Array} */ var data3 = new Uint32Array(3);
+ /** @type {Uint32Array} */ var data4 = new Uint32Array(4);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1uiv(uvec4_f, data1);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2uiv(uvec4_f, data2);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3uiv(uvec4_f, data3);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4uiv(uvec4_f, data4);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}uiv is used to load a uniform variable of type /** @type {number} */ var , vec2, vec3, or vec4.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1uiv(vec4_v, data1);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2uiv(vec4_v, data2);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3uiv(vec4_v, data3);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4uiv(vec4_v, data4);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if glUniform{1234}uiv is used to load a uniform variable of type /** @type {number} */ var , ivec2, ivec3 or ivec4.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1uiv(ivec4_f, data1);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2uiv(ivec4_f, data2);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3uiv(ivec4_f, data3);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4uiv(ivec4_f, data4);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1uiv(sampler_f, data1);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.useProgram(null);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniformuiv_invalid_count', 'Invalid glUniform{1234}uiv() usage', gl,
+ function() {
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+
+ gl.useProgram(program.getProgram());
+ /** @type {WebGLUniformLocation} */ var uvec4_f = gl.getUniformLocation(program.getProgram(), 'uvec4_f'); // uvec4
+ this.expectError(gl.NO_ERROR);
+
+ if (uvec4_f == null)
+ assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
+
+ /** @type {Uint32Array} */ var data = new Uint32Array(12);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if count is greater than 1 and the indicated uniform variable is not an array variable.');
+ gl.useProgram(program.getProgram());
+ gl.uniform1uiv(uvec4_f, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform2uiv(uvec4_f, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform3uiv(uvec4_f, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniform4uiv(uvec4_f, data);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.useProgram(null);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniform_matrixfv_incompatible_type', 'Invalid glUniformMatrix{234}fv() usage', gl,
+ function() {
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+
+ gl.useProgram(program.getProgram());
+ /** @type {WebGLUniformLocation} */ var mat4_v = gl.getUniformLocation(program.getProgram(), 'mat4_v'); // mat4
+ /** @type {WebGLUniformLocation} */ var sampler_f = gl.getUniformLocation(program.getProgram(), 'sampler_f'); // sampler2D
+ this.expectError(gl.NO_ERROR);
+
+ if (mat4_v == null || sampler_f == null)
+ assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
+
+ /** @type {Float32Array} */ var data4 = new Float32Array(4);
+ /** @type {Float32Array} */ var data9 = new Float32Array(9);
+ /** @type {Float32Array} */ var data16 = new Float32Array(16);
+ /** @type {Float32Array} */ var data6 = new Float32Array(6);
+ /** @type {Float32Array} */ var data8 = new Float32Array(8);
+ /** @type {Float32Array} */ var data12 = new Float32Array(12);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the glUniform command.');
+ gl.useProgram(program.getProgram());
+ gl.uniformMatrix2fv(mat4_v, false, data4);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix3fv(mat4_v, false, data9);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix4fv(mat4_v, false, data16);
+ this.expectError(gl.NO_ERROR);
+
+ gl.uniformMatrix2x3fv(mat4_v, false, data6);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix3x2fv(mat4_v, false, data6);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix2x4fv(mat4_v, false, data8);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix4x2fv(mat4_v, false, data8);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix3x4fv(mat4_v, false, data12);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix4x3fv(mat4_v, false, data12);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if a sampler is loaded using a command other than glUniform1i and glUniform1iv.');
+ gl.useProgram(program.getProgram());
+ gl.uniformMatrix2fv(sampler_f, false, data4);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix3fv(sampler_f, false, data9);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix4fv(sampler_f, false, data16);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.uniformMatrix2x3fv(sampler_f, false, data6);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix3x2fv(sampler_f, false, data6);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix2x4fv(sampler_f, false, data8);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix4x2fv(sampler_f, false, data8);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix3x4fv(sampler_f, false, data12);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix4x3fv(sampler_f, false, data12);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.useProgram(null);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('uniform_matrixfv_invalid_count', 'Invalid glUniformMatrix{234}fv() usage', gl,
+ function() {
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+
+ gl.useProgram(program.getProgram());
+ /** @type {WebGLUniformLocation} */ var mat4_v = gl.getUniformLocation(program.getProgram(), 'mat4_v'); // mat4
+ this.expectError(gl.NO_ERROR);
+
+ if (mat4_v == null)
+ assertMsgOptions(false, 'Failed to retrieve uniform location', false, true);
+
+ /** @type {Float32Array} */ var data = new Float32Array(144);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if count is greater than 1 and the indicated uniform variable is not an array variable.');
+ gl.useProgram(program.getProgram());
+ gl.uniformMatrix2fv(mat4_v, false, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix3fv(mat4_v, false, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix4fv(mat4_v, false, data);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.uniformMatrix2x3fv(mat4_v, false, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix3x2fv(mat4_v, false, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix2x4fv(mat4_v, false, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix4x2fv(mat4_v, false, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix3x4fv(mat4_v, false, data);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.uniformMatrix4x3fv(mat4_v, false, data);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.useProgram(null);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('bind_transform_feedback', 'Invalid gl.bindTransformFeedback() usage', gl,
+ function() {
+ /** @type {Array<WebGLTransformFeedback>} */ var tfID = [];
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ /** @type {WebGLBuffer} */ var buf;
+ /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
+
+ buf = gl.createBuffer();
+ tfID[0] = gl.createTransformFeedback();
+ tfID[1] = gl.createTransformFeedback();
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.TRANSFORM_FEEDBACK.');
+ gl.bindTransformFeedback(-1, tfID[0]);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the transform feedback operation is active on the currently bound transform feedback object, and is not paused.');
+ gl.useProgram(program.getProgram());
+ gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram(program.getProgram());
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID[0]);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buf);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+ gl.beginTransformFeedback(gl.TRIANGLES);
+ this.expectError(gl.NO_ERROR);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID[1]);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.endTransformFeedback();
+ this.expectError(gl.NO_ERROR);
+
+ gl.useProgram(null);
+ gl.deleteBuffer(buf);
+ gl.deleteTransformFeedback(tfID[0]);
+ gl.deleteTransformFeedback(tfID[1]);
+ this.expectError(gl.NO_ERROR);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('begin_transform_feedback', 'Invalid gl.beginTransformFeedback() usage', gl,
+ function() {
+ /** @type {Array<WebGLTransformFeedback>} */ var tfID = [];
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ /** @type {WebGLBuffer} */ var buf;
+ /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
+
+ buf = gl.createBuffer();
+ tfID[0] = gl.createTransformFeedback();
+ tfID[1] = gl.createTransformFeedback();
+
+ gl.useProgram(program.getProgram());
+ gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram(program.getProgram());
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID[0]);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buf);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if primitiveMode is not one of gl.POINTS, gl.LINES, or gl.TRIANGLES.');
+ gl.beginTransformFeedback(-1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is already active.');
+ gl.beginTransformFeedback(gl.TRIANGLES);
+ this.expectError(gl.NO_ERROR);
+ gl.beginTransformFeedback(gl.POINTS);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if any binding point used in transform feedback mode does not have a buffer object bound.');
+ /** @type{WebGLBuffer} */ var dummyBuf = gl.createBuffer()
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, dummyBuf);
+ gl.beginTransformFeedback(gl.TRIANGLES);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if no binding points would be used because no program object is active.');
+ gl.useProgram(null);
+ gl.beginTransformFeedback(gl.TRIANGLES);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.useProgram(program.getProgram());
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if no binding points would be used because the active program object has specified no varying variables to record.');
+ gl.transformFeedbackVaryings(program.getProgram(), [], gl.INTERLEAVED_ATTRIBS);
+ gl.beginTransformFeedback(gl.TRIANGLES);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.endTransformFeedback();
+ gl.deleteBuffer(buf);
+ gl.deleteBuffer(dummyBuf);
+ gl.deleteTransformFeedback(tfID[0]);
+ gl.deleteTransformFeedback(tfID[1]);
+ this.expectError(gl.NO_ERROR);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('pause_transform_feedback', 'Invalid gl.pauseTransformFeedback() usage', gl,
+ function() {
+ /** @type {Array<WebGLTransformFeedback>} */ var tfID = [];
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ /** @type {WebGLBuffer} */ var buf;
+ /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
+
+ buf = gl.createBuffer();
+ tfID[0] = gl.createTransformFeedback();
+ tfID[1] = gl.createTransformFeedback();
+
+ gl.useProgram(program.getProgram());
+ gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram(program.getProgram());
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID[0]);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buf);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the currently bound transform feedback object is not active or is paused.');
+ gl.pauseTransformFeedback();
+ this.expectError(gl.INVALID_OPERATION);
+ gl.beginTransformFeedback(gl.TRIANGLES);
+ gl.pauseTransformFeedback();
+ this.expectError(gl.NO_ERROR);
+ gl.pauseTransformFeedback();
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.endTransformFeedback();
+ gl.deleteBuffer(buf);
+ gl.deleteTransformFeedback(tfID[0]);
+ gl.deleteTransformFeedback(tfID[1]);
+ this.expectError(gl.NO_ERROR);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('resume_transform_feedback', 'Invalid gl.resumeTransformFeedback() usage', gl,
+ function() {
+ /** @type {Array<WebGLTransformFeedback>} */ var tfID = [];
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ /** @type {WebGLBuffer} */ var buf;
+ /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
+
+ buf = gl.createBuffer();
+ tfID[0] = gl.createTransformFeedback();
+ tfID[1] = gl.createTransformFeedback();
+
+ gl.useProgram(program.getProgram());
+ gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram(program.getProgram());
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID[0]);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buf);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the currently bound transform feedback object is not active or is not paused.');
+ gl.resumeTransformFeedback();
+ this.expectError(gl.INVALID_OPERATION);
+ gl.beginTransformFeedback(gl.TRIANGLES);
+ gl.resumeTransformFeedback();
+ this.expectError(gl.INVALID_OPERATION);
+ gl.pauseTransformFeedback();
+ gl.resumeTransformFeedback();
+ this.expectError(gl.NO_ERROR);
+
+ gl.endTransformFeedback();
+ gl.deleteBuffer(buf);
+ gl.deleteTransformFeedback(tfID[0]);
+ gl.deleteTransformFeedback(tfID[1]);
+ this.expectError(gl.NO_ERROR);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('end_transform_feedback', 'Invalid gl.endTransformFeedback() usage', gl,
+ function() {
+ /** @type {WebGLTransformFeedback} */ var tfID;
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ /** @type {WebGLBuffer} */ var buf;
+ /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
+
+ buf = gl.createBuffer();
+ tfID = gl.createTransformFeedback();
+
+ gl.useProgram(program.getProgram());
+ gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram(program.getProgram());
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID);
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buf);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is not active.');
+ gl.endTransformFeedback();
+ this.expectError(gl.INVALID_OPERATION);
+ gl.beginTransformFeedback(gl.TRIANGLES);
+ gl.endTransformFeedback();
+ this.expectError(gl.NO_ERROR);
+
+ gl.deleteBuffer(buf);
+ gl.deleteTransformFeedback(tfID);
+ this.expectError(gl.NO_ERROR);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_transform_feedback_varying', 'Invalid glGetTransformFeedbackVarying() usage', gl,
+ function() {
+ /** @type {WebGLTransformFeedback} */ var tfID;
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ /** @type {gluShaderProgram.ShaderProgram} */ var programInvalid = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, ''));
+ /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
+ /** @type {number} */ var maxTransformFeedbackVaryings = 0;
+
+ /** @type {number} */ var length;
+ /** @type {number} */ var size;
+ /** @type {number} */ var type;
+ /** @type {WebGLActiveInfo} */ var name;
+
+ tfID = gl.createTransformFeedback();
+
+ gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
+ this.expectError(gl.NO_ERROR);
+ gl.linkProgram(program.getProgram());
+ this.expectError(gl.NO_ERROR);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, tfID);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('An exception is thrown if program is null.');
+ this.expectThrowNoError(function() {
+ gl.getTransformFeedbackVarying(null, 0);
+ });
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater or equal to the value of gl.TRANSFORM_FEEDBACK_VARYINGS.');
+ maxTransformFeedbackVaryings = /** @type {number} */ (gl.getProgramParameter(program.getProgram(), gl.TRANSFORM_FEEDBACK_VARYINGS));
+ name = gl.getTransformFeedbackVarying(program.getProgram(), maxTransformFeedbackVaryings);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION or gl.INVALID_VALUE is generated program has not been linked.');
+ name = gl.getTransformFeedbackVarying(programInvalid.getProgram(), 0);
+ this.expectError([gl.INVALID_OPERATION, gl.INVALID_VALUE]);
+
+ gl.deleteTransformFeedback(tfID);
+ this.expectError(gl.NO_ERROR);
+ }
+ ));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('transform_feedback_varyings', 'Invalid gl.transformFeedbackVaryings() usage', gl,
+ function() {
+ /** @type {WebGLTransformFeedback} */ var tfID;
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ /** @type {Array<string>} */ var tfVarying = ['gl_Position'];
+ /** @type {number} */ var maxTransformFeedbackSeparateAttribs = 0;
+
+ tfID = gl.createTransformFeedback();
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('An exception is thrown if program is null.');
+ this.expectThrowNoError(function() {
+ gl.transformFeedbackVaryings(null, tfVarying, gl.INTERLEAVED_ATTRIBS);
+ });
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if bufferMode is gl.SEPARATE_ATTRIBS and count is greater than gl.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS.');
+ maxTransformFeedbackSeparateAttribs = /** @type {number} */ (gl.getParameter(gl.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS));
+ for (var count = 0; count < maxTransformFeedbackSeparateAttribs; ++count) {
+ tfVarying = tfVarying.concat(['gl_Position']);
+ }
+ gl.transformFeedbackVaryings(program.getProgram(), tfVarying, gl.SEPARATE_ATTRIBS);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTransformFeedback(tfID);
+ this.expectError(gl.NO_ERROR);
+ }
+ ));
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} gl
+ */
+ es3fNegativeShaderApiTests.run = function(gl) {
+ //Set up Test Root parameters
+ var testName = 'negative_shader_api';
+ var testDescription = 'Negative Shader Api Tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.testCases = tcuTestCase.newTest(testName, testDescription, null);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+ try {
+ es3fNegativeShaderApiTests.init(gl);
+ tcuTestCase.runner.runCallback(tcuTestCase.runTestCases);
+ } catch (err) {
+ bufferedLogToConsole(err);
+ tcuTestCase.runner.terminate();
+ }
+ };
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeStateApiTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeStateApiTests.js
new file mode 100644
index 0000000000..40d6384edc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeStateApiTests.js
@@ -0,0 +1,927 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.0 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Negative GL State API tests.
+ *//*--------------------------------------------------------------------*/
+'use strict';
+goog.provide('functional.gles3.es3fNegativeStateApiTests');
+
+goog.require('framework.common.tcuTestCase');
+goog.require('functional.gles3.es3fApiCase');
+goog.require('framework.opengl.gluShaderProgram');
+
+goog.scope(function() {
+
+ var es3fNegativeStateApiTests = functional.gles3.es3fNegativeStateApiTests;
+ var es3fApiCase = functional.gles3.es3fApiCase;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+
+ /**
+ * @type {string}
+ * @const
+ */
+ var uniformTestVertSource = '#version 300 es\n' +
+ 'uniform mediump vec4 vUnif_vec4;\n' +
+ 'in mediump vec4 attr;\n' +
+ 'layout(std140) uniform Block { mediump vec4 blockVar; };\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vUnif_vec4 + blockVar + attr;\n' +
+ '}\n';
+
+ /**
+ * @type {string}
+ * @const
+ */
+ var uniformTestFragSource = '#version 300 es\n' +
+ 'uniform mediump ivec4 fUnif_ivec4;\n' +
+ 'uniform mediump uvec4 fUnif_uvec4;\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(vec4(fUnif_ivec4) + vec4(fUnif_uvec4));\n' +
+ '}\n';
+
+ /**
+ * @param {WebGL2RenderingContext} gl
+ */
+ es3fNegativeStateApiTests.init = function(gl) {
+
+ var testGroup = tcuTestCase.runner.testCases;
+
+ // Enabling & disabling states
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('enable', 'Invalid gl.enable() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if cap is not one of the allowed values.');
+ gl.enable(-1);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('disable', 'Invalid gl.disable() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if cap is not one of the allowed values.');
+ gl.disable(-1);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ // Simple state queries
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_parameter', 'Invalid gl.getParameter() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not one of the allowed values.');
+ /** @type{boolean} */ var params = false;
+ //glGetBooleanv(-1, params);
+ params = /** @type{boolean} */ (gl.getParameter(-1));
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_indexed_parameter', 'Invalid gl.getIndexedParameter() usage', gl, function() {
+ /** @type{number} */ var data = -1;
+ /** @type{number} */ var maxUniformBufferBindings;
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if name is not an accepted value.');
+ data = /** @type{number} */ (gl.getIndexedParameter(-1, 0));
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is outside of the valid range for the indexed state target.');
+ maxUniformBufferBindings = /** @type{number} */ (gl.getParameter(gl.MAX_UNIFORM_BUFFER_BINDINGS));
+ this.expectError(gl.NO_ERROR);
+ data = /** @type{number} */ (gl.getIndexedParameter(gl.UNIFORM_BUFFER_BINDING, maxUniformBufferBindings));
+ this.expectError(gl.INVALID_VALUE);
+
+ }));
+
+ // Enumerated state queries: Shaders
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_attached_shaders', 'Invalid gl.getAttachedShaders() usage', gl, function() {
+ /** @type{WebGLShader} */ var shaderObject = gl.createShader(gl.VERTEX_SHADER);
+ /** @type{WebGLProgram} */ var program = gl.createProgram();
+
+ bufferedLogToConsole('An exception is thrown if program is null.');
+ this.expectThrowNoError(function() {
+ gl.getAttachedShaders(null);
+ });
+
+ gl.deleteShader(shaderObject);
+ gl.deleteProgram(program);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_shader_parameter', 'Invalid gl.getShaderParameter() usage', gl, function() {
+ /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
+ /** @type{WebGLProgram} */ var program = gl.createProgram();
+ /** @type{number} */ var param = -1;
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted value.');
+ param = /** @type{number} */ (gl.getShaderParameter(shader, -1));
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('An exception is thrown if shader is null.');
+ this.expectThrowNoError(function() {
+ gl.getShaderParameter(null, gl.SHADER_TYPE);
+ });
+
+ gl.deleteShader(shader);
+ gl.deleteProgram(program);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_shader_info_log', 'Invalid gl.getShaderInfoLog() usage', gl, function() {
+ /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
+ /** @type{WebGLProgram} */ var program = gl.createProgram();
+
+ bufferedLogToConsole('An exception is thrown if shader is null.');
+ this.expectThrowNoError(function() {
+ gl.getShaderInfoLog(null);
+ });
+
+ gl.deleteShader(shader);
+ gl.deleteProgram(program);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_shader_precision_format', 'Invalid gl.getShaderPrecisionFormat() usage', gl, function() {
+ /** @type{WebGLShaderPrecisionFormat } */ var precision;
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if shaderType or precisionType is not an accepted value.');
+ precision = gl.getShaderPrecisionFormat (-1, gl.MEDIUM_FLOAT);
+ this.expectError(gl.INVALID_ENUM);
+ precision = gl.getShaderPrecisionFormat (gl.VERTEX_SHADER, -1);
+ this.expectError(gl.INVALID_ENUM);
+ precision = gl.getShaderPrecisionFormat (-1, -1);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_shader_source', 'Invalid gl.getShaderSource() usage', gl, function() {
+ /** @type{WebGLProgram} */ var program = gl.createProgram();
+ /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
+
+ bufferedLogToConsole('An exception is thrown if shader is null.');
+ this.expectThrowNoError(function() {
+ gl.getShaderSource(null);
+ });
+
+ gl.deleteProgram(program);
+ gl.deleteShader(shader);
+ }));
+
+ // Enumerated state queries: Programs
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_program_parameter', 'Invalid gl.getProgramParameter() usage', gl, function() {
+ /** @type{WebGLProgram} */ var program = gl.createProgram();
+ /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
+ /** @type{boolean} */ var params;
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted value.');
+ params = /** @type{boolean} */ (gl.getProgramParameter(program, -1));
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('An exception is thrown if program is null.');
+ this.expectThrowNoError(function() {
+ gl.getProgramParameter(null, gl.LINK_STATUS);
+ });
+
+ gl.deleteProgram(program);
+ gl.deleteShader(shader);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_program_info_log', 'Invalid gl.getProgramInfoLog() usage', gl, function() {
+ /** @type{WebGLProgram} */ var program = gl.createProgram();
+ /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
+
+ bufferedLogToConsole('An exception is thrown if program is null.');
+ this.expectThrowNoError(function() {
+ gl.getProgramInfoLog (null);
+ });
+
+ gl.deleteProgram(program);
+ gl.deleteShader(shader);
+ }));
+
+ // Enumerated state queries: Shader variables
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_tex_parameter', 'Invalid gl.getTexParameter() usage', gl, function() {
+ /** @type{WebGLTexture} */ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target or pname is not an accepted value.');
+ gl.getTexParameter (-1, gl.TEXTURE_MAG_FILTER);
+ this.expectError(gl.INVALID_ENUM);
+ gl.getTexParameter (gl.TEXTURE_2D, -1);
+ this.expectError(gl.INVALID_ENUM);
+ gl.getTexParameter (-1, -1);
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.deleteTexture(texture);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_uniform', 'Invalid gl.getUniform() usage', gl, function() {
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+ gl.useProgram(program.getProgram());
+
+ /** @type{WebGLUniformLocation} */ var unif = gl.getUniformLocation(program.getProgram(), 'vUnif_vec4'); // vec4
+ assertMsgOptions(unif != null, 'Failed to retrieve uniform location', false, true);
+
+ /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
+ /** @type{WebGLProgram} */ var programEmpty = gl.createProgram();
+ /** @type{*} */ var params;
+
+ bufferedLogToConsole('An exception is thrown if program is null.');
+ this.expectThrowNoError(function() {
+ gl.getUniform (null, unif);
+ });
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if program has not been successfully linked.');
+ params = gl.getUniform (programEmpty, unif);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('An exception is thrown if location is null.');
+ this.expectThrowNoError(function() {
+ gl.getUniform (program.getProgram(), null);
+ });
+
+ gl.deleteShader(shader);
+ gl.deleteProgram(programEmpty);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_active_uniform', 'Invalid gl.getActiveUniform() usage', gl, function() {
+ /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+ /** @type{number} */ var numActiveUniforms = -1;
+
+ numActiveUniforms = /** @type{number} */ (gl.getProgramParameter(program.getProgram(), gl.ACTIVE_UNIFORMS));
+ bufferedLogToConsole('// gl.ACTIVE_UNIFORMS = ' + numActiveUniforms + ' (expected 4).');
+
+ bufferedLogToConsole('An exception is thrown if program is null.');
+ this.expectThrowNoError(function() {
+ gl.getActiveUniform(null, 0);
+ });
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to the number of active uniform variables in program.');
+ gl.useProgram(program.getProgram());
+ gl.getActiveUniform(program.getProgram(), numActiveUniforms);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.useProgram(null);
+ gl.deleteShader(shader);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_active_uniforms', 'Invalid gl.getActiveUniforms() usage', gl, function() {
+ /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+ /** @type{Array<number>} */ var dummyUniformIndex = [1];
+ /** @type{Array<number>} */ var dummyParamDst;
+ /** @type{number} */ var numActiveUniforms = -1;
+
+ gl.useProgram(program.getProgram());
+
+ numActiveUniforms = /** @type{number} */ (gl.getProgramParameter(program.getProgram(), gl.ACTIVE_UNIFORMS));
+ bufferedLogToConsole('// gl.ACTIVE_UNIFORMS = ' + numActiveUniforms + ' (expected 4).');
+
+ bufferedLogToConsole('An exception is thrown if program is null.');
+ this.expectThrowNoError(function() {
+ gl.getActiveUniforms(null, dummyUniformIndex, gl.UNIFORM_TYPE);
+ });
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if any value in uniformIndices is greater than or equal to the value of gl.ACTIVE_UNIFORMS for program.');
+ /** @type{Array<number>} */ var invalidUniformIndices;
+ /** @type{Array<number>} */ var dummyParamsDst;
+ for (var excess = 0; excess <= 2; excess++) {
+ invalidUniformIndices = [1, numActiveUniforms - 1 + excess, 1];
+ dummyParamsDst = gl.getActiveUniforms(program.getProgram(), invalidUniformIndices, gl.UNIFORM_TYPE);
+ this.expectError(excess == 0 ? gl.NO_ERROR : gl.INVALID_VALUE);
+ }
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted token.');
+ dummyParamDst = gl.getActiveUniforms(program.getProgram(), dummyUniformIndex, -1);
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.useProgram(null);
+ gl.deleteShader(shader);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_active_uniform_block_parameter', 'Invalid gl.getActiveUniformBlockParameter() usage', gl, function() {
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+ /** @type{*} */ var params;
+ /** @type{number} */ var numActiveBlocks = -1;
+
+ numActiveBlocks = /** @type{number} */ (gl.getProgramParameter(program.getProgram(), gl.ACTIVE_UNIFORM_BLOCKS));
+ bufferedLogToConsole('// gl.ACTIVE_UNIFORM_BLOCKS = ' + numActiveBlocks + ' (expected 1).');
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if uniformBlockIndex is greater than or equal to the value of gl.ACTIVE_UNIFORM_BLOCKS or is not the index of an active uniform block in program.');
+ gl.useProgram(program.getProgram());
+ this.expectError(gl.NO_ERROR);
+ params = gl.getActiveUniformBlockParameter(program.getProgram(), numActiveBlocks, gl.UNIFORM_BLOCK_BINDING);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not one of the accepted tokens.');
+ params = gl.getActiveUniformBlockParameter(program.getProgram(), 0, -1);
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.useProgram(null);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_active_uniform_block_name', 'Invalid gl.getActiveUniformBlockName() usage', gl, function() {
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+ /** @type{number} */ var length = -1;
+ /** @type{number} */ var numActiveBlocks = -1;
+ /** @type{string} */ var uniformBlockName;
+
+ numActiveBlocks = /** @type{number} */ (gl.getProgramParameter(program.getProgram(), gl.ACTIVE_UNIFORM_BLOCKS));
+ bufferedLogToConsole('// gl.ACTIVE_UNIFORM_BLOCKS = ' + numActiveBlocks + ' (expected 1).');
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if uniformBlockIndex is greater than or equal to the value of gl.ACTIVE_UNIFORM_BLOCKS or is not the index of an active uniform block in program.');
+ gl.useProgram(program.getProgram());
+ this.expectError(gl.NO_ERROR);
+ uniformBlockName = gl.getActiveUniformBlockName(program.getProgram(), numActiveBlocks);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.useProgram(null);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_active_attrib', 'Invalid gl.getActiveAttrib() usage', gl, function() {
+ /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+ /** @type{number} */ var numActiveAttributes = -1;
+
+ /** @type{WebGLActiveInfo} */ var activeInfo;
+ /** @type{number} */ var size = -1;
+ /** @type{number} */ var type = -1;
+ /** @type{string} */ var name;
+
+ numActiveAttributes = /** @type{number} */(gl.getProgramParameter(program.getProgram(), gl.ACTIVE_ATTRIBUTES));
+ bufferedLogToConsole('// gl.ACTIVE_ATTRIBUTES = ' + numActiveAttributes + ' (expected 1).');
+
+ gl.useProgram(program.getProgram());
+
+ bufferedLogToConsole('An exception is thrown if program is null.');
+ this.expectThrowNoError(function() {
+ gl.getActiveAttrib(null, 0);
+ });
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.ACTIVE_ATTRIBUTES.');
+ activeInfo = gl.getActiveAttrib(program.getProgram(), numActiveAttributes);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.useProgram(null);
+ gl.deleteShader(shader);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_uniform_indices', 'Invalid gl.getUniformIndices() usage', gl, function() {
+ /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
+ gl.useProgram(program.getProgram());
+ /** @type{number} */ var numActiveBlocks = -1;
+ /** @type{Array<string>} */ var uniformName = ['Block.blockVar'];
+ /** @type{Array<number>} */ var uniformIndices = [-1];
+
+ numActiveBlocks = /** @type{number} */(gl.getProgramParameter(program.getProgram(), gl.ACTIVE_UNIFORM_BLOCKS));
+ bufferedLogToConsole('// gl.ACTIVE_UNIFORM_BLOCKS = ' + numActiveBlocks);
+ this.expectError (gl.NO_ERROR);
+
+ bufferedLogToConsole('An exception is thrown if program is null.');
+ this.expectThrowNoError(function() {
+ gl.getUniformIndices(null, uniformName);
+ });
+
+ gl.useProgram(null);
+ gl.deleteShader(shader);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_vertex_attrib', 'Invalid gl.getVertexAttrib() usage', gl, function() {
+ /** @type{*} */ var params;
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted value.');
+ params = gl.getVertexAttrib(0, -1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
+ /** @type{number} */ var maxVertexAttribs;
+ maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ params = gl.getVertexAttrib(maxVertexAttribs, gl.VERTEX_ATTRIB_ARRAY_ENABLED);
+ this.expectError(gl.INVALID_VALUE);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_vertex_attrib_offset', 'Invalid gl.getVertexAttribOffset() usage', gl, function() {
+ /** @type{number} */ var ptr;
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted value.');
+ ptr = gl.getVertexAttribOffset(0, -1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
+ /** @type{number} */ var maxVertexAttribs;
+ maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ ptr = gl.getVertexAttribOffset(maxVertexAttribs, gl.VERTEX_ATTRIB_ARRAY_POINTER);
+ this.expectError(gl.INVALID_VALUE);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_frag_data_location', 'Invalid gl.getFragDataLocation() usage', gl, function() {
+ /** @type{WebGLShader} */ var shader = gl.createShader(gl.VERTEX_SHADER);
+ /** @type{WebGLProgram} */ var program = gl.createProgram();
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if program has not been linked.');
+ gl.getFragDataLocation(program, 'gl_FragColor');
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteProgram(program);
+ gl.deleteShader(shader);
+ }));
+
+ // Enumerated state queries: Buffers
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_buffer_parameter', 'Invalid gl.getBufferParameter() usage', gl, function() {
+ /** @type{number} */ var params = -1;
+ /** @type{WebGLBuffer} */ var buf;
+ buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target or value is not an accepted value.');
+ params = /** @type{number} */ (gl.getBufferParameter(-1, gl.BUFFER_SIZE));
+ this.expectError(gl.INVALID_ENUM);
+ params = /** @type{number} */ (gl.getBufferParameter(gl.ARRAY_BUFFER, -1));
+ this.expectError(gl.INVALID_ENUM);
+ params = /** @type{number} */ (gl.getBufferParameter(-1, -1));
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the reserved buffer object name 0 is bound to target.');
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ params = /** @type{number} */ (gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE));
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteBuffer(buf);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_framebuffer_attachment_parameter', 'Invalid gl.getFramebufferAttachmentParameter() usage', gl, function() {
+ /** @type{*} */ var params;
+ /** @type{WebGLFramebuffer} */ var fbo;
+ /** @type{Array<WebGLRenderbuffer>} */ var rbo = [];
+
+ fbo = gl.createFramebuffer();
+ rbo[0] = gl.createRenderbuffer();
+ rbo[1] = gl.createRenderbuffer();
+
+ gl.bindFramebuffer (gl.FRAMEBUFFER, fbo);
+ gl.bindRenderbuffer (gl.RENDERBUFFER, rbo[0]);
+ gl.renderbufferStorage (gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 16, 16);
+ gl.framebufferRenderbuffer (gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rbo[0]);
+ gl.bindRenderbuffer (gl.RENDERBUFFER, rbo[1]);
+ gl.renderbufferStorage (gl.RENDERBUFFER, gl.STENCIL_INDEX8, 16, 16);
+ gl.framebufferRenderbuffer (gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, rbo[1]);
+ gl.checkFramebufferStatus (gl.FRAMEBUFFER);
+ this.expectError (gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not one of the accepted tokens.');
+ gl.getFramebufferAttachmentParameter(-1, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE); // TYPE is gl.RENDERBUFFER
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not valid for the value of gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE.');
+ gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL); // TYPE is gl.RENDERBUFFER
+ this.expectError(gl.INVALID_ENUM);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.BACK, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); // TYPE is gl.FRAMEBUFFER_DEFAULT
+ this.expectError(gl.INVALID_ENUM);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if attachment is gl.DEPTH_STENCIL_ATTACHMENT and different objects are bound to the depth and stencil attachment points of target.');
+ gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the value of gl.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is gl.NONE and pname is not gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME.');
+ gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); // TYPE is gl.NONE
+ this.expectError(gl.NO_ERROR);
+ gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE); // TYPE is gl.NONE
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION or gl.INVALID_ENUM is generated if attachment is not one of the accepted values for the current binding of target.');
+ gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.BACK, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); // A FBO is bound so gl.BACK is invalid
+ this.expectError([gl.INVALID_OPERATION, gl.INVALID_ENUM]);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME); // Default framebuffer is bound so gl.COLOR_ATTACHMENT0 is invalid
+ this.expectError([gl.INVALID_OPERATION, gl.INVALID_ENUM]);
+
+ gl.deleteFramebuffer(fbo);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_renderbuffer_parameter', 'Invalid gl.getRenderbufferParameter() usage', gl, function() {
+ /** @type{number} */ var params = -1;
+ /** @type{WebGLRenderbuffer} */ var rbo;
+ rbo = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.RENDERBUFFER.');
+ gl.getRenderbufferParameter(-1, gl.RENDERBUFFER_WIDTH);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not one of the accepted tokens.');
+ gl.getRenderbufferParameter(gl.RENDERBUFFER, -1);
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.deleteRenderbuffer(rbo);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_internalformat_parameter', 'Invalid gl.getInternalformatParameter() usage', gl, function() {
+ /** @type{WebGLRenderbuffer} */ var rbo = gl.createRenderbuffer();
+ /** @type{WebGLFramebuffer} */ var fbo = gl.createFramebuffer();
+ /** @type{WebGLTexture} */ var tex = gl.createTexture();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not gl.SAMPLES or gl.NUM_SAMPLE_COUNTS.');
+ gl.getInternalformatParameter (gl.RENDERBUFFER, gl.RGBA8, -1);
+ this.expectError (gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if internalformat is not color-, depth-, or stencil-renderable.');
+ gl.getInternalformatParameter (gl.RENDERBUFFER, gl.RG8_SNORM, gl.NUM_SAMPLE_COUNTS);
+ this.expectError (gl.INVALID_ENUM);
+ gl.getInternalformatParameter (gl.RENDERBUFFER, gl.COMPRESSED_RGB8_ETC2, gl.NUM_SAMPLE_COUNTS);
+ this.expectError (gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.RENDERBUFFER.');
+ gl.getInternalformatParameter (-1, gl.RGBA8, gl.NUM_SAMPLE_COUNTS);
+ this.expectError (gl.INVALID_ENUM);
+ gl.getInternalformatParameter (gl.FRAMEBUFFER, gl.RGBA8, gl.NUM_SAMPLE_COUNTS);
+ this.expectError (gl.INVALID_ENUM);
+ gl.getInternalformatParameter (gl.TEXTURE_2D, gl.RGBA8, gl.NUM_SAMPLE_COUNTS);
+ this.expectError (gl.INVALID_ENUM);
+
+ gl.deleteRenderbuffer(rbo);
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(tex);
+
+ }));
+
+ // Query object queries
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_query', 'Invalid gl.getQuery() usage', gl, function() {
+ /** @type{number} */ var params = -1;
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target or pname is not an accepted value.');
+ gl.getQuery (gl.ANY_SAMPLES_PASSED, -1);
+ this.expectError (gl.INVALID_ENUM);
+ gl.getQuery (-1, gl.CURRENT_QUERY);
+ this.expectError (gl.INVALID_ENUM);
+ gl.getQuery (-1, -1);
+ this.expectError (gl.INVALID_ENUM);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_query_parameter', 'Invalid gl.getQueryParameter() usage', gl, function() {
+
+ /** @type{WebGLQuery} */ var id;
+ id = gl.createQuery();
+
+ bufferedLogToConsole('An exception is thrown if the query object is null.');
+ this.expectThrowNoError(function() {
+ gl.getQueryParameter (null, gl.QUERY_RESULT_AVAILABLE);
+ });
+
+ bufferedLogToConsole('// Note: ' + id + ' is not a query object yet, since it hasn\'t been used by gl.beginQuery');
+ gl.getQueryParameter (id, gl.QUERY_RESULT_AVAILABLE);
+ this.expectError (gl.INVALID_OPERATION);
+
+ gl.beginQuery (gl.ANY_SAMPLES_PASSED, id);
+ gl.endQuery (gl.ANY_SAMPLES_PASSED);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted value.');
+ gl.getQueryParameter (id, -1);
+ this.expectError (gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if id is the name of a currently active query object.');
+ gl.beginQuery (gl.ANY_SAMPLES_PASSED, id);
+ this.expectError (gl.NO_ERROR);
+ gl.getQueryParameter (id, gl.QUERY_RESULT_AVAILABLE);
+ this.expectError (gl.INVALID_OPERATION);
+ gl.endQuery (gl.ANY_SAMPLES_PASSED);
+ this.expectError (gl.NO_ERROR);
+
+ gl.deleteQuery(id);
+ }));
+
+ // Sync object queries
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('get_sync_parameter', 'Invalid gl.getSyncParameter() usage', gl, function() {
+ /** @type{WebGLSync} */ var sync;
+
+ bufferedLogToConsole('An exception is thrown if sync is null.');
+ this.expectThrowNoError(function() {
+ gl.getSyncParameter (null, gl.OBJECT_TYPE);
+ });
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not one of the accepted tokens.');
+ sync = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
+ this.expectError (gl.NO_ERROR);
+ gl.getSyncParameter (sync, -1);
+ this.expectError (gl.INVALID_ENUM);
+
+ }));
+
+ // Enumerated boolean state queries
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_enabled', 'Invalid gl.isEnabled() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if cap is not an accepted value.');
+ gl.isEnabled(-1);
+ this.expectError(gl.INVALID_ENUM);
+ gl.isEnabled(gl.TRIANGLES);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ // Named Object Usage
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_buffer', 'Invalid gl.isBuffer() usage', gl, function() {
+ /** @type{WebGLBuffer} */ var buffer;
+ /** @type{boolean} */ var isBuffer;
+
+ bufferedLogToConsole('A name returned by glGenBuffers, but not yet associated with a buffer object by calling glBindBuffer, is not the name of a buffer object.');
+ isBuffer = gl.isBuffer(buffer);
+ assertMsgOptions(!isBuffer, 'Got invalid boolean value', false, true);
+
+ buffer = gl.createBuffer();
+ isBuffer = gl.isBuffer(buffer);
+ assertMsgOptions(!isBuffer, 'Got invalid boolean value', false, true);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ isBuffer = gl.isBuffer(buffer);
+ assertMsgOptions(isBuffer, 'Got invalid boolean value', false, true);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.deleteBuffer(buffer);
+ isBuffer = gl.isBuffer(buffer);
+ assertMsgOptions(!isBuffer, 'Got invalid boolean value', false, true);
+
+ this.expectError (gl.NO_ERROR);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_framebuffer', 'Invalid gl.isFramebuffer() usage', gl, function() {
+ /** @type{WebGLFramebuffer} */ var fbo;
+ /** @type{boolean} */ var isFbo;
+
+ bufferedLogToConsole('A name returned by glGenFramebuffers, but not yet bound through a call to gl.bindFramebuffer is not the name of a framebuffer object.');
+ isFbo = gl.isFramebuffer(fbo);
+ assertMsgOptions(!isFbo, 'Got invalid boolean value', false, true);
+
+ fbo = gl.createFramebuffer();
+ isFbo = gl.isFramebuffer(fbo);
+ assertMsgOptions(!isFbo, 'Got invalid boolean value', false, true);
+
+ gl.bindFramebuffer (gl.FRAMEBUFFER, fbo);
+ isFbo = gl.isFramebuffer(fbo);
+ assertMsgOptions(isFbo, 'Got invalid boolean value', false, true);
+
+ gl.bindFramebuffer (gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+ isFbo = gl.isFramebuffer(fbo);
+ assertMsgOptions(!isFbo, 'Got invalid boolean value', false, true);
+
+ this.expectError (gl.NO_ERROR);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_program', 'Invalid gl.isProgram() usage', gl, function() {
+ /** @type{WebGLProgram} */ var program;
+ /** @type{boolean} */ var isProgram;
+
+ bufferedLogToConsole('A name created with gl.createProgram, and not yet deleted with glDeleteProgram is a name of a program object.');
+ isProgram = gl.isProgram(program);
+ assertMsgOptions(!isProgram, 'Got invalid boolean value', false, true);
+
+ program = gl.createProgram();
+ isProgram = gl.isProgram(program);
+ assertMsgOptions(isProgram, 'Got invalid boolean value', false, true);
+
+ gl.deleteProgram(program);
+ isProgram = gl.isProgram(program);
+ assertMsgOptions(!isProgram, 'Got invalid boolean value', false, true);
+
+ this.expectError (gl.NO_ERROR);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_renderbuffer', 'Invalid gl.isRenderbuffer() usage', gl, function() {
+ /** @type{WebGLRenderbuffer} */ var rbo;
+ /** @type{boolean} */ var isRbo;
+
+ bufferedLogToConsole('A name returned by glGenRenderbuffers, but not yet bound through a call to gl.bindRenderbuffer or gl.framebufferRenderbuffer is not the name of a renderbuffer object.');
+ isRbo = gl.isRenderbuffer(rbo);
+ assertMsgOptions(!isRbo, 'Got invalid boolean value', false, true);
+
+ rbo = gl.createRenderbuffer();
+ isRbo = gl.isRenderbuffer(rbo);
+ assertMsgOptions(!isRbo, 'Got invalid boolean value', false, true);
+
+ gl.bindRenderbuffer (gl.RENDERBUFFER, rbo);
+ isRbo = gl.isRenderbuffer(rbo);
+ assertMsgOptions(isRbo, 'Got invalid boolean value', false, true);
+
+ gl.bindRenderbuffer (gl.RENDERBUFFER, null);
+ gl.deleteRenderbuffer(rbo);
+ isRbo = gl.isRenderbuffer(rbo);
+ assertMsgOptions(!isRbo, 'Got invalid boolean value', false, true);
+
+ this.expectError (gl.NO_ERROR);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_shader', 'Invalid gl.isShader() usage', gl, function() {
+ /** @type{WebGLShader} */ var shader;
+ /** @type{boolean} */ var isShader;
+
+ bufferedLogToConsole('A name created with glCreateShader, and not yet deleted with glDeleteShader is a name of a shader object.');
+ isShader = gl.isProgram(shader);
+ assertMsgOptions(!isShader, 'Got invalid boolean value', false, true);
+
+ shader = gl.createShader(gl.VERTEX_SHADER);
+ isShader = gl.isShader(shader);
+ assertMsgOptions(isShader, 'Got invalid boolean value', false, true);
+
+ gl.deleteShader (shader);
+ isShader = gl.isShader(shader);
+ assertMsgOptions(!isShader, 'Got invalid boolean value', false, true);
+
+ this.expectError (gl.NO_ERROR);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_texture', 'Invalid gl.isTexture() usage', gl, function() {
+ /** @type{WebGLTexture} */ var texture;
+ /** @type{boolean} */ var isTexture;
+
+ bufferedLogToConsole('A name returned by glGenTextures, but not yet bound through a call to glBindTexture is not the name of a texture.');
+ isTexture = gl.isTexture(texture);
+ assertMsgOptions(!isTexture, 'Got invalid boolean value', false, true);
+
+ texture = gl.createTexture();
+ isTexture = gl.isTexture(texture);
+ assertMsgOptions(!isTexture, 'Got invalid boolean value', false, true);
+
+ gl.bindTexture (gl.TEXTURE_2D, texture);
+ isTexture = gl.isTexture(texture);
+ assertMsgOptions(isTexture, 'Got invalid boolean value', false, true);
+
+ gl.bindTexture (gl.TEXTURE_2D, null);
+ gl.deleteTexture(texture);
+ isTexture = gl.isTexture(texture);
+ assertMsgOptions(!isTexture, 'Got invalid boolean value', false, true);
+
+ this.expectError (gl.NO_ERROR);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_query', 'Invalid gl.isQuery() usage', gl, function() {
+ /** @type{WebGLQuery} */ var query;
+ /** @type{boolean} */ var isQuery;
+
+ bufferedLogToConsole('A name returned by glGenQueries, but not yet associated with a query object by calling gl.beginQuery, is not the name of a query object.');
+ isQuery = gl.isQuery(query);
+ assertMsgOptions(!isQuery, 'Got invalid boolean value', false, true);
+
+ query = gl.createQuery();
+ isQuery = gl.isQuery(query);
+ assertMsgOptions(!isQuery, 'Got invalid boolean value', false, true);
+
+ gl.beginQuery (gl.ANY_SAMPLES_PASSED, query);
+ isQuery = gl.isQuery(query);
+ assertMsgOptions(isQuery, 'Got invalid boolean value', false, true);
+
+ gl.endQuery (gl.ANY_SAMPLES_PASSED);
+ gl.deleteQuery (query);
+ isQuery = gl.isQuery(query);
+ assertMsgOptions(!isQuery, 'Got invalid boolean value', false, true);
+
+ this.expectError (gl.NO_ERROR);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_sampler', 'Invalid gl.isSampler() usage', gl, function() {
+ /** @type{WebGLSampler} */ var sampler;
+ /** @type{boolean} */ var isSampler;
+
+ bufferedLogToConsole('A name returned by glGenSamplers is the name of a sampler object.');
+ isSampler = gl.isSampler(sampler);
+ assertMsgOptions(!isSampler, 'Got invalid boolean value', false, true);
+
+ sampler = gl.createSampler();
+ isSampler = gl.isSampler(sampler);
+ assertMsgOptions(isSampler, 'Got invalid boolean value', false, true);
+
+ gl.bindSampler(0, sampler);
+ isSampler = gl.isSampler(sampler);
+ assertMsgOptions(isSampler, 'Got invalid boolean value', false, true);
+
+ gl.deleteSampler(sampler);
+ isSampler = gl.isSampler(sampler);
+ assertMsgOptions(!isSampler, 'Got invalid boolean value', false, true);
+
+ this.expectError (gl.NO_ERROR);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_sync', 'Invalid gl.isSync() usage', gl, function() {
+ /** @type{WebGLSync} */ var sync;
+ /** @type{boolean} */ var isSync;
+
+ bufferedLogToConsole('A name returned by gl.fenceSync is the name of a sync object.');
+ isSync = gl.isSync(sync);
+ assertMsgOptions(!isSync, 'Got invalid boolean value', false, true);
+
+ sync = gl.fenceSync (gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
+ isSync = gl.isSync(sync);
+ assertMsgOptions(isSync, 'Got invalid boolean value', false, true);
+
+ gl.deleteSync (sync);
+ isSync = gl.isSync(sync);
+ assertMsgOptions(!isSync, 'Got invalid boolean value', false, true);
+
+ this.expectError (gl.NO_ERROR);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_transform_feedback', 'Invalid gl.isTransformFeedback() usage', gl, function() {
+ /** @type{WebGLTransformFeedback} */ var tf;
+ /** @type{boolean} */ var isTF;
+
+ bufferedLogToConsole('A name returned by glGenTransformFeedbacks, but not yet bound using glBindTransformFeedback, is not the name of a transform feedback object.');
+ isTF = gl.isTransformFeedback(tf);
+ assertMsgOptions(!isTF, 'Got invalid boolean value', false, true);
+
+ tf = gl.createTransformFeedback();
+ isTF = gl.isTransformFeedback(tf);
+ assertMsgOptions(!isTF, 'Got invalid boolean value', false, true);
+
+ gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, tf);
+ isTF = gl.isTransformFeedback(tf);
+ assertMsgOptions(isTF, 'Got invalid boolean value', false, true);
+
+ gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, null);
+ gl.deleteTransformFeedback (tf);
+ isTF = gl.isTransformFeedback(tf);
+ assertMsgOptions(!isTF, 'Got invalid boolean value', false, true);
+
+ this.expectError (gl.NO_ERROR);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('is_vertex_array', 'Invalid gl.isVertexArray() usage', gl, function() {
+ /** @type{WebGLVertexArrayObject} */ var vao;
+ /** @type{boolean} */ var isVao;
+
+ bufferedLogToConsole('A name returned by glGenVertexArrays, but not yet bound using glBindVertexArray, is not the name of a vertex array object.');
+ isVao = gl.isVertexArray(vao);
+ assertMsgOptions(!isVao, 'Got invalid boolean value', false, true);
+
+ vao = gl.createVertexArray();
+ isVao = gl.isVertexArray(vao);
+ assertMsgOptions(!isVao, 'Got invalid boolean value', false, true);
+
+ gl.bindVertexArray (vao);
+ isVao = gl.isVertexArray(vao);
+ assertMsgOptions(isVao, 'Got invalid boolean value', false, true);
+
+ gl.bindVertexArray (null);
+ gl.deleteVertexArray (vao);
+ isVao = gl.isVertexArray(vao);
+ assertMsgOptions(!isVao, 'Got invalid boolean value', false, true);
+
+ this.expectError (gl.NO_ERROR);
+ }));
+ };
+
+ /**
+ * @param {WebGL2RenderingContext} gl
+ */
+ es3fNegativeStateApiTests.run = function(gl) {
+ var testName = 'state';
+ var testDescription = 'Negative GL State API Cases';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.testCases = tcuTestCase.newTest(testName, testDescription, null);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+ try {
+ es3fNegativeStateApiTests.init(gl);
+ tcuTestCase.runner.runCallback(tcuTestCase.runTestCases);
+ } catch (err) {
+ bufferedLogToConsole(err);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeTextureApiTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeTextureApiTests.js
new file mode 100644
index 0000000000..8bccf1bb37
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeTextureApiTests.js
@@ -0,0 +1,3002 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.0 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Negative Texture API tests.
+ *//*--------------------------------------------------------------------*/
+'use strict';
+goog.provide('functional.gles3.es3fNegativeTextureApiTests');
+
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('functional.gles3.es3fApiCase');
+goog.require('framework.opengl.gluTexture');
+goog.require('framework.opengl.gluTextureUtil');
+
+goog.scope(function() {
+
+ var es3fNegativeTextureApiTests = functional.gles3.es3fNegativeTextureApiTests;
+ var tcuTexture = framework.common.tcuTexture;
+ var es3fApiCase = functional.gles3.es3fApiCase;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var gluTexture = framework.opengl.gluTexture;
+ var gluTextureUtil = framework.opengl.gluTextureUtil;
+
+ function etc2Unsupported() {
+ debug("Skipping test: no support for WEBGL_compressed_texture_etc");
+ }
+
+
+ /**
+ * @param {number} width
+ * @param {number} height
+ * @return {number}
+ */
+ es3fNegativeTextureApiTests.etc2DataSize = function(width, height) {
+ return Math.ceil(width / 4) * Math.ceil(height / 4) * 8;
+ };
+
+ /**
+ * @param {number} width
+ * @param {number} height
+ * @return {number}
+ */
+ es3fNegativeTextureApiTests.etc2EacDataSize = function(width, height) {
+ return 2 * es3fNegativeTextureApiTests.etc2DataSize(width, height);
+ };
+
+ /**
+ * @param {function(number)} func
+ */
+ es3fNegativeTextureApiTests.forCubeFaces = function(func) {
+ var faceGLVar;
+ for (var faceIterTcu in tcuTexture.CubeFace) {
+ faceGLVar = gluTexture.cubeFaceToGLFace(tcuTexture.CubeFace[faceIterTcu]);
+ func(faceGLVar);
+ }
+ };
+
+ /**
+ * @param {WebGL2RenderingContext} gl
+ */
+ es3fNegativeTextureApiTests.init = function(gl) {
+
+ var haveCompressedTextureETC = gluTextureUtil.enableCompressedTextureETC();
+
+ var testGroup = tcuTestCase.runner.testCases;
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('activetexture', 'Invalid gl.ActiveTexture() usage', gl,
+ function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if texture is not one of gl.TEXTUREi, where i ranges from 0 to (gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1).');
+ gl.activeTexture(-1);
+ this.expectError(gl.INVALID_ENUM);
+ var numMaxTextureUnits = /** @type {number} */(gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS));
+ gl.activeTexture(gl.TEXTURE0 + numMaxTextureUnits);
+ this.expectError(gl.INVALID_ENUM);
+
+ }));
+
+ // gl.bindTexture
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('bindTexture', 'Invalid gl.bindTexture() usage', gl,
+ function() {
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not one of the allowable values.');
+ gl.bindTexture(0, texture[0]);
+ this.expectError(gl.INVALID_ENUM);
+ gl.bindTexture(gl.FRAMEBUFFER, texture[0]);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if texture was previously created with a target that doesn\'t match that of target.');
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ this.expectError(gl.NO_ERROR);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[0]);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.bindTexture(gl.TEXTURE_3D, texture[0]);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, texture[0]);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+ this.expectError(gl.NO_ERROR);
+ gl.bindTexture(gl.TEXTURE_2D, texture[1]);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.bindTexture(gl.TEXTURE_3D, texture[1]);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, texture[1]);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ // gl.compressedTexImage2D
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedteximage2d_invalid_target', 'Invalid gl.compressedTexImage2D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is invalid.');
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(0);
+ gl.compressedTexImage2D(0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_ENUM);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_ENUM);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedteximage2d_invalid_format', 'Invalid gl.compressedTexImage2D() usage', gl,
+ function() {
+
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if internalformat is not a supported format returned in gl.COMPRESSED_TEXTURE_FORMATS.');
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(0);
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_ENUM);
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_ENUM);
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_ENUM);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_ENUM);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_ENUM);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_ENUM);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_ENUM);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_ENUM);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_ENUM);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedteximage2d_neg_level', 'Invalid gl.compressedTexImage2D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is less than 0.');
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(0);
+ gl.compressedTexImage2D(gl.TEXTURE_2D, -1, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, -1, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, -1, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, -1, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, -1, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, -1, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, -1, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedteximage2d_max_level', 'Invalid gl.compressedTexImage2D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_TEXTURE_SIZE) for a 2d texture target.');
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(16, 16));
+
+ /** @type {number} */ var log2MaxTextureSize = Math.floor(Math.log2(/** @type {number} */(gl.getParameter(gl.MAX_TEXTURE_SIZE)))) + 1;
+ gl.compressedTexImage2D(gl.TEXTURE_2D, log2MaxTextureSize, gl.COMPRESSED_RGB8_ETC2, 16, 16, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_CUBE_MAP_TEXTURE_SIZE) for a cubemap target.');
+ /** @type {number} */ var log2MaxCubemapSize = Math.floor(Math.log2(/** @type {number} */(gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE)))) + 1;
+
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, log2MaxCubemapSize, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, log2MaxCubemapSize, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, log2MaxCubemapSize, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, log2MaxCubemapSize, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, log2MaxCubemapSize, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, log2MaxCubemapSize, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedteximage2d_neg_width_height', 'Invalid gl.compressedTexImage2D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width or height is less than 0.');
+
+ bufferedLogToConsole('gl.TEXTURE_2D target');
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(0);
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, 0, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, -1, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, -1, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_X target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, 0, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, -1, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, -1, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_Y target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, 0, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, -1, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, -1, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_Z target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, 0, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, -1, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, -1, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_X target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, 0, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, -1, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, -1, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Y target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, 0, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, -1, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, -1, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Z target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, 0, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, -1, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, -1, 0, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedteximage2d_max_width_height', 'Invalid gl.compressedTexImage2D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+ var maxTextureSize = /** @type {number} */ (gl.getParameter(gl.MAX_TEXTURE_SIZE)) + 1;
+ var maxCubemapSize = /** @type {number} */ (gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE)) + 1;
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width or height is greater than gl.MAX_TEXTURE_SIZE.');
+
+ var maxSideSize = Math.max(maxCubemapSize, maxTextureSize);
+ var scratchBuffer = new ArrayBuffer(
+ Math.max(es3fNegativeTextureApiTests.etc2EacDataSize(maxSideSize, 1),
+ es3fNegativeTextureApiTests.etc2EacDataSize(1, maxSideSize)));
+ function getUint8ArrayEtc2EacDataSize(w, h) {
+ return new Uint8Array(scratchBuffer, 0, es3fNegativeTextureApiTests.etc2EacDataSize(w, h));
+ }
+
+ var dataTextureMaxByOne = getUint8ArrayEtc2EacDataSize(maxTextureSize, 1);
+ var dataTextureOneByMax = getUint8ArrayEtc2EacDataSize(1, maxTextureSize);
+
+ bufferedLogToConsole('gl.TEXTURE_2D target');
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, maxTextureSize, 1, 0, dataTextureMaxByOne);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 1, maxTextureSize, 0, dataTextureOneByMax);
+ this.expectError(gl.INVALID_VALUE);
+
+ var dataCubemapMaxByOne = getUint8ArrayEtc2EacDataSize(maxCubemapSize, 1);
+ var dataCubemapOneByMax = getUint8ArrayEtc2EacDataSize(1, maxCubemapSize);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_X target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, maxCubemapSize, 1, 0, dataCubemapMaxByOne);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 1, maxCubemapSize, 0, dataCubemapOneByMax);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_Y target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, maxCubemapSize, 1, 0, dataCubemapMaxByOne);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 1, maxCubemapSize, 0, dataCubemapOneByMax);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_Z target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, maxCubemapSize, 1, 0, dataCubemapMaxByOne);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 1, maxCubemapSize, 0, dataCubemapOneByMax);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_X target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, maxCubemapSize, 1, 0, dataCubemapMaxByOne);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 1, maxCubemapSize, 0, dataCubemapOneByMax);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Y target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, maxCubemapSize, 1, 0, dataCubemapMaxByOne);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 1, maxCubemapSize, 0, dataCubemapOneByMax);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Z target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, maxCubemapSize, 1, 0, dataCubemapMaxByOne);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 1, maxCubemapSize, 0, dataCubemapOneByMax);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedteximage2d_invalid_border', 'Invalid gl.compressedTexImage2D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(0);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if border is not 0.');
+
+ bufferedLogToConsole('gl.TEXTURE_2D target');
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 1, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, -1, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_X target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 1, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, -1, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_Y target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 1, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, -1, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_Z target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 1, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, -1, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_X target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 1, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, -1, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Y target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 1, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, -1, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Z target');
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 1, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, -1, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedteximage2d_invalid_size', 'Invalid gl.compressedTexImage2D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+
+ /** @type {WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if imageSize is not consistent with the format, dimensions, and contents of the specified compressed image data.');
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, new Uint8Array(1));
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 0, new Uint8Array(4 * 4 * 8));
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.COMPRESSED_RGB8_ETC2, 16, 16, 0, new Uint8Array(4 * 4 * 16));
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.COMPRESSED_SIGNED_R11_EAC, 16, 16, 0, new Uint8Array(4 * 4 * 16));
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture);
+
+
+ }));
+
+ // gl.copyTexImage2D
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copyteximage2d_invalid_target', 'Invalid gl.copyTexImage2D() usage', gl,
+ function() {
+
+
+ /** @type {WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is invalid.');
+ gl.copyTexImage2D(0, 0, gl.RGB, 0, 0, 64, 64, 0);
+ this.expectError(gl.INVALID_ENUM);
+
+
+ gl.deleteTexture(texture);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copyteximage2d_invalid_format', 'Invalid gl.copyTexImage2D() usage', gl,
+ function() {
+
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ bufferedLogToConsole('gl.INVALID_ENUM or gl.INVALID_VALUE is generated if internalformat is not an accepted format.');
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 64, 64, 0);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_VALUE]);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 0, 16, 16, 0);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_VALUE]);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, 0, 16, 16, 0);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_VALUE]);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, 0, 16, 16, 0);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_VALUE]);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, 0, 16, 16, 0);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_VALUE]);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, 0, 16, 16, 0);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_VALUE]);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, 0, 16, 16, 0);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_VALUE]);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copyteximage2d_inequal_width_height_cube', 'Invalid gl.copyTexImage2D() usage', gl,
+ function() {
+
+
+ /** @type {WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
+
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if target is one of the six cube map 2D image targets and the width and height parameters are not equal.');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, 0, 0, 16, 17, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, 0, 0, 16, 17, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, 0, 0, 16, 17, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, 0, 0, 16, 17, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, 0, 0, 16, 17, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, 0, 0, 16, 17, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copyteximage2d_neg_level', 'Invalid gl.copyTexImage2D() usage', gl,
+ function() {
+
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is less than 0.');
+ gl.copyTexImage2D(gl.TEXTURE_2D, -1, gl.RGB, 0, 0, 64, 64, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, -1, gl.RGB, 0, 0, 16, 16, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, -1, gl.RGB, 0, 0, 16, 16, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, -1, gl.RGB, 0, 0, 16, 16, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, -1, gl.RGB, 0, 0, 16, 16, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, -1, gl.RGB, 0, 0, 16, 16, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, -1, gl.RGB, 0, 0, 16, 16, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copyteximage2d_max_level', 'Invalid gl.copyTexImage2D() usage', gl,
+ function() {
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_TEXTURE_SIZE).');
+ /** @type {number} */ var log2MaxTextureSize = Math.floor(Math.log2(/** @type {number} */(gl.getParameter(gl.MAX_TEXTURE_SIZE)))) + 1;
+ gl.copyTexImage2D(gl.TEXTURE_2D, log2MaxTextureSize, gl.RGB, 0, 0, 64, 64, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_CUBE_MAP_TEXTURE_SIZE).');
+ /** @type {number} */ var log2MaxCubemapSize = Math.floor(Math.log2(/** @type {number} */(gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE)))) + 1;
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, log2MaxCubemapSize, gl.RGB, 0, 0, 16, 16, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, log2MaxCubemapSize, gl.RGB, 0, 0, 16, 16, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, log2MaxCubemapSize, gl.RGB, 0, 0, 16, 16, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, log2MaxCubemapSize, gl.RGB, 0, 0, 16, 16, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, log2MaxCubemapSize, gl.RGB, 0, 0, 16, 16, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, log2MaxCubemapSize, gl.RGB, 0, 0, 16, 16, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copyteximage2d_neg_width_height', 'Invalid gl.copyTexImage2D() usage', gl,
+ function() {
+
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width or height is less than 0.');
+
+ bufferedLogToConsole('gl.TEXTURE_2D target');
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGB, 0, 0, -1, 1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGB, 0, 0, 1, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGB, 0, 0, -1, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_X target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, 0, 0, -1, 1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, 0, 0, 1, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, 0, 0, -1, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_Y target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, 0, 0, -1, 1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, 0, 0, 1, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, 0, 0, -1, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_Z target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, 0, 0, -1, 1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, 0, 0, 1, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, 0, 0, -1, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_X target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, 0, 0, -1, 1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, 0, 0, 1, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, 0, 0, -1, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Y target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, 0, 0, -1, 1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, 0, 0, 1, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, 0, 0, -1, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Z target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, 0, 0, -1, 1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, 0, 0, 1, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, 0, 0, -1, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copyteximage2d_max_width_height', 'Invalid gl.copyTexImage2D() usage', gl,
+ function() {
+
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ var maxTextureSize = /** @type {number} */(gl.getParameter(gl.MAX_TEXTURE_SIZE)) + 1;
+ var maxCubemapSize = /** @type {number} */(gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE)) + 1;
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width or height is greater than gl.MAX_TEXTURE_SIZE.');
+
+ bufferedLogToConsole('gl.TEXTURE_2D target');
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGB, 0, 0, maxTextureSize, 1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGB, 0, 0, 1, maxTextureSize, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGB, 0, 0, maxTextureSize, maxTextureSize, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_X target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, 0, 0, 1, maxCubemapSize, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, 0, 0, maxCubemapSize, 1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, 0, 0, maxCubemapSize, maxCubemapSize, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_Y target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, 0, 0, 1, maxCubemapSize, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, 0, 0, maxCubemapSize, 1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, 0, 0, maxCubemapSize, maxCubemapSize, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_Z target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, 0, 0, 1, maxCubemapSize, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, 0, 0, maxCubemapSize, 1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, 0, 0, maxCubemapSize, maxCubemapSize, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_X target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, 0, 0, 1, maxCubemapSize, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, 0, 0, maxCubemapSize, 1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, 0, 0, maxCubemapSize, maxCubemapSize, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Y target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, 0, 0, 1, maxCubemapSize, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, 0, 0, maxCubemapSize, 1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, 0, 0, maxCubemapSize, maxCubemapSize, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Z target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, 0, 0, 1, maxCubemapSize, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, 0, 0, maxCubemapSize, 1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, 0, 0, maxCubemapSize, maxCubemapSize, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copyteximage2d_invalid_border', 'Invalid gl.copyTexImage2D() usage', gl,
+ function() {
+
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if border is not 0.');
+
+ bufferedLogToConsole('gl.TEXTURE_2D target');
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGB, 0, 0, 0, 0, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGB, 0, 0, 0, 0, 1);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_X target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, 0, 0, 0, 0, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, 0, 0, 0, 0, 1);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_Y target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, 0, 0, 0, 0, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, 0, 0, 0, 0, 1);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_2D target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, 0, 0, 0, 0, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, 0, 0, 0, 0, 1);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_X target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, 0, 0, 0, 0, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, 0, 0, 0, 0, 1);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Y target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, 0, 0, 0, 0, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, 0, 0, 0, 0, 1);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Z target');
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, 0, 0, 0, 0, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, 0, 0, 0, 0, 1);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copyteximage2d_incomplete_framebuffer', 'Invalid gl.copyTexImage2D() usage', gl,
+ function() {
+
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ /** @type {WebGLFramebuffer} */ var fbo;
+ fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
+ gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, 0, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA8, 0, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA8, 0, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA8, 0, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA8, 0, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA8, 0, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.copyTexImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA8, 0, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+ }));
+
+ // gl.copyTexSubImage2D
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copytexsubimage2d_invalid_target', 'Invalid gl.copyTexSubImage2D() usage', gl,
+ function() {
+
+ /** @type {WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is invalid.');
+ gl.copyTexSubImage2D(0, 0, 0, 0, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copytexsubimage2d_neg_level', 'Invalid gl.copyTexSubImage2D() usage', gl,
+ function() {
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+ es3fNegativeTextureApiTests.forCubeFaces(function(faceGL) {
+ gl.texImage2D(faceGL, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ });
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is less than 0.');
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, -1, 0, 0, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_VALUE);
+ var local = this;
+ es3fNegativeTextureApiTests.forCubeFaces(function(faceGL) {
+ gl.copyTexSubImage2D(faceGL, -1, 0, 0, 0, 0, 4, 4);
+ local.expectError(gl.INVALID_VALUE);
+ });
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copytexsubimage2d_max_level', 'Invalid gl.copyTexSubImage2D() usage', gl,
+ function() {
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.texImage2D (gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+ es3fNegativeTextureApiTests.forCubeFaces(function(faceGL) {
+ gl.texImage2D(faceGL, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ });
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_TEXTURE_SIZE) for 2D texture targets.');
+ /** @type{number} */ var log2MaxTextureSize = Math.floor(Math.log2(/** @type{number} */(gl.getParameter(gl.MAX_TEXTURE_SIZE)))) + 1;
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, log2MaxTextureSize, 0, 0, 0, 0, 4, 4);
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_CUBE_MAP_SIZE) for cubemap targets.');
+ /** @type{number} */ var log2MaxCubemapSize = Math.floor(Math.log2(/** @type{number} */(gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE)))) + 1;
+ var local = this;
+ es3fNegativeTextureApiTests.forCubeFaces(function(faceGL) {
+ gl.copyTexSubImage2D(faceGL, log2MaxCubemapSize, 0, 0, 0, 0, 4, 4);
+ local.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ });
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copytexsubimage2d_neg_offset', 'Invalid gl.copyTexSubImage2D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D (gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if xoffset < 0 or yoffset < 0.');
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, -1, 0, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, -1, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, -1, -1, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copytexsubimage2d_invalid_offset', 'Invalid gl.copyTexSubImage2D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D (gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if xoffset + width > texture_width or yoffset + height > texture_height.');
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 14, 0, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 14, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 14, 14, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copytexsubimage2d_neg_width_height', 'Invalid gl.copyTexSubImage2D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D (gl.TEXTURE_2D, 0, gl.RGBA, 16, 16, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width or height is less than 0.');
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 0, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, -1, -1);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copytexsubimage2d_incomplete_framebuffer', 'Invalid gl.copyTexSubImage2D() usage', gl,
+ function() {
+ bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ /** @type{WebGLFramebuffer} */ var fbo;
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.NO_ERROR);
+
+ fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ this.expectError(gl.NO_ERROR);
+
+ gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.copyTexSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.copyTexSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.copyTexSubImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.copyTexSubImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.copyTexSubImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.copyTexSubImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, 0, 0, 0, 0);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+ }));
+
+ // glDeleteTextures
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('deletetextures', 'glDeleteTextures() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+
+ bufferedLogToConsole('gl.NO_ERROR is generated if texture is null.');
+ gl.deleteTexture(null);
+ this.expectError(gl.NO_ERROR);
+
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.deleteTexture(null);
+ this.expectError(gl.NO_ERROR);
+
+ gl.deleteTexture(texture);
+ }));
+
+ // gl.generateMipmap
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('generatemipmap', 'Invalid gl.generateMipmap() usage', gl,
+ function() {
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ /** @type{WebGLFramebuffer} */ var fbo;
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not gl.TEXTURE_2D or gl.TEXTURE_CUBE_MAP.');
+ gl.generateMipmap(0);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('INVALID_OPERATION is generated if the texture bound to target is not cube complete.');
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[0]);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.REPEAT);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, 0, 0, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[0]);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, 16, 16, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, 32, 32, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
+ this.expectError(gl.INVALID_OPERATION);
+
+ if (haveCompressedTextureETC) {
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the zero level array is stored in a compressed internal format.');
+ gl.bindTexture(gl.TEXTURE_2D, texture[1]);
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, new Uint8Array(0));
+ gl.generateMipmap(gl.TEXTURE_2D);
+ this.expectError(gl.INVALID_OPERATION);
+ } else {
+ etc2Unsupported();
+ }
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the level base array was not specified with an unsized internal format or a sized internal format that is both color-renderable and texture-filterable.');
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB8_SNORM, 0, 0, 0, gl.RGB, gl.BYTE, null);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.R8I, 0, 0, 0, gl.RED_INTEGER, gl.BYTE, null);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, 0, 0, 0, gl.RGBA, gl.FLOAT, null);
+ gl.generateMipmap(gl.TEXTURE_2D);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ // gl.pixelStorei
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('pixelstorei', 'Invalid gl.pixelStorei() usage', gl,
+ function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if pname is not an accepted value.');
+ gl.pixelStorei(0,1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if a negative row length, pixel skip, or row skip value is specified, or if alignment is specified as other than 1, 2, 4, or 8.');
+ gl.pixelStorei(gl.PACK_ROW_LENGTH, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.pixelStorei(gl.PACK_SKIP_ROWS, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.pixelStorei(gl.PACK_SKIP_PIXELS, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.pixelStorei(gl.UNPACK_ROW_LENGTH, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.pixelStorei(gl.UNPACK_SKIP_ROWS, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.pixelStorei(gl.UNPACK_SKIP_IMAGES, -1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.pixelStorei(gl.PACK_ALIGNMENT, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.pixelStorei(gl.PACK_ALIGNMENT, 16);
+ this.expectError(gl.INVALID_VALUE);
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, 16);
+ this.expectError(gl.INVALID_VALUE);
+
+ }));
+
+ // gl.texImage2D
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('teximage2d', 'Invalid gl.texImage2D() usage', gl,
+ function() {
+
+
+ /** @type {WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is invalid.');
+ gl.texImage2D(0, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not a type constant.');
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, 0, null);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if format is not an accepted format constant.');
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, 0, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if internalFormat is not one of the accepted resolution and format symbolic constants.');
+ gl.texImage2D(gl.TEXTURE_2D, 0, 0, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the combination of internalFormat, format and type is invalid.');
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGB, gl.UNSIGNED_SHORT_4_4_4_4, null);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB5_A1, 1, 1, 0, gl.RGB, gl.UNSIGNED_SHORT_5_5_5_1, null);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB10_A2, 1, 1, 0, gl.RGB, gl.UNSIGNED_INT_2_10_10_10_REV, null);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32UI, 1, 1, 0, gl.RGBA_INTEGER, gl.INT, null);
+ this.expectError(gl.INVALID_OPERATION);
+
+
+ gl.deleteTexture(texture);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('teximage2d_inequal_width_height_cube', 'Invalid gl.texImage2D() usage', gl,
+ function() {
+
+ /** @type {WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if target is one of the six cube map 2D image targets and the width and height parameters are not equal.');
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, 1, 2, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, 1, 2, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, 1, 2, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, 1, 2, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, 1, 2, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, 1, 2, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('teximage2d_neg_level', 'Invalid gl.texImage2D() usage', gl,
+ function() {
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is less than 0.');
+ gl.texImage2D(gl.TEXTURE_2D, -1, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is less than 0.');
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, -1, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, -1, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, -1, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, -1, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, -1, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, -1, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('teximage2d_max_level', 'Invalid gl.texImage2D() usage', gl,
+ function() {
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_TEXTURE_SIZE).');
+ /** @type{number} */ var log2MaxTextureSize = Math.floor(Math.log2(/** @type{number} */(gl.getParameter(gl.MAX_TEXTURE_SIZE)))) + 1;
+ gl.texImage2D(gl.TEXTURE_2D, log2MaxTextureSize, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_CUBE_MAP_TEXTURE_SIZE).');
+ /** @type{number} */ var log2MaxCubemapSize = Math.floor(Math.log2(/** @type{number} */(gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE)))) + 1;
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, log2MaxCubemapSize, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, log2MaxCubemapSize, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, log2MaxCubemapSize, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, log2MaxCubemapSize, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, log2MaxCubemapSize, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, log2MaxCubemapSize, gl.RGB, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('teximage2d_neg_width_height', 'Invalid gl.texImage2D() usage', gl,
+ function() {
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width or height is less than 0.');
+
+ bufferedLogToConsole('gl.TEXTURE_2D target');
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, -1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, -1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, -1, -1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_X target');
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, -1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, 1, -1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, -1, -1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_Y target');
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, -1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, 1, -1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, -1, -1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_Z target');
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, -1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, 1, -1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, -1, -1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_X target');
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, -1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, 1, -1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, -1, -1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Y target');
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, -1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, 1, -1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, -1, -1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Z target');
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, -1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, 1, -1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, -1, -1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('teximage2d_max_width_height', 'Invalid gl.texImage2D() usage', gl,
+ function() {
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ var maxTextureSize = /** @type{number} */(gl.getParameter(gl.MAX_TEXTURE_SIZE)) + 1;
+ var maxCubemapSize = /** @type{number} */(gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE)) + 1;
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width or height is greater than gl.MAX_TEXTURE_SIZE.');
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, maxTextureSize, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, maxTextureSize, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, maxTextureSize, maxTextureSize, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width or height is greater than gl.MAX_CUBE_MAP_TEXTURE_SIZE.');
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_X target');
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, maxCubemapSize, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, 1, maxCubemapSize, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, maxCubemapSize, maxCubemapSize, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_Y target');
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, maxCubemapSize, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, 1, maxCubemapSize, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, maxCubemapSize, maxCubemapSize, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_POSITIVE_Z target');
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, maxCubemapSize, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, 1, maxCubemapSize, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, maxCubemapSize, maxCubemapSize, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_X target');
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, maxCubemapSize, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, 1, maxCubemapSize, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, maxCubemapSize, maxCubemapSize, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Y target');
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, maxCubemapSize, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, 1, maxCubemapSize, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, maxCubemapSize, maxCubemapSize, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.TEXTURE_CUBE_MAP_NEGATIVE_Z target');
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, maxCubemapSize, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, 1, maxCubemapSize, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, maxCubemapSize, maxCubemapSize, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('teximage2d_invalid_border', 'Invalid gl.texImage2D() usage', gl,
+ function() {
+
+ /** @type {Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if border is not 0.');
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 1, 1, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 1, -1, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGB, 1, 1, 1, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGB, 1, 1, 1, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGB, 1, 1, 1, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGB, 1, 1, 1, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGB, 1, 1, 1, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGB, 1, 1, 1, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+ }));
+
+ // gl.texSubImage2D
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texsubimage2d', 'Invalid gl.texSubImage2D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.NO_ERROR);
+
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(64);
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is invalid.');
+ gl.texSubImage2D(0, 0, 0, 0, 4, 4, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if format is not an accepted format constant.');
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 4, 4, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not a type constant.');
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 4, 4, gl.RGB, 0, uint8);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the combination of internalFormat of the previously specified texture array, format and type is not valid.');
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 4, 4, gl.RGBA, gl.UNSIGNED_SHORT_5_6_5, uint8);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 4, 4, gl.RGB, gl.UNSIGNED_SHORT_4_4_4_4, uint8);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 4, 4, gl.RGB, gl.UNSIGNED_SHORT_5_5_5_1, uint8);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 4, 4, gl.RGB, gl.UNSIGNED_SHORT_5_5_5_1, uint8);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 4, 4, gl.RGBA_INTEGER, gl.UNSIGNED_INT, uint8);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 4, 4, gl.RGB, gl.FLOAT, uint8);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texsubimage2d_neg_level', 'Invalid gl.texSubImage2D() usage', gl,
+ function() {
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 32, 32, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+ es3fNegativeTextureApiTests.forCubeFaces(function(faceGL) {
+ gl.texImage2D(faceGL, 0, gl.RGB, 32, 32, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ });
+ this.expectError(gl.NO_ERROR);
+
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(4);
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is less than 0.');
+ gl.texSubImage2D(gl.TEXTURE_2D, -1, 0, 0, 0, 0, gl.RGB, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is less than 0.');
+ var local = this;
+ es3fNegativeTextureApiTests.forCubeFaces(function(faceGL) {
+ gl.texSubImage2D(faceGL, -1, 0, 0, 0, 0, gl.RGB, gl.UNSIGNED_BYTE, uint8);
+ local.expectError(gl.INVALID_VALUE);
+ });
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texsubimage2d_max_level', 'Invalid gl.texSubImage2D() usage', gl,
+ function() {
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D, texture[0]);
+ gl.texImage2D (gl.TEXTURE_2D, 0, gl.RGB, 32, 32, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture (gl.TEXTURE_CUBE_MAP, texture[1]);
+ es3fNegativeTextureApiTests.forCubeFaces(function(faceGL) {
+ gl.texImage2D(faceGL, 0, gl.RGB, 32, 32, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ });
+
+ this.expectError (gl.NO_ERROR);
+
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(4);
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_TEXTURE_SIZE).');
+ /** @type{number} */ var log2MaxTextureSize = Math.floor(Math.log2(/** @type{number} */(gl.getParameter(gl.MAX_TEXTURE_SIZE)))) + 1;
+ gl.texSubImage2D(gl.TEXTURE_2D, log2MaxTextureSize, 0, 0, 0, 0, gl.RGB, gl.UNSIGNED_BYTE, uint8);
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_CUBE_MAP_TEXTURE_SIZE).');
+ /** @type{number} */ var log2MaxCubemapSize = Math.floor(Math.log2(/** @type{number} */(gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE)))) + 1;
+ var local = this;
+ es3fNegativeTextureApiTests.forCubeFaces(function(faceGL) {
+ gl.texSubImage2D(faceGL, log2MaxCubemapSize, 0, 0, 0, 0, gl.RGB, gl.UNSIGNED_BYTE, uint8);
+ local.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ });
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texsubimage2d_neg_offset', 'Invalid gl.texSubImage2D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 32, 32, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.NO_ERROR);
+
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(4);
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if xoffset or yoffset are negative.');
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, -1, 0, 0, 0, gl.RGB, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, -1, 0, 0, gl.RGB, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, -1, -1, 0, 0, gl.RGB, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texsubimage2d_invalid_offset', 'Invalid gl.texSubImage2D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.NO_ERROR);
+
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(64);
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if xoffset + width > texture_width or yoffset + height > texture_height.');
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 30, 0, 4, 4, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 30, 4, 4, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 30, 30, 4, 4, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texsubimage2d_neg_width_height', 'Invalid gl.texSubImage2D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.NO_ERROR);
+
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(4);
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width or height is less than 0.');
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, -1, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, -1, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, -1, -1, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ // gl.texParameteri
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texparameteri', 'Invalid gl.texParameteri() usage', gl,
+ function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target or pname is not one of the accepted defined values.');
+ gl.texParameteri(0, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_OPERATION]);
+ gl.texParameteri(gl.TEXTURE_2D, 0, gl.LINEAR);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_OPERATION]);
+ gl.texParameteri(0, 0, gl.LINEAR);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_OPERATION]);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if params should have a defined symbolic constant value (based on the value of pname) and does not.');
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, 0);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_OPERATION]);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.REPEAT);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_OPERATION]);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, 0);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_OPERATION]);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.NEAREST);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_OPERATION]);
+
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target or pname is not one of the accepted defined values.');
+ gl.texParameteri(0, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ this.expectError(gl.INVALID_ENUM);
+ gl.texParameteri(gl.TEXTURE_2D, 0, gl.LINEAR);
+ this.expectError(gl.INVALID_ENUM);
+ gl.texParameteri(0, 0, gl.LINEAR);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if params should have a defined symbolic constant value (based on the value of pname) and does not.');
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, 0);
+ this.expectError(gl.INVALID_ENUM);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.REPEAT);
+ this.expectError(gl.INVALID_ENUM);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, 0);
+ this.expectError(gl.INVALID_ENUM);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.NEAREST);
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.deleteTexture(texture);
+ }));
+
+ // gl.texParameterf
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texparameterf', 'Invalid gl.texParameterf() usage', gl,
+ function() {
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target or pname is not one of the accepted defined values.');
+ gl.texParameterf(0, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_OPERATION]);
+ gl.texParameterf(gl.TEXTURE_2D, 0, gl.LINEAR);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_OPERATION]);
+ gl.texParameterf(0, 0, gl.LINEAR);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_OPERATION]);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if params should have a defined symbolic constant value (based on the value of pname) and does not.');
+ gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, 0);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_OPERATION]);
+ gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.REPEAT);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_OPERATION]);
+ gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, 0);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_OPERATION]);
+ gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.NEAREST);
+ this.expectError([gl.INVALID_ENUM, gl.INVALID_OPERATION]);
+
+ /** @type{ WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target or pname is not one of the accepted defined values.');
+ gl.texParameterf(0, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ this.expectError(gl.INVALID_ENUM);
+ gl.texParameterf(gl.TEXTURE_2D, 0, gl.LINEAR);
+ this.expectError(gl.INVALID_ENUM);
+ gl.texParameterf(0, 0, gl.LINEAR);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if params should have a defined symbolic constant value (based on the value of pname) and does not.');
+ gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, 0);
+ this.expectError(gl.INVALID_ENUM);
+ gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.REPEAT);
+ this.expectError(gl.INVALID_ENUM);
+ gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, 0);
+ this.expectError(gl.INVALID_ENUM);
+ gl.texParameterf(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.NEAREST);
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.deleteTexture(texture);
+ }));
+
+ // gl.compressedTexSubImage2D
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedtexsubimage2d', 'Invalid gl.compressedTexSubImage2D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D, texture);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is invalid.');
+ gl.compressedTexSubImage2D(0, 0, 0, 0, 0, 0, gl.COMPRESSED_RGB8_ETC2, new Uint8Array(0));
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.compressedTexImage2D (gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 18, 18, 0, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(18, 18)));
+ this.expectError (gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if format does not match the internal format of the texture image being modified.');
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, gl.COMPRESSED_RGB8_ETC2, new Uint8Array(0));
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('For ETC2/EAC images gl.INVALID_OPERATION is generated if width is not a multiple of four, and width + xoffset is not equal to the width of the texture level.');
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 4, 0, 10, 4, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(10, 4)));
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('For ETC2/EAC images gl.INVALID_OPERATION is generated if height is not a multiple of four, and height + yoffset is not equal to the height of the texture level.');
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 4, 4, 10, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(4, 10)));
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('For ETC2/EAC images gl.INVALID_OPERATION is generated if xoffset or yoffset is not a multiple of four.');
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 1, 4, 4, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(4, 4)));
+ this.expectError(gl.INVALID_OPERATION);
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 1, 0, 4, 4, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(4, 4)));
+ this.expectError(gl.INVALID_OPERATION);
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 1, 1, 4, 4, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(4, 4)));
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedtexsubimage2d_neg_level', 'Invalid gl.compressedTexSubImage2D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.compressedTexImage2D (gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 18, 18, 0, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(18, 18)));
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+ es3fNegativeTextureApiTests.forCubeFaces(function(faceGL) {
+ gl.compressedTexImage2D(faceGL, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 18, 18, 0, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(18, 18)));
+ });
+
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is less than 0.');
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, -1, 0, 0, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is less than 0.');
+ var local = this;
+ es3fNegativeTextureApiTests.forCubeFaces(function(faceGL) {
+ gl.compressedTexSubImage2D(faceGL, -1, 0, 0, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ local.expectError(gl.INVALID_VALUE);
+ });
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedtexsubimage2d_max_level', 'Invalid gl.compressedTexSubImage2D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture[0]);
+ gl.compressedTexImage2D (gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 18, 18, 0, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(18, 18)));
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture[1]);
+ es3fNegativeTextureApiTests.forCubeFaces(function(faceGL) {
+ gl.compressedTexImage2D(faceGL, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 18, 18, 0, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(18, 18)));
+ });
+
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_TEXTURE_SIZE).');
+ /** @type{number} */ var log2MaxTextureSize = Math.floor(Math.log2(/** @type{number} */(gl.getParameter(gl.MAX_TEXTURE_SIZE)))) + 1;
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, log2MaxTextureSize, 0, 0, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_CUBE_MAP_TEXTURE_SIZE).');
+ /** @type{number} */ var log2MaxCubemapSize = Math.floor(Math.log2(/** @type{number} */(gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE)))) + 1;
+ var local = this;
+ es3fNegativeTextureApiTests.forCubeFaces(function(faceGL) {
+ gl.compressedTexSubImage2D(faceGL, log2MaxCubemapSize, 0, 0, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ local.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ });
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedtexsubimage2d_neg_offset', 'Invalid gl.compressedTexSubImage2D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{ WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 8, 8, 0, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(8, 8)));
+
+ // \note Both gl.INVALID_VALUE and gl.INVALID_OPERATION are valid here since implementation may
+ // first check if offsets are valid for certain format and only after that check that they
+ // are not negative.
+ bufferedLogToConsole('gl.INVALID_VALUE or gl.INVALID_OPERATION is generated if xoffset or yoffset are negative.');
+
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, -4, 0, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, -4, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, -4, -4, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedtexsubimage2d_invalid_offset', 'Invalid gl.compressedTexSubImage2D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D, texture);
+ gl.compressedTexImage2D (gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 0, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(16, 16)));
+ this.expectError (gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE or gl.INVALID_OPERATION is generated if xoffset + width > texture_width or yoffset + height > texture_height.');
+
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 12, 0, 8, 4, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(8, 4)));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 12, 4, 8, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(4, 8)));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 12, 12, 8, 8, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(8, 8)));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedtexsubimage2d_neg_width_height', 'Invalid gl.compressedTexSubImage2D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D, texture);
+ gl.compressedTexImage2D (gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 0, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(16, 16)));
+ this.expectError (gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE or gl.INVALID_OPERATION is generated if width or height is less than 0.');
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, -4, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, -4, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, -4, -4, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedtexsubimage2d_invalid_size', 'Invalid gl.compressedTexImage2D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D, texture);
+ gl.compressedTexImage2D (gl.TEXTURE_2D, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 0, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(16, 16)));
+ this.expectError (gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if imageSize is not consistent with the format, dimensions, and contents of the specified compressed image data.');
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(1));
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 16, 16, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(4*4*16-1));
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ // gl.texImage3D
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('teximage3d', 'Invalid gl.texImage3D() usage', gl,
+ function() {
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D, texture[0]);
+ gl.bindTexture (gl.TEXTURE_3D, texture[1]);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is invalid.');
+ gl.texImage3D(0, 0, gl.RGBA, 1, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_ENUM);
+ gl.texImage3D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not a type constant.');
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 1, 1, 1, 0, gl.RGBA, 0, null);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if format is not an accepted format constant.');
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 1, 1, 1, 0, 0, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if internalFormat is not one of the accepted resolution and format symbolic constants.');
+ gl.texImage3D(gl.TEXTURE_3D, 0, 0, 1, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if target is gl.TEXTURE_3D and format is gl.DEPTH_COMPONENT, or gl.DEPTH_STENCIL.');
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 1, 1, 1, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 1, 1, 1, 0, gl.DEPTH_COMPONENT, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the combination of internalFormat, format and type is invalid.');
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGB, 1, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 1, 1, 1, 0, gl.RGB, gl.UNSIGNED_SHORT_4_4_4_4, null);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGB5_A1, 1, 1, 1, 0, gl.RGB, gl.UNSIGNED_SHORT_5_5_5_1, null);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGB10_A2, 1, 1, 1, 0, gl.RGB, gl.UNSIGNED_INT_2_10_10_10_REV, null);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA32UI, 1, 1, 1, 0, gl.RGBA_INTEGER, gl.INT, null);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('teximage3d_neg_level', 'Invalid gl.texImage3D() usage', gl,
+ function() {
+ // NOTE: this method hangs the browser if the textures are binded.
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture[0]);
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture[1]);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is less than 0.');
+ gl.texImage3D(gl.TEXTURE_3D, -1, gl.RGB, 1, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, -1, gl.RGB, 1, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('teximage3d_max_level', 'Invalid gl.texImage3D() usage', gl,
+ function() {
+
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture[0]);
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture[1]);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_3D_TEXTURE_SIZE).');
+ /** @type{number} */ var log2Max3DTextureSize = Math.floor(Math.log2(/** @type{number} */ (gl.getParameter(gl.MAX_3D_TEXTURE_SIZE)))) + 1;
+ gl.texImage3D(gl.TEXTURE_3D, log2Max3DTextureSize, gl.RGB, 1, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_TEXTURE_SIZE).');
+ /** @type{number} */ var log2MaxTextureSize = Math.floor(Math.log2(/** @type{number} */ (gl.getParameter(gl.MAX_TEXTURE_SIZE)))) + 1;
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, log2MaxTextureSize, gl.RGB, 1, 1, 1, 0, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('teximage3d_neg_width_height_depth', 'Invalid gl.texImage3D() usage', gl,
+ function() {
+
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture[0]);
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture[1]);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width or height is less than 0.');
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, -1, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 1, -1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 1, 1, -1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, -1, -1, -1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, -1, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, 1, -1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, 1, 1, -1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, -1, -1, -1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('teximage3d_max_width_height_depth', 'Invalid gl.texImage3D() usage', gl,
+ function() {
+
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture[0]);
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture[1]);
+
+ var max3DTextureSize = /** @type{number} */ (gl.getParameter(gl.MAX_3D_TEXTURE_SIZE)) + 1;
+ var maxTextureSize = /** @type{number} */ (gl.getParameter(gl.MAX_TEXTURE_SIZE)) + 1;
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width, height or depth is greater than gl.MAX_3D_TEXTURE_SIZE.');
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, max3DTextureSize, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 1, max3DTextureSize, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 1, 1, max3DTextureSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, max3DTextureSize, max3DTextureSize, max3DTextureSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width, height or depth is greater than gl.MAX_TEXTURE_SIZE.');
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, maxTextureSize, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, 1, maxTextureSize, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, 1, 1, maxTextureSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, maxTextureSize, maxTextureSize, maxTextureSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('teximage3d_invalid_border', 'Invalid gl.texImage3D() usage', gl,
+ function() {
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture[0]);
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture[1]);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if border is not 0 or 1.');
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGB, 1, 1, 1, -1, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGB, 1, 1, 1, 2, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGB, 1, 1, 1, -1, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGB, 1, 1, 1, 2, gl.RGB, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ // gl.texSubImage3D
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texsubimage3d', 'Invalid gl.texSubImage3D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture);
+ gl.texImage3D (gl.TEXTURE_3D, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError (gl.NO_ERROR);
+
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(256);
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is invalid.');
+ gl.texSubImage3D(0, 0, 0, 0, 0, 4, 4, 4, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_ENUM);
+ gl.texSubImage3D(gl.TEXTURE_2D, 0, 0, 0, 0, 4, 4, 4, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if format is not an accepted format constant.');
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 0, 4, 4, 4, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not a type constant.');
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 4, 4, 4, gl.RGB, 0, uint8);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the combination of internalFormat of the previously specified texture array, format and type is not valid.');
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 4, 4, 4, gl.RGB, gl.UNSIGNED_SHORT_4_4_4_4, uint8);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 4, 4, 4, gl.RGB, gl.UNSIGNED_SHORT_5_5_5_1, uint8);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 4, 4, 4, gl.RGB, gl.UNSIGNED_SHORT_5_5_5_1, uint8);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 4, 4, 4, gl.RGBA_INTEGER, gl.UNSIGNED_INT, uint8);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 4, 4, 4, gl.RGB, gl.FLOAT, uint8);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texsubimage3d_neg_level', 'Invalid gl.texSubImage3D() usage', gl,
+ function() {
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture[0]);
+ gl.texImage3D (gl.TEXTURE_3D, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture[1]);
+ gl.texImage3D (gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError (gl.NO_ERROR);
+
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(4);
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is less than 0.');
+ gl.texSubImage3D(gl.TEXTURE_3D, -1, 0, 0, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, -1, 0, 0, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texsubimage3d_max_level', 'Invalid gl.texSubImage3D() usage', gl,
+ function() {
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture[0]);
+ gl.texImage3D (gl.TEXTURE_3D, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture[1]);
+ gl.texImage3D (gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError (gl.NO_ERROR);
+
+ /** @type{number} */ var log2Max3DTextureSize = Math.floor(Math.log2(/** @type{number} */(gl.getParameter(gl.MAX_3D_TEXTURE_SIZE)))) + 1;
+ /** @type{number} */ var log2MaxTextureSize = Math.floor(Math.log2(/** @type{number} */(gl.getParameter(gl.MAX_TEXTURE_SIZE)))) + 1;
+
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(4);
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_3D_TEXTURE_SIZE).');
+ gl.texSubImage3D(gl.TEXTURE_3D, log2Max3DTextureSize, 0, 0, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_TEXTURE_SIZE).');
+ gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, log2MaxTextureSize, 0, 0, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texsubimage3d_neg_offset', 'Invalid gl.texSubImage3D() usage', gl,
+ function() {
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture[0]);
+ gl.texImage3D (gl.TEXTURE_3D, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture[1]);
+ gl.texImage3D (gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError (gl.NO_ERROR);
+
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(4);
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if xoffset, yoffset or zoffset are negative.');
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, -1, 0, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, -1, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, -1, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, -1, -1, -1, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, 0, -1, 0, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, -1, 0, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, -1, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, 0, -1, -1, -1, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texsubimage3d_invalid_offset', 'Invalid gl.texSubImage3D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture);
+ gl.texImage3D (gl.TEXTURE_3D, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError (gl.NO_ERROR);
+
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(256);
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if xoffset + width > texture_width.');
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 2, 0, 0, 4, 4, 4, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if yoffset + height > texture_height.');
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 2, 0, 4, 4, 4, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if zoffset + depth > texture_depth.');
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 2, 4, 4, 4, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texsubimage3d_neg_width_height', 'Invalid gl.texSubImage3D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture);
+ gl.texImage3D (gl.TEXTURE_3D, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ /** @type {ArrayBufferView} */ var uint8 = new Uint8Array(4);
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width, height or depth is less than 0.');
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, -1, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 0, -1, 0, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 0, 0, -1, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+ gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, -1, -1, -1, gl.RGBA, gl.UNSIGNED_BYTE, uint8);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copytexsubimage3d', 'Invalid gl.copyTexSubImage3D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture);
+ gl.texImage3D (gl.TEXTURE_3D, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is invalid.');
+ gl.copyTexSubImage3D(0, 0, 0, 0, 0, 0, 0, 4, 0);
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.deleteTexture(texture);
+ }));
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copytexsubimage3d_neg_level', 'Invalid gl.copyTexSubImage3D() usage', gl,
+ function() {
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture[0]);
+ gl.texImage3D (gl.TEXTURE_3D, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture[1]);
+ gl.texImage3D (gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError (gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is less than 0.');
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, -1, 0, 0, 0, 0, 0, 4, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexSubImage3D(gl.TEXTURE_2D_ARRAY, -1, 0, 0, 0, 0, 0, 4, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copytexsubimage3d_max_level', 'Invalid gl.copyTexSubImage3D() usage', gl,
+ function() {
+ /** @type{number} */ var log2Max3DTextureSize = Math.floor(Math.log2(/** @type{number} */(gl.getParameter(gl.MAX_3D_TEXTURE_SIZE)))) + 1;
+ /** @type{number} */ var log2MaxTextureSize = Math.floor(Math.log2(/** @type{number} */(gl.getParameter(gl.MAX_TEXTURE_SIZE)))) + 1;
+
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture[0]);
+ gl.texImage3D (gl.TEXTURE_3D, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture[1]);
+ gl.texImage3D (gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError (gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_3D_TEXTURE_SIZE).');
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, log2Max3DTextureSize, 0, 0, 0, 0, 0, 4, 0);
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_TEXTURE_SIZE).');
+ gl.copyTexSubImage3D(gl.TEXTURE_2D_ARRAY, log2MaxTextureSize, 0, 0, 0, 0, 0, 4, 0);
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copytexsubimage3d_neg_offset', 'Invalid gl.copyTexSubImage3D() usage', gl,
+ function() {
+ /** @type{ WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture);
+ gl.texImage3D (gl.TEXTURE_3D, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if xoffset, yoffset or zoffset is negative.');
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, -1, 0, 0, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, -1, 0, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, -1, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_VALUE);
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, -1, -1, -1, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copytexsubimage3d_invalid_offset', 'Invalid gl.copyTexSubImage3D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture);
+ gl.texImage3D (gl.TEXTURE_3D, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if xoffset + width > texture_width.');
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 1, 0, 0, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if yoffset + height > texture_height.');
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 1, 0, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if zoffset + 1 > texture_depth.');
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 4, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copytexsubimage3d_neg_width_height', 'Invalid gl.copyTexSubImage3D() usage', gl,
+ function() {
+ /** @type{ WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture);
+ gl.texImage3D (gl.TEXTURE_3D, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width < 0.');
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 0, 0, -4, 4);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if height < 0.');
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 0, 0, 4, -4);
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('copytexsubimage3d_incomplete_framebuffer', 'Invalid gl.copyTexSubImage3D() usage', gl,
+ function() {
+ bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+ /** @type{WebGLFramebuffer} */ var fbo;
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_3D, texture[0]);
+ gl.texImage3D(gl.TEXTURE_3D, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, texture[1]);
+ gl.texImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA, 4, 4, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ this.expectError(gl.NO_ERROR);
+
+ fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, fbo);
+ gl.checkFramebufferStatus(gl.READ_FRAMEBUFFER);
+ this.expectError(gl.NO_ERROR);
+
+ gl.copyTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.copyTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, 0, 0, 4, 4);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ // gl.compressedTexImage3D
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedteximage3d', 'Invalid gl.compressedTexImage3D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{Array<WebGLTexture>} */ var texture = [];
+
+ // We have to create and bind textures to each target for the test because default textures are not supported by WebGL.
+ texture[0] = gl.createTexture();
+ texture[1] = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_CUBE_MAP, texture[0]);
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture[1]);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is invalid.');
+ gl.compressedTexImage3D(0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, 0, new Uint8Array(0));
+ this.expectError(gl.INVALID_ENUM);
+ gl.compressedTexImage3D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, 0, new Uint8Array(0));
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if internalformat is not one of the specific compressed internal formats.');
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, 0, 0, new Uint8Array(0));
+ this.expectError(gl.INVALID_ENUM);
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.RGBA8, 0, 0, 0, 0, new Uint8Array(0));
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.deleteTexture(texture[0]);
+ gl.deleteTexture(texture[1]);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedteximage3d_neg_level', 'Invalid gl.compressedTexImage3D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{ WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is less than 0.');
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, -1, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, 0, new Uint8Array(0));
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedteximage3d_max_level', 'Invalid gl.compressedTexImage3D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{ WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_TEXTURE_SIZE).');
+ /** @type{number} */ var log2MaxTextureSize = Math.floor(Math.log2(/** @type{number} */(gl.getParameter(gl.MAX_TEXTURE_SIZE)))) + 1;
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, log2MaxTextureSize, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, 0, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+
+ gl.deleteTexture(texture);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedteximage3d_neg_width_height_depth', 'Invalid gl.compressedTexImage3D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{ WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width, height or depth is less than 0.');
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, 0, 0, 0, new Uint8Array(0));
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, -1, 0, 0, new Uint8Array(0));
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, -1, 0, new Uint8Array(0));
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, -1, -1, -1, 0, new Uint8Array(0));
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedteximage3d_max_width_height_depth', 'Invalid gl.compressedTexImage3D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{ WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture);
+
+ var maxTextureSize = /** @type{number} */(gl.getParameter(gl.MAX_TEXTURE_SIZE)) + 1;
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width, height or depth is greater than gl.MAX_TEXTURE_SIZE.');
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, maxTextureSize, 0, 0, 0, new Uint8Array(0));
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, maxTextureSize, 0, 0, new Uint8Array(0));
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, maxTextureSize, 0, new Uint8Array(0));
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, maxTextureSize, maxTextureSize, maxTextureSize, 0, new Uint8Array(0));
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedteximage3d_invalid_border', 'Invalid gl.compressedTexImage3D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{ WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if border is not 0.');
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, -1, new Uint8Array(0));
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, 1, new Uint8Array(0));
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedteximage3d_invalid_size', 'Invalid gl.compressedTexImage3D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{ WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if imageSize is not consistent with the format, dimensions, and contents of the specified compressed image data.');
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 0, 0, 0, 0, new Uint8Array(1));
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 1, 0, new Uint8Array(4*4*8));
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGB8_ETC2, 16, 16, 1, 0, new Uint8Array(4*4*16));
+ this.expectError(gl.INVALID_VALUE);
+ gl.compressedTexImage3D(gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_SIGNED_R11_EAC, 16, 16, 1, 0, new Uint8Array(4*4*16));
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+
+ }));
+
+ // gl.compressedTexSubImage3D
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedtexsubimage3d', 'Invalid gl.compressedTexSubImage3D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is invalid.');
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.compressedTexSubImage3D(0, 0, 0, 0, 0, 0, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError(gl.INVALID_ENUM);
+
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture);
+ gl.compressedTexImage3D (gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 18, 18, 1, 0, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(18, 18)));
+ this.expectError (gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if format does not match the internal format of the texture image being modified.');
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, 0, 0, 0, gl.COMPRESSED_RGB8_ETC2, new Uint8Array(0));
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if internalformat is an ETC2/EAC format and target is not gl.TEXTURE_2D_ARRAY.');
+ gl.compressedTexSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 0, 18, 18, 1, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(18, 18)));
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('For ETC2/EAC images gl.INVALID_OPERATION is generated if width is not a multiple of four, and width + xoffset is not equal to the width of the texture level.');
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 4, 0, 0, 10, 4, 1, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(10, 4)));
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('For ETC2/EAC images gl.INVALID_OPERATION is generated if height is not a multiple of four, and height + yoffset is not equal to the height of the texture level.');
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 4, 0, 4, 10, 1, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(4, 10)));
+ this.expectError(gl.INVALID_OPERATION);
+
+ bufferedLogToConsole('For ETC2/EAC images gl.INVALID_OPERATION is generated if xoffset or yoffset is not a multiple of four.');
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 1, 0, 0, 4, 4, 1, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(4, 4)));
+ this.expectError(gl.INVALID_OPERATION);
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 1, 0, 4, 4, 1, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(4, 4)));
+ this.expectError(gl.INVALID_OPERATION);
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 1, 1, 0, 4, 4, 1, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(4, 4)));
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedtexsubimage3d_neg_level', 'Invalid gl.compressedTexSubImage3D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture);
+ gl.compressedTexImage3D (gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 1, 0, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(16, 16)));
+ this.expectError (gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is less than 0.');
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, -1, 0, 0, 0, 0, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedtexsubimage3d_max_level', 'Invalid gl.compressedTexSubImage3D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture);
+ gl.compressedTexImage3D (gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 1, 0, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(16, 16)));
+ this.expectError (gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if level is greater than log_2(gl.MAX_TEXTURE_SIZE).');
+ /** @type{number} */ var log2MaxTextureSize = Math.floor(Math.log2(/** @type{number} */(gl.getParameter(gl.MAX_TEXTURE_SIZE)))) + 1;
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, log2MaxTextureSize, 0, 0, 0, 0, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedtexsubimage3d_neg_offset', 'Invalid gl.compressedTexSubImage3D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture);
+ gl.compressedTexImage3D (gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 1, 0, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(16, 16)));
+ this.expectError (gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE or gl.INVALID_OPERATION is generated if xoffset, yoffset or zoffset are negative.');
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, -4, 0, 0, 0, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, -4, 0, 0, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, -4, 0, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, -4, -4, -4, 0, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedtexsubimage3d_invalid_offset', 'Invalid gl.compressedTexSubImage3D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture);
+ gl.compressedTexImage3D (gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 4, 4, 1, 0, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(4, 4)));
+ this.expectError (gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE or gl.INVALID_OPERATION is generated if xoffset + width > texture_width or yoffset + height > texture_height.');
+
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 12, 0, 0, 8, 4, 1, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(8, 4)));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 12, 0, 4, 8, 1, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(4, 8)));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 12, 4, 4, 1, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(4, 4)));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 12, 12, 12, 8, 8, 1, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(8, 8)));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedtexsubimage3d_neg_width_height_depth', 'Invalid gl.compressedTexSubImage3D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture);
+ gl.compressedTexImage3D (gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 1, 0, new Uint8Array(es3fNegativeTextureApiTests.etc2EacDataSize(16, 16)));
+ this.expectError (gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE or gl.INVALID_OPERATION is generated if width, height or depth are negative.');
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, -4, 0, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, 0, -4, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, 0, 0, -4, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, -4, -4, -4, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError([gl.INVALID_VALUE, gl.INVALID_OPERATION]);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('compressedtexsubimage3d_invalid_size', 'Invalid gl.compressedTexSubImage3D() usage', gl,
+ function() {
+ if (!haveCompressedTextureETC) { etc2Unsupported(); return; }
+
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D_ARRAY, texture);
+ gl.compressedTexImage3D (gl.TEXTURE_2D_ARRAY, 0, gl.COMPRESSED_RGBA8_ETC2_EAC, 16, 16, 1, 0, new Uint8Array(4*4*16));
+ this.expectError (gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if imageSize is not consistent with the format, dimensions, and contents of the specified compressed image data.');
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, 16, 16, 1, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(0));
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.compressedTexSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, 16, 16, 1, gl.COMPRESSED_RGBA8_ETC2_EAC, new Uint8Array(4*4*16-1));
+ this.expectError(gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ // gl.texStorage2D
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texstorage2d', 'Invalid gl.texStorage2D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D, texture);
+
+ bufferedLogToConsole('gl.INVALID_ENUM or gl.INVALID_VALUE is generated if internalformat is not a valid sized internal format.');
+ gl.texStorage2D (gl.TEXTURE_2D, 1, 0, 16, 16);
+ this.expectError ([gl.INVALID_ENUM, gl.INVALID_VALUE]);
+ gl.texStorage2D (gl.TEXTURE_2D, 1, gl.RGBA_INTEGER, 16, 16);
+ this.expectError ([gl.INVALID_ENUM, gl.INVALID_VALUE]);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not one of the accepted target enumerants.');
+ gl.texStorage2D (0, 1, gl.RGBA8, 16, 16);
+ this.expectError (gl.INVALID_ENUM);
+ gl.texStorage2D (gl.TEXTURE_3D, 1, gl.RGBA8, 16, 16);
+ this.expectError (gl.INVALID_ENUM);
+ gl.texStorage2D (gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, 16, 16);
+ this.expectError (gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width or height are less than 1.');
+ gl.texStorage2D (gl.TEXTURE_2D, 1, gl.RGBA8, 0, 16);
+ this.expectError (gl.INVALID_VALUE);
+ gl.texStorage2D (gl.TEXTURE_2D, 1, gl.RGBA8, 16, 0);
+ this.expectError (gl.INVALID_VALUE);
+ gl.texStorage2D (gl.TEXTURE_2D, 1, gl.RGBA8, 0, 0);
+ this.expectError (gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texstorage2d_invalid_binding', 'Invalid gl.texStorage2D() usage', gl,
+ function() {
+ gl.bindTexture (gl.TEXTURE_2D, null);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if there is no texture object curently bound to target.');
+ gl.texStorage2D (gl.TEXTURE_2D, 1, gl.RGBA8, 16, 16);
+ this.expectError (gl.INVALID_OPERATION);
+
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D, texture);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the texture object currently bound to target already has gl.TEXTURE_IMMUTABLE_FORMAT set to true.');
+ /** @type{number} */ var immutable;
+ immutable = /** @type{number} */(gl.getTexParameter(gl.TEXTURE_2D, gl.TEXTURE_IMMUTABLE_FORMAT));
+ bufferedLogToConsole('// gl.TEXTURE_IMMUTABLE_FORMAT = ' + ((immutable != 0) ? 'true' : 'false'));
+ gl.texStorage2D (gl.TEXTURE_2D, 1, gl.RGBA8, 16, 16);
+ this.expectError (gl.NO_ERROR);
+ immutable = /** @type{number} */(gl.getTexParameter(gl.TEXTURE_2D, gl.TEXTURE_IMMUTABLE_FORMAT));
+ bufferedLogToConsole('// gl.TEXTURE_IMMUTABLE_FORMAT = ' + ((immutable != 0) ? 'true' : 'false'));
+ gl.texStorage2D (gl.TEXTURE_2D, 1, gl.RGBA8, 16, 16);
+ this.expectError (gl.INVALID_OPERATION);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texstorage2d_invalid_levels', 'Invalid gl.texStorage2D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_2D, texture);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if levels is less than 1.');
+ gl.texStorage2D (gl.TEXTURE_2D, 0, gl.RGBA8, 16, 16);
+ this.expectError (gl.INVALID_VALUE);
+ gl.texStorage2D (gl.TEXTURE_2D, 0, gl.RGBA8, 0, 0);
+ this.expectError (gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if levels is greater than floor(log_2(max(width, height))) + 1');
+ /** @type{number} */ var log2MaxSize = Math.floor(Math.log2(Math.max(16, 4))) + 1 + 1;
+ gl.texStorage2D (gl.TEXTURE_2D, log2MaxSize, gl.RGBA8, 16, 4);
+ this.expectError (gl.INVALID_OPERATION);
+ gl.texStorage2D (gl.TEXTURE_2D, log2MaxSize, gl.RGBA8, 4, 16);
+ this.expectError (gl.INVALID_OPERATION);
+ gl.texStorage2D (gl.TEXTURE_2D, log2MaxSize, gl.RGBA8, 16, 16);
+ this.expectError (gl.INVALID_OPERATION);
+
+ gl.deleteTexture(texture);
+ }));
+
+ // gl.texStorage3D
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texstorage3d', 'Invalid gl.texStorage3D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture);
+
+ bufferedLogToConsole('gl.INVALID_ENUM or gl.INVALID_VALUE is generated if internalformat is not a valid sized internal format.');
+ gl.texStorage3D (gl.TEXTURE_3D, 1, 0, 4, 4, 4);
+ this.expectError ([gl.INVALID_ENUM, gl.INVALID_VALUE]);
+ gl.texStorage3D (gl.TEXTURE_3D, 1, gl.RGBA_INTEGER, 4, 4, 4);
+ this.expectError ([gl.INVALID_ENUM, gl.INVALID_VALUE]);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if target is not one of the accepted target enumerants.');
+ gl.texStorage3D (0, 1, gl.RGBA8, 4, 4, 4);
+ this.expectError (gl.INVALID_ENUM);
+ gl.texStorage3D (gl.TEXTURE_CUBE_MAP, 1, gl.RGBA8, 4, 4, 4);
+ this.expectError (gl.INVALID_ENUM);
+ gl.texStorage3D (gl.TEXTURE_2D, 1, gl.RGBA8, 4, 4, 4);
+ this.expectError (gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if width, height or depth are less than 1.');
+ gl.texStorage3D (gl.TEXTURE_3D, 1, gl.RGBA8, 0, 4, 4);
+ this.expectError (gl.INVALID_VALUE);
+ gl.texStorage3D (gl.TEXTURE_3D, 1, gl.RGBA8, 4, 0, 4);
+ this.expectError (gl.INVALID_VALUE);
+ gl.texStorage3D (gl.TEXTURE_3D, 1, gl.RGBA8, 4, 4, 0);
+ this.expectError (gl.INVALID_VALUE);
+ gl.texStorage3D (gl.TEXTURE_3D, 1, gl.RGBA8, 0, 0, 0);
+ this.expectError (gl.INVALID_VALUE);
+
+ gl.deleteTexture(texture);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texstorage3d_invalid_binding', 'Invalid gl.texStorage3D() usage', gl,
+ function() {
+ gl.bindTexture (gl.TEXTURE_3D, null);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if there is no texture object curently bound to target.');
+ gl.texStorage3D (gl.TEXTURE_3D, 1, gl.RGBA8, 4, 4, 4);
+ this.expectError (gl.INVALID_OPERATION);
+
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if the texture object currently bound to target already has gl.TEXTURE_IMMUTABLE_FORMAT set to true.');
+ /** @type{number} */ var immutable;
+ immutable = /** @type{number} */(gl.getTexParameter(gl.TEXTURE_3D, gl.TEXTURE_IMMUTABLE_FORMAT));
+ bufferedLogToConsole('// gl.TEXTURE_IMMUTABLE_FORMAT = ' + ((immutable != 0) ? 'true' : 'false'));
+ gl.texStorage3D (gl.TEXTURE_3D, 1, gl.RGBA8, 4, 4, 4);
+ this.expectError (gl.NO_ERROR);
+ immutable = /** @type{number} */(gl.getTexParameter(gl.TEXTURE_3D, gl.TEXTURE_IMMUTABLE_FORMAT));
+ bufferedLogToConsole('// gl.TEXTURE_IMMUTABLE_FORMAT = ' + ((immutable != 0) ? 'true' : 'false'));
+ gl.texStorage3D (gl.TEXTURE_3D, 1, gl.RGBA8, 4, 4, 4);
+ this.expectError (gl.INVALID_OPERATION);
+
+ gl.deleteTexture(texture);
+ }));
+
+ // NOTE: the test doesn't cause glError using the parameters defined in the original test of C code
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('texstorage3d_invalid_levels', 'Invalid gl.texStorage3D() usage', gl,
+ function() {
+ /** @type{WebGLTexture} */ var texture;
+ texture = gl.createTexture();
+ gl.bindTexture (gl.TEXTURE_3D, texture);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if levels is less than 1.');
+ gl.texStorage3D (gl.TEXTURE_3D, 0, gl.RGBA8, 4, 4, 4);
+ this.expectError (gl.INVALID_VALUE);
+ gl.texStorage3D (gl.TEXTURE_3D, 0, gl.RGBA8, 0, 0, 0);
+ this.expectError (gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if levels is greater than floor(log_2(max(width, height, depth))) + 1');
+ /** @type{number} */ var log2MaxSize = Math.floor(Math.log2(8)) + 1 + 1;
+ gl.texStorage3D (gl.TEXTURE_3D, log2MaxSize, gl.RGBA8, 8, 2, 2);
+ this.expectError (gl.INVALID_OPERATION);
+ gl.texStorage3D (gl.TEXTURE_3D, log2MaxSize, gl.RGBA8, 2, 8, 2);
+ this.expectError (gl.INVALID_OPERATION);
+ gl.texStorage3D (gl.TEXTURE_3D, log2MaxSize, gl.RGBA8, 2, 2, 8);
+ this.expectError (gl.INVALID_OPERATION);
+ gl.texStorage3D (gl.TEXTURE_3D, log2MaxSize, gl.RGBA8, 8, 8, 8);
+ this.expectError (gl.INVALID_OPERATION);
+
+ gl.deleteTexture(texture);
+ }));
+ };
+
+ /**
+ * @param {WebGL2RenderingContext} gl
+ */
+ es3fNegativeTextureApiTests.run = function(gl) {
+ var testName = 'negativeTextureApi';
+ var testDescription = 'Negative Texture API tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.testCases = tcuTestCase.newTest(testName, testDescription, null);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+ try {
+ es3fNegativeTextureApiTests.init(gl);
+ tcuTestCase.runner.runCallback(tcuTestCase.runTestCases);
+ } catch (err) {
+ bufferedLogToConsole(err);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeVertexArrayApiTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeVertexArrayApiTests.js
new file mode 100644
index 0000000000..d921a6f52b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fNegativeVertexArrayApiTests.js
@@ -0,0 +1,906 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.0 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Negative Vertex Array API tests.
+ *//*--------------------------------------------------------------------*/
+'use strict';
+goog.provide('functional.gles3.es3fNegativeVertexArrayApiTests');
+
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('functional.gles3.es3fApiCase');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.simplereference.sglrGLContext');
+
+goog.scope(function() {
+
+ var es3fNegativeVertexArrayApiTests = functional.gles3.es3fNegativeVertexArrayApiTests;
+ var tcuTexture = framework.common.tcuTexture;
+ var es3fApiCase = functional.gles3.es3fApiCase;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
+
+ /**
+ * @type {string}
+ * @const
+ */
+ var vertexShaderSource = '#version 300 es\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(0.0);\n' +
+ '}\n';
+
+ /**
+ * @type {string}
+ * @const
+ */
+ var fragmentShaderSource = '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ /**
+ * @param {WebGL2RenderingContext} gl
+ */
+ es3fNegativeVertexArrayApiTests.init = function(gl) {
+
+ var testGroup = tcuTestCase.runner.testCases;
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('vertex_attribf', 'Invalid glVertexAttrib{1234}f() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
+ var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ gl.vertexAttrib1f(maxVertexAttribs, 0.0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.vertexAttrib2f(maxVertexAttribs, 0.0, 0.0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.vertexAttrib3f(maxVertexAttribs, 0.0, 0.0, 0.0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.vertexAttrib4f(maxVertexAttribs, 0.0, 0.0, 0.0, 0.0);
+ this.expectError(gl.INVALID_VALUE);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('vertex_attribfv', 'Invalid glVertexAttrib{1234}fv() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
+ var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ /** @type{Array<number>} */ var v = [0.0];
+ gl.vertexAttrib1fv(maxVertexAttribs, v);
+ this.expectError(gl.INVALID_VALUE);
+ gl.vertexAttrib2fv(maxVertexAttribs, v);
+ this.expectError(gl.INVALID_VALUE);
+ gl.vertexAttrib3fv(maxVertexAttribs, v);
+ this.expectError(gl.INVALID_VALUE);
+ gl.vertexAttrib4fv(maxVertexAttribs, v);
+ this.expectError(gl.INVALID_VALUE);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('vertex_attribi4', 'Invalid glVertexAttribI4{i|ui}f() usage', gl, function() {
+ var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ /** @type{number} */ var valInt = 0;
+ /** @type{number} */ var valUint = 0;
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
+ gl.vertexAttribI4i(maxVertexAttribs, valInt, valInt, valInt, valInt);
+ this.expectError(gl.INVALID_VALUE);
+ gl.vertexAttribI4ui(maxVertexAttribs, valUint, valUint, valUint, valUint);
+ this.expectError(gl.INVALID_VALUE);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('vertex_attribi4v', 'Invalid glVertexAttribI4{i|ui}fv() usage', gl, function() {
+ var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ /** @type{Array<number>} */ var valInt = [0];
+ /** @type{Array<number>} */ var valUint = [0];
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
+ gl.vertexAttribI4iv(maxVertexAttribs, valInt);
+ this.expectError(gl.INVALID_VALUE);
+ gl.vertexAttribI4uiv(maxVertexAttribs, valUint);
+ this.expectError(gl.INVALID_VALUE);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('vertex_attrib_pointer', 'Invalid gl.vertexAttribPointer() usage', gl, function() {
+ /** @type{WebGLBuffer} */ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not an accepted value.');
+ gl.vertexAttribPointer(0, 1, 0, true, 0, 0);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
+ var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ gl.vertexAttribPointer(maxVertexAttribs, 1, gl.BYTE, true, 0, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if size is not 1, 2, 3, or 4.');
+ gl.vertexAttribPointer(0, 0, gl.BYTE, true, 0, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if stride is negative.');
+ gl.vertexAttribPointer(0, 1, gl.BYTE, true, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if type is gl.INT_2_10_10_10_REV or gl.UNSIGNED_INT_2_10_10_10_REV and size is not 4.');
+ gl.vertexAttribPointer(0, 2, gl.INT_2_10_10_10_REV, true, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.vertexAttribPointer(0, 2, gl.UNSIGNED_INT_2_10_10_10_REV, true, 0, 0);
+ this.expectError(gl.INVALID_OPERATION);
+ gl.vertexAttribPointer(0, 4, gl.INT_2_10_10_10_REV, true, 0, 0);
+ this.expectError(gl.NO_ERROR);
+ gl.vertexAttribPointer(0, 4, gl.UNSIGNED_INT_2_10_10_10_REV, true, 0, 0);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated a non-zero vertex array object is bound, zero is bound to the gl.ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL.');
+ /** @type{WebGLVertexArrayObject} */ var vao;
+ /** @type{number} */ var offset = 1;
+ vao = gl.createVertexArray();
+ gl.bindVertexArray(vao);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ this.expectError(gl.NO_ERROR);
+
+ gl.vertexAttribPointer(0, 1, gl.BYTE, true, 0, offset);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.bindVertexArray(null);
+ gl.deleteVertexArray(vao);
+ this.expectError(gl.NO_ERROR);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('vertex_attrib_i_pointer', 'Invalid gl.vertexAttribIPointer() usage', gl, function() {
+ /** @type{WebGLBuffer} */ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not an accepted value.');
+ gl.vertexAttribIPointer(0, 1, 0, 0, 0);
+ this.expectError(gl.INVALID_ENUM);
+ gl.vertexAttribIPointer(0, 4, gl.INT_2_10_10_10_REV, 0, 0);
+ this.expectError(gl.INVALID_ENUM);
+ gl.vertexAttribIPointer(0, 4, gl.UNSIGNED_INT_2_10_10_10_REV, 0, 0);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
+ var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ gl.vertexAttribIPointer(maxVertexAttribs, 1, gl.BYTE, 0, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if size is not 1, 2, 3, or 4.');
+ gl.vertexAttribIPointer(0, 0, gl.BYTE, 0, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if stride is negative.');
+ gl.vertexAttribIPointer(0, 1, gl.BYTE, -1, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated a non-zero vertex array object is bound, zero is bound to the gl.ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL.');
+ /** @type{WebGLVertexArrayObject} */ var vao;
+ /** @type{number} */ var offset = 1;
+ vao = gl.createVertexArray();
+ gl.bindVertexArray(vao);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ this.expectError(gl.NO_ERROR);
+
+ gl.vertexAttribIPointer(0, 1, gl.BYTE, 0, offset);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.bindVertexArray(null);
+ gl.deleteVertexArray(vao);
+ this.expectError(gl.NO_ERROR);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('enable_vertex_attrib_array', 'Invalid gl.enableVertexAttribArray() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
+ var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ gl.enableVertexAttribArray(maxVertexAttribs);
+ this.expectError(gl.INVALID_VALUE);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('disable_vertex_attrib_array', 'Invalid gl.disableVertexAttribArray() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
+ var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ gl.disableVertexAttribArray(maxVertexAttribs);
+ this.expectError(gl.INVALID_VALUE);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('vertex_attrib_divisor', 'Invalid gl.vertexAttribDivisor() usage', gl, function() {
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if index is greater than or equal to gl.MAX_VERTEX_ATTRIBS.');
+ var maxVertexAttribs = /** @type{number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ gl.vertexAttribDivisor(maxVertexAttribs, 0);
+ this.expectError(gl.INVALID_VALUE);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_arrays', 'Invalid gl.drawArrays() usage', gl, function() {
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ gl.useProgram(program.getProgram());
+ /** @type{WebGLFramebuffer} */ var fbo;
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
+ gl.drawArrays(-1, 0, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
+ gl.drawArrays(gl.POINTS, 0, -1);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
+ fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ gl.drawArrays(gl.POINTS, 0, 1);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+
+ gl.useProgram(null);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_arrays_invalid_program', 'Invalid gl.drawArrays() usage', gl, function() {
+ gl.useProgram(null);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.useProgram(null) is used.');
+ gl.drawArrays(gl.POINTS, 0, 1);
+ this.expectError(gl.INVALID_OPERATION);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_arrays_incomplete_primitive', 'Invalid gl.drawArrays() usage', gl, function() {
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ gl.useProgram(program.getProgram());
+ /** @type{WebGLFramebuffer} */ var fbo;
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
+ gl.drawArrays(-1, 0, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
+ gl.drawArrays(gl.TRIANGLES, 0, -1);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
+ fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ gl.drawArrays(gl.TRIANGLES, 0, 1);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+
+ gl.useProgram(null);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_elements', 'Invalid gl.drawElements() usage', gl, function() {
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ gl.useProgram(program.getProgram());
+ /** @type{WebGLFramebuffer} */ var fbo;
+ /** @type{WebGLBuffer} */ var buf;
+ /** @type{WebGLTransformFeedback} */ var tfID;
+ /** @type{number} */ var vertices = 0;
+
+ /** @type{WebGLBuffer} */ var bufElements = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
+ gl.drawElements(-1, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
+ gl.drawElements(gl.POINTS, 0, -1, vertices);
+ this.expectError(gl.INVALID_ENUM);
+ gl.drawElements(gl.POINTS, 0, gl.FLOAT, vertices);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
+ gl.drawElements(gl.POINTS, -1, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
+ fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ gl.drawElements(gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+
+ if (!sglrGLContext.isExtensionSupported(gl, 'EXT_geometry_shader')) { // gl.EXT_geometry_shader removes error
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is active and not paused.');
+ /** @type{Array<string>} */ var tfVarying = ['gl_Position'];
+
+ buf = gl.createBuffer();
+ tfID = gl.createTransformFeedback();
+
+ gl.useProgram (program.getProgram());
+ gl.transformFeedbackVaryings (program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram (program.getProgram());
+ gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, tfID);
+ gl.bindBuffer (gl.TRANSFORM_FEEDBACK_BUFFER, buf);
+ gl.bufferData (gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
+ gl.bindBufferBase (gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+ gl.beginTransformFeedback (gl.POINTS);
+ this.expectError (gl.NO_ERROR);
+
+ gl.drawElements (gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError (gl.INVALID_OPERATION);
+
+ gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
+
+ gl.pauseTransformFeedback();
+ gl.drawElements (gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError (gl.NO_ERROR);
+
+ gl.endTransformFeedback ();
+ gl.deleteBuffer(buf);
+ gl.deleteTransformFeedback(tfID);
+ gl.deleteBuffer(bufElements);
+ this.expectError (gl.NO_ERROR);
+
+ }
+
+ gl.useProgram(null);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_elements_invalid_program', 'Invalid gl.drawElements() usage', gl, function() {
+ gl.useProgram(null);
+ /** @type{number} */ var vertices = 0;
+
+ /** @type{WebGLBuffer} */ var bufElements = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.useProgram(null) was set.');
+ gl.drawElements(gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteBuffer(bufElements);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_elements_incomplete_primitive', 'Invalid gl.drawElements() usage', gl, function() {
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ gl.useProgram(program.getProgram());
+ /** @type{WebGLFramebuffer} */ var fbo;
+ /** @type{WebGLBuffer} */ var buf;
+ /** @type{WebGLTransformFeedback} */ var tfID;
+ /** @type{number} */ var vertices = 0;
+
+ /** @type{WebGLBuffer} */ var bufElements = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
+ gl.drawElements(-1, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
+ gl.drawElements(gl.TRIANGLES, 0, -1, vertices);
+ this.expectError(gl.INVALID_ENUM);
+ gl.drawElements(gl.TRIANGLES, 0, gl.FLOAT, vertices);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
+ gl.drawElements(gl.TRIANGLES, -1, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
+ fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ gl.drawElements(gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+
+ if (!sglrGLContext.isExtensionSupported(gl, 'EXT_geometry_shader')) {// gl.EXT_geometry_shader removes error
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is active and not paused.');
+ /** @type{Array<string>} */ var tfVarying = ['gl_Position'];
+
+ buf = gl.createBuffer();
+ tfID = gl.createTransformFeedback();
+
+ gl.useProgram (program.getProgram());
+ gl.transformFeedbackVaryings (program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram (program.getProgram());
+ gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, tfID);
+ gl.bindBuffer (gl.TRANSFORM_FEEDBACK_BUFFER, buf);
+ gl.bufferData (gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
+ gl.bindBufferBase (gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+ gl.beginTransformFeedback (gl.TRIANGLES);
+ this.expectError (gl.NO_ERROR);
+
+ gl.drawElements (gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError (gl.INVALID_OPERATION);
+
+ gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
+
+ gl.pauseTransformFeedback();
+ gl.drawElements (gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError (gl.NO_ERROR);
+
+ gl.endTransformFeedback ();
+ gl.deleteBuffer(buf);
+ gl.deleteTransformFeedback(tfID);
+ gl.deleteBuffer(bufElements);
+ this.expectError (gl.NO_ERROR);
+
+ }
+
+ gl.useProgram(null);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_arrays_instanced', 'Invalid gl.drawArraysInstanced() usage', gl, function() {
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ gl.useProgram(program.getProgram());
+ /** @type{WebGLFramebuffer} */ var fbo;
+
+ /** @type{WebGLBuffer} */ var bufElements = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, bufElements);
+
+ gl.vertexAttribDivisor(0, 1);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
+ gl.drawArraysInstanced(-1, 0, 1, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if count or primcount are negative.');
+ gl.drawArraysInstanced(gl.POINTS, 0, -1, 1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.drawArraysInstanced(gl.POINTS, 0, 1, -1);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
+ fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ gl.drawArraysInstanced(gl.POINTS, 0, 1, 1);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+
+ gl.deleteBuffer(bufElements);
+
+ gl.useProgram(null);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_arrays_instanced_invalid_program', 'Invalid gl.drawArraysInstanced() usage', gl, function() {
+ gl.useProgram(null);
+
+ /** @type{WebGLBuffer} */ var bufElements = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, bufElements);
+
+ gl.vertexAttribDivisor(0, 1);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.useProgram(null) is set.');
+ gl.drawArraysInstanced(gl.POINTS, 0, 1, 1);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteBuffer(bufElements);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_arrays_instanced_incomplete_primitive', 'Invalid gl.drawArraysInstanced() usage', gl, function() {
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ gl.useProgram(program.getProgram());
+ /** @type{WebGLFramebuffer} */ var fbo;
+
+ /** @type{WebGLBuffer} */ var bufElements = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, bufElements);
+
+ gl.vertexAttribDivisor(0, 1);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
+ gl.drawArraysInstanced(-1, 0, 1, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if count or primcount are negative.');
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, -1, 1);
+ this.expectError(gl.INVALID_VALUE);
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 1, -1);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
+ fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 1, 1);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+
+ gl.deleteBuffer(bufElements);
+
+ gl.useProgram(null);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_elements_instanced', 'Invalid gl.drawElementsInstanced() usage', gl, function() {
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ gl.useProgram(program.getProgram());
+ /** @type{WebGLFramebuffer} */ var fbo;
+ /** @type{WebGLBuffer} */ var buf;
+ /** @type{WebGLTransformFeedback} */ var tfID;
+ /** @type{number} */ var vertices = 0;
+
+ /** @type{WebGLBuffer} */ var bufElements = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
+
+ gl.vertexAttribDivisor(0, 1);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
+ gl.drawElementsInstanced(-1, 0, gl.UNSIGNED_BYTE, vertices, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
+ gl.drawElementsInstanced(gl.POINTS, 0, -1, vertices, 1);
+ this.expectError(gl.INVALID_ENUM);
+ gl.drawElementsInstanced(gl.POINTS, 0, gl.FLOAT, vertices, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if count or primcount are negative.');
+ gl.drawElementsInstanced(gl.POINTS, -1, gl.UNSIGNED_BYTE, vertices, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.drawElementsInstanced(gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices, -1);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
+ fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ gl.drawElementsInstanced(gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices, 1);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+
+ if (!sglrGLContext.isExtensionSupported(gl, 'EXT_geometry_shader')) {// gl.EXT_geometry_shader removes error
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is active and not paused.');
+ /** @type{Array<string>} */ var tfVarying = ['gl_Position'];
+
+ buf = gl.createBuffer();
+ tfID = gl.createTransformFeedback();
+
+ gl.useProgram (program.getProgram());
+ gl.transformFeedbackVaryings (program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram (program.getProgram());
+ gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, tfID);
+ gl.bindBuffer (gl.TRANSFORM_FEEDBACK_BUFFER, buf);
+ gl.bufferData (gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
+ gl.bindBufferBase (gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+ gl.beginTransformFeedback (gl.POINTS);
+ this.expectError (gl.NO_ERROR);
+
+ gl.drawElementsInstanced (gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices, 1);
+ this.expectError (gl.INVALID_OPERATION);
+
+ gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
+
+ gl.pauseTransformFeedback();
+ gl.drawElementsInstanced (gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices, 1);
+ this.expectError (gl.NO_ERROR);
+
+ gl.endTransformFeedback ();
+ gl.deleteBuffer(buf);
+ gl.deleteTransformFeedback(tfID);
+ gl.deleteBuffer(bufElements);
+ this.expectError (gl.NO_ERROR);
+
+ }
+
+ gl.useProgram(null);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_elements_instanced_invalid_program', 'Invalid gl.drawElementsInstanced() usage', gl, function() {
+ gl.useProgram(null);
+ /** @type{number} */ var vertices = 0;
+
+ /** @type{WebGLBuffer} */ var bufElements;
+ bufElements = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
+
+ gl.vertexAttribDivisor(0, 1);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.useProgram(null) is set.');
+ gl.drawElementsInstanced(gl.POINTS, 0, gl.UNSIGNED_BYTE, vertices, 1);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteBuffer(bufElements);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_elements_instanced_incomplete_primitive', 'Invalid gl.drawElementsInstanced() usage', gl, function() {
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ gl.useProgram(program.getProgram());
+ /** @type{WebGLFramebuffer} */ var fbo;
+ /** @type{WebGLBuffer} */ var buf;
+ /** @type{WebGLTransformFeedback} */ var tfID;
+ /** @type{number} */ var vertices = 0;
+
+ /** @type{WebGLBuffer} */ var bufElements;
+ bufElements = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
+
+ gl.vertexAttribDivisor(0, 1);
+ this.expectError(gl.NO_ERROR);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
+ gl.drawElementsInstanced(-1, 0, gl.UNSIGNED_BYTE, vertices, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
+ gl.drawElementsInstanced(gl.TRIANGLES, 0, -1, vertices, 1);
+ this.expectError(gl.INVALID_ENUM);
+ gl.drawElementsInstanced(gl.TRIANGLES, 0, gl.FLOAT, vertices, 1);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if count or primcount are negative.');
+ gl.drawElementsInstanced(gl.TRIANGLES, -1, gl.UNSIGNED_BYTE, vertices, 0);
+ this.expectError(gl.INVALID_VALUE);
+ gl.drawElementsInstanced(gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices, -1);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
+ fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ gl.drawElementsInstanced(gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices, 1);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+
+ if (!sglrGLContext.isExtensionSupported(gl, 'EXT_geometry_shader')) {// gl.EXT_geometry_shader removes error
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is active and not paused.');
+ /** @type{Array<string>} */ var tfVarying = ['gl_Position'];
+
+ buf = gl.createBuffer();
+ tfID = gl.createTransformFeedback();
+
+ gl.useProgram (program.getProgram());
+ gl.transformFeedbackVaryings (program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram (program.getProgram());
+ gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, tfID);
+ gl.bindBuffer (gl.TRANSFORM_FEEDBACK_BUFFER, buf);
+ gl.bufferData (gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
+ gl.bindBufferBase (gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+ gl.beginTransformFeedback (gl.TRIANGLES);
+ this.expectError (gl.NO_ERROR);
+
+ gl.drawElementsInstanced (gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices, 1);
+ this.expectError (gl.INVALID_OPERATION);
+
+ gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
+
+ gl.pauseTransformFeedback();
+ gl.drawElementsInstanced (gl.TRIANGLES, 0, gl.UNSIGNED_BYTE, vertices, 1);
+ this.expectError (gl.NO_ERROR);
+
+ gl.endTransformFeedback ();
+ gl.deleteBuffer(buf);
+ gl.deleteTransformFeedback(tfID);
+ gl.deleteBuffer(bufElements);
+ this.expectError (gl.NO_ERROR);
+
+ }
+
+ gl.useProgram(null);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_range_elements', 'Invalid gl.drawRangeElements() usage', gl, function() {
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ gl.useProgram(program.getProgram());
+ /** @type{WebGLFramebuffer} */ var fbo;
+ /** @type{WebGLBuffer} */ var buf;
+ /** @type{WebGLTransformFeedback} */ var tfID;
+ /** @type{number} */ var vertices = 0;
+
+ /** @type{WebGLBuffer} */ var bufElements;
+ bufElements = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
+ gl.drawRangeElements(-1, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
+ gl.drawRangeElements(gl.POINTS, 0, 1, 0, -1, vertices);
+ this.expectError(gl.INVALID_ENUM);
+ gl.drawRangeElements(gl.POINTS, 0, 1, 0, gl.FLOAT, vertices);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
+ gl.drawRangeElements(gl.POINTS, 0, 1, -1, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if end < start.');
+ gl.drawRangeElements(gl.POINTS, 1, 0, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
+ fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ gl.drawRangeElements(gl.POINTS, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+
+ if (!sglrGLContext.isExtensionSupported(gl, 'EXT_geometry_shader')) {// gl.EXT_geometry_shader removes error
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is active and not paused.');
+ /** @type{Array<string>} */ var tfVarying = ['gl_Position'];
+
+ buf = gl.createBuffer();
+ tfID = gl.createTransformFeedback();
+
+ gl.useProgram (program.getProgram());
+ gl.transformFeedbackVaryings (program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram (program.getProgram());
+ gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, tfID);
+ gl.bindBuffer (gl.TRANSFORM_FEEDBACK_BUFFER, buf);
+ gl.bufferData (gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
+ gl.bindBufferBase (gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+ gl.beginTransformFeedback (gl.POINTS);
+ this.expectError (gl.NO_ERROR);
+
+ gl.drawRangeElements (gl.POINTS, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError (gl.INVALID_OPERATION);
+
+ gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
+
+ gl.pauseTransformFeedback();
+ gl.drawRangeElements (gl.POINTS, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError (gl.NO_ERROR);
+
+ gl.endTransformFeedback ();
+ gl.deleteBuffer(buf);
+ gl.deleteTransformFeedback(tfID);
+ gl.deleteBuffer(bufElements);
+ this.expectError (gl.NO_ERROR);
+
+ }
+
+ gl.useProgram(null);
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_range_elements_invalid_program', 'Invalid gl.drawRangeElements() usage', gl, function() {
+ gl.useProgram(null);
+ /** @type{number} */ var vertices = 0;
+
+ /** @type{WebGLBuffer} */ var bufElements;
+ bufElements = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
+ gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
+
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if gl.useProgram(null) is set.');
+ gl.drawRangeElements(gl.POINTS, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_OPERATION);
+
+ gl.deleteBuffer(bufElements);
+
+ }));
+
+ testGroup.addChild(new es3fApiCase.ApiCaseCallback('draw_range_elements_incomplete_primitive', 'Invalid gl.drawRangeElements() usage', gl, function() {
+ /** @type{gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl,gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+ gl.useProgram(program.getProgram());
+ /** @type{WebGLFramebuffer} */ var fbo;
+ /** @type{WebGLBuffer} */ var buf;
+ /** @type{WebGLTransformFeedback} */ var tfID;
+ /** @type{number} */ var vertices = 0;
+
+ /** @type{WebGLBuffer} */ var bufElements;
+ bufElements = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufElements);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if mode is not an accepted value.');
+ gl.drawRangeElements(-1, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_ENUM is generated if type is not one of the accepted values.');
+ gl.drawRangeElements(gl.TRIANGLES, 0, 1, 0, -1, vertices);
+ this.expectError(gl.INVALID_ENUM);
+ gl.drawRangeElements(gl.TRIANGLES, 0, 1, 0, gl.FLOAT, vertices);
+ this.expectError(gl.INVALID_ENUM);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if count is negative.');
+ gl.drawRangeElements(gl.TRIANGLES, 0, 1, -1, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_VALUE is generated if end < start.');
+ gl.drawRangeElements(gl.TRIANGLES, 1, 0, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_VALUE);
+
+ bufferedLogToConsole('gl.INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.');
+ fbo = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+ gl.drawRangeElements(gl.TRIANGLES, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError(gl.INVALID_FRAMEBUFFER_OPERATION);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.deleteFramebuffer(fbo);
+
+ if (!sglrGLContext.isExtensionSupported(gl, 'EXT_geometry_shader')) {// gl.EXT_geometry_shader removes error
+ bufferedLogToConsole('gl.INVALID_OPERATION is generated if transform feedback is active and not paused.');
+ /** @type{Array<string>} */ var tfVarying = ['gl_Position'];
+
+ buf = gl.createBuffer();
+ tfID = gl.createTransformFeedback();
+
+ gl.useProgram (program.getProgram());
+ gl.transformFeedbackVaryings (program.getProgram(), tfVarying, gl.INTERLEAVED_ATTRIBS);
+ gl.linkProgram (program.getProgram());
+ gl.bindTransformFeedback (gl.TRANSFORM_FEEDBACK, tfID);
+ gl.bindBuffer (gl.TRANSFORM_FEEDBACK_BUFFER, buf);
+ gl.bufferData (gl.TRANSFORM_FEEDBACK_BUFFER, 32, gl.DYNAMIC_DRAW);
+ gl.bindBufferBase (gl.TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+ gl.beginTransformFeedback (gl.TRIANGLES);
+ this.expectError (gl.NO_ERROR);
+
+ gl.drawRangeElements (gl.TRIANGLES, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError (gl.INVALID_OPERATION);
+
+ gl.bufferData (gl.ELEMENT_ARRAY_BUFFER, 32, gl.STATIC_DRAW);
+
+ gl.pauseTransformFeedback();
+ gl.drawRangeElements (gl.TRIANGLES, 0, 1, 0, gl.UNSIGNED_BYTE, vertices);
+ this.expectError (gl.NO_ERROR);
+
+ gl.endTransformFeedback ();
+ gl.deleteBuffer(buf);
+ gl.deleteTransformFeedback(tfID);
+ gl.deleteBuffer(bufElements);
+ this.expectError (gl.NO_ERROR);
+
+ }
+
+ gl.useProgram(null);
+ }));
+ };
+
+ /**
+ * @param {WebGL2RenderingContext} gl
+ */
+ es3fNegativeVertexArrayApiTests.run = function(gl) {
+ var testName = 'vertex_array';
+ var testDescription = 'Negative Vertex Array API Cases';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.testCases = tcuTestCase.newTest(testName, testDescription, null);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+ try {
+ es3fNegativeVertexArrayApiTests.init(gl);
+ tcuTestCase.runner.runCallback(tcuTestCase.runTestCases);
+ } catch (err) {
+ bufferedLogToConsole(err);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fOcclusionQueryTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fOcclusionQueryTests.js
new file mode 100644
index 0000000000..8549d657bd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fOcclusionQueryTests.js
@@ -0,0 +1,511 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fOcclusionQueryTests');
+goog.require('framework.common.tcuLogImage');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluShaderProgram');
+
+goog.scope(function() {
+var es3fOcclusionQueryTests = functional.gles3.es3fOcclusionQueryTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var tcuLogImage = framework.common.tcuLogImage;
+var tcuSurface = framework.common.tcuSurface;
+var deRandom = framework.delibs.debase.deRandom;
+var deString = framework.delibs.debase.deString;
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+/** @const */ var DEPTH_WRITE_COLOR = [0, 0, 1, 1];
+/** @const */ var DEPTH_CLEAR_COLOR = [0, 0.5, 0.8, 1];
+/** @const */ var STENCIL_WRITE_COLOR = [0, 1, 0, 1];
+/** @const */ var STENCIL_CLEAR_COLOR = [0, 0.8, 0.5, 1];
+/** @const */ var TARGET_COLOR = [1, 0, 0, 1];
+/** @const */ var ELEMENTS_PER_VERTEX = 4;
+/** @const */ var NUM_CASE_ITERATIONS = 10;
+
+// Constants to tweak visible/invisible case probability balance.
+
+/** @const */ var DEPTH_CLEAR_OFFSET = 100;
+/** @const */ var STENCIL_CLEAR_OFFSET = 100;
+/** @const */ var SCISSOR_OFFSET = 100;
+/** @const */ var SCISSOR_MINSIZE = 250;
+
+/** @const */ var OCCLUDER_SCISSOR = (1 << 0);
+/** @const */ var OCCLUDER_DEPTH_WRITE = (1 << 1);
+/** @const */ var OCCLUDER_DEPTH_CLEAR = (1 << 2);
+/** @const */ var OCCLUDER_STENCIL_WRITE = (1 << 3);
+/** @const */ var OCCLUDER_STENCIL_CLEAR = (1 << 4);
+
+/**
+ * @enum
+ */
+es3fOcclusionQueryTests.State = {
+ DRAW: 0,
+ VERIFY: 1,
+ FINISH: 2
+};
+
+/* Maximum time to wait for query result (in seconds) */
+/** @const */ var MAX_VERIFY_WAIT = 5;
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+es3fOcclusionQueryTests.OcclusionQueryCase = function(name, description, numOccluderDraws, numOccludersPerDraw, occluderSize, numTargetDraws, numTargetsPerDraw, targetSize, queryMode, occluderTypes) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ this.m_numOccluderDraws = numOccluderDraws;
+ this.m_numOccludersPerDraw = numOccludersPerDraw;
+ this.m_occluderSize = occluderSize;
+ this.m_numTargetDraws = numTargetDraws;
+ this.m_numTargetsPerDraw = numTargetsPerDraw;
+ this.m_targetSize = targetSize;
+ this.m_queryMode = queryMode;
+ this.m_occluderTypes = occluderTypes;
+ this.m_program = null;
+ this.m_iterNdx = 0;
+ this.m_rnd = new deRandom.Random(deString.deStringHash(name));
+ this.m_state = es3fOcclusionQueryTests.State.DRAW;
+ /** @type {WebGLQuery} */ this.m_query;
+};
+
+setParentClass(es3fOcclusionQueryTests.OcclusionQueryCase, tcuTestCase.DeqpTest);
+
+es3fOcclusionQueryTests.OcclusionQueryCase.prototype.generateVertices = function(width, height, primitiveCount, verticesPerPrimitive, rnd, primitiveSize, minZ, maxZ) {
+ var dst = [];
+ var w = width / 2;
+ var h = height / 2;
+ var s = primitiveSize / 2;
+
+ var vertexCount = verticesPerPrimitive * primitiveCount;
+
+ // First loop gets a random point inside unit square
+ for (var i = 0; i < vertexCount; i += 3) {
+ var rndX = rnd.getFloat(-w, w);
+ var rndY = rnd.getFloat(-h, h);
+
+ // Second loop gets 3 random points within given distance s from (rndX, rndY)
+ for (var j = 0; j < verticesPerPrimitive; j++) {
+ var offset = (i + j) * ELEMENTS_PER_VERTEX;
+ dst[offset] = rndX + rnd.getFloat(-s, s); // x
+ dst[offset + 1] = rndY + rnd.getFloat(-s, s); // y
+ dst[offset + 2] = rnd.getFloat(minZ, maxZ); // z
+ dst[offset + 3] = 1; // w
+ }
+ }
+ return dst;
+};
+
+es3fOcclusionQueryTests.OcclusionQueryCase.prototype.init = function() {
+ var vertShaderSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) in mediump vec4 a_position;\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ '}\n';
+
+ var fragShaderSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 dEQP_FragColor;\n' +
+ 'uniform mediump vec4 u_color;\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' mediump float depth_gradient = gl_FragCoord.z;\n' +
+ ' mediump float bias = 0.1;\n' +
+ ' dEQP_FragColor = vec4(u_color.xyz * (depth_gradient + bias), 1);\n' +
+ '}\n';
+
+ this.m_program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertShaderSource, fragShaderSource));
+
+ if (!this.m_program.isOk())
+ testFailedOptions('Failed to compile program', true);
+
+ this.m_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.m_buffer);
+ gl.vertexAttribPointer(0, ELEMENTS_PER_VERTEX, gl.FLOAT, false, 0, 0);
+};
+
+es3fOcclusionQueryTests.OcclusionQueryCase.prototype.draw = function() {
+ var colorUnif = gl.getUniformLocation(this.m_program.getProgram(), 'u_color');
+
+ var targetW = gl.drawingBufferWidth;
+ var targetH = gl.drawingBufferHeight;
+
+ bufferedLogToConsole('Case iteration ' + (this.m_iterNdx + 1) + ' / ' + NUM_CASE_ITERATIONS);
+ bufferedLogToConsole('Parameters:\n' +
+ '- ' + this.m_numOccluderDraws + ' occluder draws, ' + this.m_numOccludersPerDraw + ' primitive writes per draw,\n' +
+ '- ' + this.m_numTargetDraws + ' target draws, ' + this.m_numTargetsPerDraw + ' targets per draw\n');
+
+ gl.clearColor(0, 0, 0, 1);
+ gl.clearDepth(1);
+ gl.clearStencil(0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ gl.useProgram(this.m_program.getProgram());
+ gl.enableVertexAttribArray(0);
+
+ // Draw occluders
+
+ var occOptions = [];
+ if (this.m_occluderTypes & OCCLUDER_DEPTH_WRITE) occOptions.push(OCCLUDER_DEPTH_WRITE);
+ if (this.m_occluderTypes & OCCLUDER_DEPTH_CLEAR) occOptions.push(OCCLUDER_DEPTH_CLEAR);
+ if (this.m_occluderTypes & OCCLUDER_STENCIL_WRITE) occOptions.push(OCCLUDER_STENCIL_WRITE);
+ if (this.m_occluderTypes & OCCLUDER_STENCIL_CLEAR) occOptions.push(OCCLUDER_STENCIL_CLEAR);
+
+ for (var i = 0; i < this.m_numOccluderDraws; i++) {
+ if (occOptions.length == 0)
+ break;
+
+ var type = occOptions[this.m_rnd.getInt(0, occOptions.length - 1)]; // Choosing a random occluder type from available options
+
+ switch (type) {
+ case OCCLUDER_DEPTH_WRITE:
+ bufferedLogToConsole('Occluder draw ' + (i + 1) + ' / ' + this.m_numOccluderDraws + ' : ' + 'Depth write');
+
+ var occluderVertices = this.generateVertices(2, 2, this.m_numOccludersPerDraw, 3, this.m_rnd, this.m_occluderSize, 0, 0.6); // Generate vertices for occluding primitives
+
+ gl.enable(gl.DEPTH_TEST);
+ gl.uniform4f(colorUnif, DEPTH_WRITE_COLOR[0], DEPTH_WRITE_COLOR[1], DEPTH_WRITE_COLOR[2], DEPTH_WRITE_COLOR[3]);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(occluderVertices), gl.STATIC_DRAW);
+ gl.drawArrays(gl.TRIANGLES, 0, 3 * this.m_numOccludersPerDraw);
+ gl.disable(gl.DEPTH_TEST);
+
+ break;
+
+ case OCCLUDER_DEPTH_CLEAR: {
+ var scissorBoxX = this.m_rnd.getInt(-DEPTH_CLEAR_OFFSET, targetW);
+ var scissorBoxY = this.m_rnd.getInt(-DEPTH_CLEAR_OFFSET, targetH);
+ var scissorBoxW = this.m_rnd.getInt(DEPTH_CLEAR_OFFSET, targetW + DEPTH_CLEAR_OFFSET);
+ var scissorBoxH = this.m_rnd.getInt(DEPTH_CLEAR_OFFSET, targetH + DEPTH_CLEAR_OFFSET);
+
+ bufferedLogToConsole('Occluder draw ' + (i + 1) + ' / ' + this.m_numOccluderDraws + ' : ' + 'Depth clear');
+ bufferedLogToConsole('Depth-clearing box drawn at ' +
+ '(' + scissorBoxX + ', ' + scissorBoxY + ')' +
+ ', width = ' + scissorBoxW + ', height = ' + scissorBoxH + '.');
+
+ gl.enable(gl.SCISSOR_TEST);
+ gl.scissor(scissorBoxX, scissorBoxY, scissorBoxW, scissorBoxH);
+ gl.clearDepth(0);
+ gl.clearColor(DEPTH_CLEAR_COLOR[0], DEPTH_CLEAR_COLOR[1], DEPTH_CLEAR_COLOR[2], DEPTH_CLEAR_COLOR[3]);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.disable(gl.SCISSOR_TEST);
+
+ break;
+ }
+
+ case OCCLUDER_STENCIL_WRITE:
+ bufferedLogToConsole('Occluder draw ' + (i + 1) + ' / ' + this.m_numOccluderDraws + ' : ' + 'Stencil write');
+
+ occluderVertices = this.generateVertices(2, 2, this.m_numOccludersPerDraw, 3, this.m_rnd, this.m_occluderSize, 0, 0.6);
+
+ gl.stencilFunc(gl.ALWAYS, 1, 0xFF);
+ gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
+
+ gl.enable(gl.STENCIL_TEST);
+ gl.uniform4f(colorUnif, STENCIL_WRITE_COLOR[0], STENCIL_WRITE_COLOR[1], STENCIL_WRITE_COLOR[2], STENCIL_WRITE_COLOR[3]);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(occluderVertices), gl.STATIC_DRAW);
+ gl.drawArrays(gl.TRIANGLES, 0, 3 * this.m_numOccludersPerDraw);
+ gl.disable(gl.STENCIL_TEST);
+
+ break;
+
+ case OCCLUDER_STENCIL_CLEAR: {
+ var scissorBoxX = this.m_rnd.getInt(-STENCIL_CLEAR_OFFSET, targetW);
+ var scissorBoxY = this.m_rnd.getInt(-STENCIL_CLEAR_OFFSET, targetH);
+ var scissorBoxW = this.m_rnd.getInt(STENCIL_CLEAR_OFFSET, targetW + STENCIL_CLEAR_OFFSET);
+ var scissorBoxH = this.m_rnd.getInt(STENCIL_CLEAR_OFFSET, targetH + STENCIL_CLEAR_OFFSET);
+
+ bufferedLogToConsole('Occluder draw ' + (i + 1) + ' / ' + this.m_numOccluderDraws + ' : ' + 'Stencil clear');
+ bufferedLogToConsole('Stencil-clearing box drawn at ' +
+ '(' + scissorBoxX + ', ' + scissorBoxY + ')' +
+ ', width = ' + scissorBoxW + ', height = ' + scissorBoxH + '.');
+
+ gl.enable(gl.SCISSOR_TEST);
+ gl.scissor(scissorBoxX, scissorBoxY, scissorBoxW, scissorBoxH);
+ gl.clearStencil(1);
+ gl.clearColor(STENCIL_CLEAR_COLOR[0], STENCIL_CLEAR_COLOR[1], STENCIL_CLEAR_COLOR[2], STENCIL_CLEAR_COLOR[3]);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ gl.disable(gl.SCISSOR_TEST);
+
+ break;
+ }
+
+ default:
+ throw new Error('Invalid occluder type: ' + type);
+ }
+ }
+
+ if (this.m_occluderTypes & OCCLUDER_SCISSOR) {
+ var scissorBoxX = this.m_rnd.getInt(-SCISSOR_OFFSET, targetW - SCISSOR_OFFSET);
+ var scissorBoxY = this.m_rnd.getInt(-SCISSOR_OFFSET, targetH - SCISSOR_OFFSET);
+ var scissorBoxW = this.m_rnd.getInt(SCISSOR_MINSIZE, targetW + SCISSOR_OFFSET);
+ var scissorBoxH = this.m_rnd.getInt(SCISSOR_MINSIZE, targetH + SCISSOR_OFFSET);
+
+ bufferedLogToConsole('Scissor box drawn at ' +
+ '(' + scissorBoxX + ', ' + scissorBoxY + ')' +
+ ', width = ' + scissorBoxW + ', height = ' + scissorBoxH + '.');
+
+ gl.enable(gl.SCISSOR_TEST);
+ gl.scissor(scissorBoxX, scissorBoxY, scissorBoxW, scissorBoxH);
+ }
+
+ this.m_query = gl.createQuery();
+ gl.beginQuery(this.m_queryMode, this.m_query);
+
+ // Draw target primitives
+
+ gl.enable(gl.DEPTH_TEST);
+ gl.enable(gl.STENCIL_TEST);
+ gl.stencilFunc(gl.EQUAL, 0, 0xFF);
+
+ for (var i = 0; i < this.m_numTargetDraws; i++) {
+ var targetVertices = this.generateVertices(2, 2, this.m_numTargetsPerDraw, 3, this.m_rnd, this.m_targetSize, 0.4, 1); // Generate vertices for target primitives
+
+ if (targetVertices.length > 0) {
+ gl.uniform4f(colorUnif, TARGET_COLOR[0], TARGET_COLOR[1], TARGET_COLOR[2], TARGET_COLOR[3]);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(targetVertices), gl.STATIC_DRAW);
+ gl.drawArrays(gl.TRIANGLES, 0, 3 * this.m_numTargetsPerDraw);
+ }
+ }
+
+ gl.endQuery(this.m_queryMode);
+ gl.disable(gl.SCISSOR_TEST);
+ gl.disable(gl.STENCIL_TEST);
+ gl.disable(gl.DEPTH_TEST);
+ this.m_state = es3fOcclusionQueryTests.State.VERIFY;
+};
+
+es3fOcclusionQueryTests.OcclusionQueryCase.prototype.verify = function() {
+ // Check that query result is available.
+ var resultAvailable = /** @type {boolean} */ (gl.getQueryParameter(this.m_query, gl.QUERY_RESULT_AVAILABLE));
+ if (!resultAvailable) {
+ if (!this.m_verifyStart)
+ this.m_verifyStart = new Date();
+ else {
+ var current = new Date();
+ var elapsedTime = 0.001 * (current.getTime() - this.m_verifyStart.getTime());
+ if (elapsedTime > MAX_VERIFY_WAIT) {
+ testFailed('Query result not available after ' + elapsedTime + ' seconds.');
+ this.m_state = es3fOcclusionQueryTests.State.FINISH;
+ }
+ }
+ return;
+ }
+
+ // Read query result.
+ var result = /** @type {number} */ (gl.getQueryParameter(this.m_query, gl.QUERY_RESULT));
+ var queryResult = (result > 0);
+
+ gl.deleteQuery(this.m_query);
+
+ // Read pixel data
+
+ var pixels = new tcuSurface.Surface();
+ pixels.readViewport(gl);
+ var colorReadResult = false;
+ var width = pixels.getWidth();
+ var height = pixels.getHeight();
+
+ for (var y = 0; y < height; y++) {
+ for (var x = 0; x < width; x++) {
+ if (pixels.getPixel(x, y)[0] != 0) {
+ colorReadResult = true;
+ break;
+ }
+ }
+ if (colorReadResult) break;
+ }
+
+ var message = 'Occlusion query result: Target ' + (queryResult ? 'visible' : 'invisible') + '. ' +
+ 'Framebuffer read result: Target ' + (colorReadResult ? 'visible' : 'invisible');
+
+ var testOk = false;
+ if (this.m_queryMode == gl.ANY_SAMPLES_PASSED_CONSERVATIVE) {
+ if (queryResult || colorReadResult)
+ testOk = queryResult; // Allow conservative occlusion query to return false positives.
+ else
+ testOk = queryResult == colorReadResult;
+ } else
+ testOk = (queryResult == colorReadResult);
+
+ if (!testOk) {
+ tcuLogImage.logImage('Result image', 'Result image', pixels.getAccess());
+ testFailed(message);
+ this.m_state = es3fOcclusionQueryTests.State.FINISH;
+ return;
+ }
+
+ bufferedLogToConsole(message);
+ bufferedLogToConsole('Case passed!');
+
+ if (++this.m_iterNdx < NUM_CASE_ITERATIONS) {
+ this.m_state = es3fOcclusionQueryTests.State.DRAW
+ } else {
+ this.m_state = es3fOcclusionQueryTests.State.FINISH;
+ testPassed();
+ }
+};
+
+
+es3fOcclusionQueryTests.OcclusionQueryCase.prototype.iterate = function() {
+ switch(this.m_state) {
+ case es3fOcclusionQueryTests.State.DRAW:
+ this.draw();
+ break;
+ case es3fOcclusionQueryTests.State.VERIFY:
+ this.verify();
+ break;
+ case es3fOcclusionQueryTests.State.FINISH:
+ return tcuTestCase.IterateResult.STOP;
+ default:
+ throw new Error('Invalid state: ' + this.m_state);
+ }
+
+ return tcuTestCase.IterateResult.CONTINUE;
+};
+
+/**
+* @constructor
+* @extends {tcuTestCase.DeqpTest}
+*/
+es3fOcclusionQueryTests.OcclusionQueryTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'occlusion_query', 'Occlusion Query Tests');
+};
+
+es3fOcclusionQueryTests.OcclusionQueryTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fOcclusionQueryTests.OcclusionQueryTests.prototype.constructor = es3fOcclusionQueryTests.OcclusionQueryTests;
+
+es3fOcclusionQueryTests.OcclusionQueryTests.prototype.init = function() {
+ // Strict occlusion query cases
+
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor', 'scissor', 1, 10, 1.6, 1, 1, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write', 'depth_write', 8, 10, 1.6, 1, 7, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_clear', 'depth_clear', 5, 10, 1.6, 1, 5, 0.2, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('stencil_write', 'stencil_write', 8, 10, 2.0, 1, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('stencil_clear', 'stencil_clear', 5, 10, 2.0, 1, 3, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_STENCIL_CLEAR));
+
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_write', 'scissor_depth_write', 5, 10, 1.6, 2, 5, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_clear', 'scissor_depth_clear', 7, 10, 1.6, 2, 5, 1.0, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_stencil_write', 'scissor_stencil_write', 4, 10, 1.6, 2, 5, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_stencil_clear', 'scissor_stencil_clear', 4, 10, 1.6, 2, 5, 1.0, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write_depth_clear', 'depth_write_depth_clear', 7, 10, 1.6, 1, 5, 0.2, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write_stencil_write', 'depth_write_stencil_write', 8, 10, 1.6, 1, 5, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write_stencil_clear', 'depth_write_stencil_clear', 8, 10, 1.6, 1, 5, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_clear_stencil_write', 'depth_clear_stencil_write', 8, 10, 1.6, 1, 5, 0.3, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_clear_stencil_clear', 'depth_clear_stencil_clear', 12, 10, 1.6, 1, 5, 0.2, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('stencil_write_stencil_clear', 'stencil_write_stencil_clear', 5, 10, 2.0, 1, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_write_depth_clear', 'scissor_depth_write_depth_clear', 5, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_write_stencil_write', 'scissor_depth_write_stencil_write', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_write_stencil_clear', 'scissor_depth_write_stencil_clear', 6, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_clear_stencil_write', 'scissor_depth_clear_stencil_write', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_clear_stencil_clear', 'scissor_depth_clear_stencil_clear', 5, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_stencil_write_stencil_clear', 'scissor_stencil_write_stencil_clear', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write_depth_clear_stencil_write', 'depth_write_depth_clear_stencil_write', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write_depth_clear_stencil_clear', 'depth_write_depth_clear_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write_stencil_write_stencil_clear', 'depth_write_stencil_write_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_clear_stencil_write_stencil_clear', 'depth_clear_stencil_write_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_write_depth_clear_stencil_write', 'scissor_depth_write_depth_clear_stencil_write', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_write_depth_clear_stencil_clear', 'scissor_depth_write_depth_clear_stencil_clear', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_write_stencil_write_stencil_clear', 'scissor_depth_write_stencil_write_stencil_clear', 5, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('scissor_depth_clear_stencil_write_stencil_clear', 'scissor_depth_clear_stencil_write_stencil_clear', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('depth_write_depth_clear_stencil_write_stencil_clear', 'depth_write_depth_clear_stencil_write_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('all_occluders', 'all_occluders', 7, 10, 1.6, 3, 5, 0.6, gl.ANY_SAMPLES_PASSED, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+
+ // Conservative occlusion query cases
+
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor', 'conservative_scissor', 1, 10, 1.6, 1, 1, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write', 'conservative_depth_write', 8, 10, 1.6, 1, 7, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_clear', 'conservative_depth_clear', 5, 10, 1.6, 1, 5, 0.2, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_stencil_write', 'conservative_stencil_write', 8, 10, 2.0, 1, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_stencil_clear', 'conservative_stencil_clear', 5, 10, 2.0, 1, 3, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_STENCIL_CLEAR));
+
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_write', 'conservative_scissor_depth_write', 5, 10, 1.6, 2, 5, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_clear', 'conservative_scissor_depth_clear', 7, 10, 1.6, 2, 5, 1.0, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_stencil_write', 'conservative_scissor_stencil_write', 4, 10, 1.6, 2, 5, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_stencil_clear', 'conservative_scissor_stencil_clear', 4, 10, 1.6, 2, 5, 1.0, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write_depth_clear', 'conservative_depth_write_depth_clear', 7, 10, 1.6, 1, 5, 0.2, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write_stencil_write', 'conservative_depth_write_stencil_write', 8, 10, 1.6, 1, 5, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write_stencil_clear', 'conservative_depth_write_stencil_clear', 8, 10, 1.6, 1, 5, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_clear_stencil_write', 'conservative_depth_clear_stencil_write', 8, 10, 1.6, 1, 5, 0.3, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_clear_stencil_clear', 'conservative_depth_clear_stencil_clear', 12, 10, 1.6, 1, 5, 0.2, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_stencil_write_stencil_clear', 'conservative_stencil_write_stencil_clear', 5, 10, 2.0, 1, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_write_depth_clear', 'conservative_scissor_depth_write_depth_clear', 5, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_write_stencil_write', 'conservative_scissor_depth_write_stencil_write', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_write_stencil_clear', 'conservative_scissor_depth_write_stencil_clear', 6, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_clear_stencil_write', 'conservative_scissor_depth_clear_stencil_write', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_clear_stencil_clear', 'conservative_scissor_depth_clear_stencil_clear', 5, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_stencil_write_stencil_clear', 'conservative_scissor_stencil_write_stencil_clear', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write_depth_clear_stencil_write', 'conservative_depth_write_depth_clear_stencil_write', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write_depth_clear_stencil_clear', 'conservative_depth_write_depth_clear_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write_stencil_write_stencil_clear', 'conservative_depth_write_stencil_write_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_clear_stencil_write_stencil_clear', 'conservative_depth_clear_stencil_write_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_write_depth_clear_stencil_write', 'conservative_scissor_depth_write_depth_clear_stencil_write', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_write_depth_clear_stencil_clear', 'conservative_scissor_depth_write_depth_clear_stencil_clear', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_write_stencil_write_stencil_clear', 'conservative_scissor_depth_write_stencil_write_stencil_clear', 5, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_scissor_depth_clear_stencil_write_stencil_clear', 'conservative_scissor_depth_clear_stencil_write_stencil_clear', 4, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_depth_write_depth_clear_stencil_write_stencil_clear', 'conservative_depth_write_depth_clear_stencil_write_stencil_clear', 7, 10, 1.6, 2, 5, 0.4, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+
+ this.addChild(new es3fOcclusionQueryTests.OcclusionQueryCase('conservative_all_occluders', 'conservative_all_occluders', 7, 10, 1.6, 3, 5, 0.6, gl.ANY_SAMPLES_PASSED_CONSERVATIVE, OCCLUDER_SCISSOR | OCCLUDER_DEPTH_WRITE | OCCLUDER_DEPTH_CLEAR | OCCLUDER_STENCIL_WRITE | OCCLUDER_STENCIL_CLEAR));
+
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fOcclusionQueryTests.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fOcclusionQueryTests.OcclusionQueryTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fOcclusionQueryTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fPixelBufferObjectTest.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fPixelBufferObjectTest.js
new file mode 100644
index 0000000000..ac577193aa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fPixelBufferObjectTest.js
@@ -0,0 +1,585 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+'use strict';
+goog.provide('functional.gles3.es3fPixelBufferObjectTest');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluTextureUtil');
+
+goog.scope(function() {
+
+var es3fPixelBufferObjectTest = functional.gles3.es3fPixelBufferObjectTest;
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+var tcuTestCase = framework.common.tcuTestCase;
+var deRandom = framework.delibs.debase.deRandom;
+var deString = framework.delibs.debase.deString;
+var tcuTextureUtil = framework.common.tcuTextureUtil;
+var tcuTexture = framework.common.tcuTexture;
+var gluTextureUtil = framework.opengl.gluTextureUtil;
+var tcuImageCompare = framework.common.tcuImageCompare;
+
+ var DE_ASSERT = function(x) {
+ if (!x)
+ throw new Error('Assert failed');
+ };
+
+ es3fPixelBufferObjectTest.DE_STATIC_ASSERT = function(expression) {
+ if (!expression) throw new Error('Assert failed');
+ };
+
+ /** @enum */
+ es3fPixelBufferObjectTest.FramebufferType = {
+ FRAMEBUFFERTYPE_NATIVE: 0,
+ FRAMEBUFFERTYPE_RENDERBUFFER: 1
+ };
+
+ /**
+ * @constructor
+ * @struct
+ */
+ es3fPixelBufferObjectTest.TestSpec = function() { // This is originaly a struct
+ this.name = '';
+ this.description = '';
+ this.useColorClear = false;
+ this.renderTriangles = false;
+ /** @type {es3fPixelBufferObjectTest.FramebufferType} */ this.framebufferType;
+ /** @type {number} */ this.renderbufferFormat;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {es3fPixelBufferObjectTest.TestSpec} spec
+ */
+ es3fPixelBufferObjectTest.ReadPixelsTest = function(spec) {
+ tcuTestCase.DeqpTest.call(this, spec.name, spec.description);
+ this.m_random = new deRandom.Random(deString.deStringHash(spec.name));
+ this.m_program = null;
+ this.m_framebuffeType = spec.framebufferType;
+ this.m_renderbufferFormat = spec.renderbufferFormat;
+ this.m_texChannelClass = undefined;
+ this.m_useColorClears = spec.useColorClear;
+ this.m_renderTriangles = spec.renderTriangles;
+ this.m_colorScale = 1.0;
+
+ if (this.m_framebuffeType === es3fPixelBufferObjectTest.FramebufferType.FRAMEBUFFERTYPE_NATIVE) {
+ this.m_colorScale = 1.0;
+ } else if (this.m_framebuffeType === es3fPixelBufferObjectTest.FramebufferType.FRAMEBUFFERTYPE_RENDERBUFFER) {
+ this.m_texChannelClass = tcuTexture.getTextureChannelClass(gluTextureUtil.mapGLInternalFormat(spec.renderbufferFormat).type);
+ switch (this.m_texChannelClass) {
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
+ this.m_colorScale = 1.0;
+ break;
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ this.m_colorScale = 100.0;
+ break;
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
+ this.m_colorScale = 100.0;
+ break;
+ case tcuTexture.TextureChannelClass.FLOATING_POINT:
+ this.m_colorScale = 100.0;
+ break;
+ default:
+ DE_ASSERT(false);
+ }
+ } else {
+ DE_ASSERT(false);
+ }
+ };
+
+ es3fPixelBufferObjectTest.ReadPixelsTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fPixelBufferObjectTest.ReadPixelsTest.prototype.constructor = es3fPixelBufferObjectTest.ReadPixelsTest;
+
+ es3fPixelBufferObjectTest.ReadPixelsTest.prototype.init = function() {
+ var outtype = '';
+
+ if (this.m_framebuffeType === es3fPixelBufferObjectTest.FramebufferType.FRAMEBUFFERTYPE_NATIVE)
+ outtype = 'vec4';
+ else if (this.m_framebuffeType === es3fPixelBufferObjectTest.FramebufferType.FRAMEBUFFERTYPE_RENDERBUFFER) {
+ switch (this.m_texChannelClass) {
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
+ outtype = 'vec4';
+ break;
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ outtype = 'ivec4';
+ break;
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
+ outtype = 'uvec4';
+ break;
+ case tcuTexture.TextureChannelClass.FLOATING_POINT:
+ outtype = 'vec4';
+ break;
+ default:
+ DE_ASSERT(false);
+ }
+ } else
+ DE_ASSERT(false);
+
+ /** @type {string} */ var vertexShaderSource =
+ '#version 300 es\n' +
+ 'in mediump vec3 a_position;\n' +
+ 'in mediump vec4 a_color;\n' +
+ 'uniform mediump float u_colorScale;\n' +
+ 'out mediump vec4 v_color;\n' +
+ 'void main(void)\n' +
+ ' {\n' +
+ '\tgl_Position = vec4(a_position, 1.0);\n' +
+ '\tv_color = u_colorScale * a_color;\n' +
+ '}';
+
+ /** @type {string} */ var fragmentShaderSource =
+ '#version 300 es\n' +
+ 'in mediump vec4 v_color;\n' +
+ 'layout (location = 0) out mediump ' +
+ outtype +
+ ' o_color;\n' +
+ 'void main(void)\n' +
+ ' {\n' +
+ '\to_color = ' +
+ outtype +
+ '(v_color);\n' +
+ '}';
+
+ this.m_program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
+
+ if (!this.m_program.isOk())
+ throw new Error('Compile failed. Program not created');
+
+ };
+
+ /**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @param {Array<number>} c
+ */
+ es3fPixelBufferObjectTest.ReadPixelsTest.prototype.renderTriangle = function(a, b, c) {
+
+ var positions = new Float32Array(36);
+
+ positions[0] = a[0];
+ positions[1] = a[1];
+ positions[2] = a[2];
+
+ positions[3] = b[0];
+ positions[4] = b[1];
+ positions[5] = b[2];
+
+ positions[6] = c[0];
+ positions[7] = c[1];
+ positions[8] = c[2];
+
+ var colors = new Float32Array([
+ 1.0, 0.0, 0.0, 1.0,
+ 0.0, 1.0, 0.0, 1.0,
+ 0.0, 0.0, 1.0, 1.0]);
+
+ gl.useProgram(this.m_program.getProgram());
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'useProgram failed ', false, true);
+
+ /** @type {WebGLUniformLocation} */ var colorScaleLoc = gl.getUniformLocation(this.m_program.getProgram(), 'u_colorScale');
+ assertMsgOptions(colorScaleLoc != -1, 'Could not find u_colorScale ', false, true);
+
+ gl.uniform1f(colorScaleLoc, this.m_colorScale);
+
+ /** @type {number} */ var coordLoc = gl.getAttribLocation(this.m_program.getProgram(), 'a_position');
+ assertMsgOptions(coordLoc != -1, 'Could not find a_position ', false, true);
+
+ /** @type {number} */ var colorLoc = gl.getAttribLocation(this.m_program.getProgram(), 'a_color');
+ assertMsgOptions(colorLoc != -1, 'Could not find a_color ', false, true);
+
+ gl.enableVertexAttribArray(colorLoc);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'enableVertexAttribArray failed ', false, true);
+ gl.enableVertexAttribArray(coordLoc);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'enableVertexAttribArray failed ', false, true);
+
+ var pos = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, pos);
+ gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(coordLoc, 3, gl.FLOAT, false, 0, 0);
+
+ var c = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, c);
+ gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, 0, 0);
+
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+
+ gl.disableVertexAttribArray(colorLoc);
+ gl.disableVertexAttribArray(coordLoc);
+ };
+
+ /**
+ * @param {number} r
+ * @param {number} g
+ * @param {number} b
+ * @param {number} a
+ */
+
+ es3fPixelBufferObjectTest.ReadPixelsTest.prototype.clearColor = function(r, g, b, a) {
+ if (this.m_framebuffeType == es3fPixelBufferObjectTest.FramebufferType.FRAMEBUFFERTYPE_NATIVE) {
+ gl.clearColor(r, g, b, a);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ } else if (this.m_framebuffeType == es3fPixelBufferObjectTest.FramebufferType.FRAMEBUFFERTYPE_RENDERBUFFER) {
+ switch (this.m_texChannelClass) {
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
+ gl.clearColor(r, g, b, a);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ break;
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ gl.clearBufferiv(gl.COLOR, 0, new Int32Array([r, g, b, a]));
+ break;
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
+ gl.clearBufferuiv(gl.COLOR, 0, new Uint32Array([r, g, b, a]));
+ break;
+ case tcuTexture.TextureChannelClass.FLOATING_POINT:
+ gl.clearBufferfv(gl.COLOR, 0, new Float32Array([r, g, b, a]));
+ break;
+ default:
+ DE_ASSERT(false);
+ }
+ } else
+ DE_ASSERT(false);
+
+ };
+
+ es3fPixelBufferObjectTest.ReadPixelsTest.prototype.iterate = function() {
+ var width = gl.drawingBufferWidth;
+ var height = gl.drawingBufferHeight;
+
+ var framebuffer = null;
+ var renderbuffer = null;
+
+ switch (this.m_framebuffeType) {
+ case es3fPixelBufferObjectTest.FramebufferType.FRAMEBUFFERTYPE_NATIVE:
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
+ break;
+ case es3fPixelBufferObjectTest.FramebufferType.FRAMEBUFFERTYPE_RENDERBUFFER:
+ framebuffer = gl.createFramebuffer();
+ renderbuffer = gl.createRenderbuffer();
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, this.m_renderbufferFormat, width, height);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbuffer);
+ break;
+ }
+
+ this.clearColor(this.m_colorScale * 0.4, this.m_colorScale * 1.0, this.m_colorScale * 0.5, this.m_colorScale * 1.0);
+
+ if (this.m_useColorClears) {
+ /** @type {number} */ var maxClearCount = 10;
+ /** @type {number} */ var minClearCount = 6;
+ /** @type {number} */ var minClearSize = 15;
+
+ /** @type {number} */ var clearCount = this.m_random.getInt(minClearCount, maxClearCount);
+
+ for (var clearNdx = 0; clearNdx < clearCount; clearNdx++) {
+ /** @type {number} */ var clearX = this.m_random.getInt(0, width - minClearSize);
+ /** @type {number} */ var clearY = this.m_random.getInt(0, height - minClearSize);
+
+ /** @type {number} */ var clearWidth = this.m_random.getInt(minClearSize, width - clearX);
+ /** @type {number} */ var clearHeight = this.m_random.getInt(minClearSize, height - clearY);
+
+ /** @type {number} */ var clearRed = this.m_colorScale * this.m_random.getFloat();
+ /** @type {number} */ var clearGreen = this.m_colorScale * this.m_random.getFloat();
+ /** @type {number} */ var clearBlue = this.m_colorScale * this.m_random.getFloat();
+ /** @type {number} */ var clearAlpha = this.m_colorScale * (0.5 + 0.5 * this.m_random.getFloat());
+
+ gl.enable(gl.SCISSOR_TEST);
+ gl.scissor(clearX, clearY, clearWidth, clearHeight);
+
+ this.clearColor(clearRed, clearGreen, clearBlue, clearAlpha);
+ }
+
+ gl.disable(gl.SCISSOR_TEST);
+
+ }
+
+ if (this.m_renderTriangles) {
+ /** @type {number} */ var minTriangleCount = 4;
+ /** @type {number} */ var maxTriangleCount = 10;
+
+ /** @type {number} */ var triangleCount = this.m_random.getInt(minTriangleCount, maxTriangleCount);
+
+ for (var triangleNdx = 0; triangleNdx < triangleCount; triangleNdx++) {
+ /** @type {number} */ var x1 = 2.0 * this.m_random.getFloat() - 1.0;
+ /** @type {number} */ var y1 = 2.0 * this.m_random.getFloat() - 1.0;
+ /** @type {number} */ var z1 = 2.0 * this.m_random.getFloat() - 1.0;
+
+ /** @type {number} */ var x2 = 2.0 * this.m_random.getFloat() - 1.0;
+ /** @type {number} */ var y2 = 2.0 * this.m_random.getFloat() - 1.0;
+ /** @type {number} */ var z2 = 2.0 * this.m_random.getFloat() - 1.0;
+
+ /** @type {number} */ var x3 = 2.0 * this.m_random.getFloat() - 1.0;
+ /** @type {number} */ var y3 = 2.0 * this.m_random.getFloat() - 1.0;
+ /** @type {number} */ var z3 = 2.0 * this.m_random.getFloat() - 1.0;
+
+ this.renderTriangle([x1, y1, z1], [x2, y2, z2], [x3, y3, z3]);
+ }
+ }
+
+ /** @type {tcuTexture.TextureFormat} */ var readFormat;
+ /** @type {number} */ var readPixelsFormat;
+ /** @type {number} */ var readPixelsType;
+ /** @type {boolean} */ var floatCompare;
+
+ if (this.m_framebuffeType == es3fPixelBufferObjectTest.FramebufferType.FRAMEBUFFERTYPE_NATIVE) {
+ readFormat = gluTextureUtil.mapGLTransferFormat(gl.RGBA, gl.UNSIGNED_BYTE);
+ readPixelsFormat = gl.RGBA;
+ readPixelsType = gl.UNSIGNED_BYTE;
+ floatCompare = false;
+ } else if (this.m_framebuffeType == es3fPixelBufferObjectTest.FramebufferType.FRAMEBUFFERTYPE_RENDERBUFFER) {
+ switch (this.m_texChannelClass) {
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
+ readFormat = gluTextureUtil.mapGLTransferFormat(gl.RGBA, gl.UNSIGNED_BYTE);
+ readPixelsFormat = gl.RGBA;
+ readPixelsType = gl.UNSIGNED_BYTE;
+ floatCompare = true;
+ break;
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ readFormat = gluTextureUtil.mapGLTransferFormat(gl.RGBA_INTEGER, gl.INT);
+ readPixelsFormat = gl.RGBA_INTEGER;
+ readPixelsType = gl.INT;
+ floatCompare = false;
+ break;
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
+ readFormat = gluTextureUtil.mapGLTransferFormat(gl.RGBA_INTEGER, gl.UNSIGNED_INT);
+ readPixelsFormat = gl.RGBA_INTEGER;
+ readPixelsType = gl.UNSIGNED_INT;
+ floatCompare = false;
+ break;
+ case tcuTexture.TextureChannelClass.FLOATING_POINT:
+ readFormat = gluTextureUtil.mapGLTransferFormat(gl.RGBA, gl.FLOAT);
+ readPixelsFormat = gl.RGBA;
+ readPixelsType = gl.FLOAT;
+ floatCompare = true;
+ break;
+ default:
+ DE_ASSERT(false);
+ // Silence warning
+ readFormat = gluTextureUtil.mapGLTransferFormat(gl.RGBA, gl.FLOAT);
+ readPixelsFormat = gl.RGBA;
+ readPixelsType = gl.FLOAT;
+ floatCompare = true;
+ }
+ } else {
+ // Silence warnings
+ readFormat = gluTextureUtil.mapGLTransferFormat(gl.RGBA, gl.FLOAT);
+ readPixelsFormat = gl.RGBA;
+ readPixelsType = gl.FLOAT;
+ floatCompare = true;
+ DE_ASSERT(false);
+ }
+
+ var readReference = new tcuTexture.Texture2D(readFormat, width, height);
+ readReference.allocLevel(0);
+
+ var pixelBuffer = gl.createBuffer();
+
+ gl.bindBuffer(gl.PIXEL_PACK_BUFFER, pixelBuffer);
+ gl.bufferData(gl.PIXEL_PACK_BUFFER, readReference.getLevel(0).getDataSize(), gl.STREAM_READ);
+ gl.readPixels(0, 0, width, height, readPixelsFormat, readPixelsType, 0);
+
+ var bufferData = new Uint8Array(readReference.getLevel(0).getDataSize());
+
+ gl.getBufferSubData(gl.PIXEL_PACK_BUFFER, 0, bufferData);
+
+ var readResult = new tcuTexture.ConstPixelBufferAccess({
+ width: width,
+ height: height,
+ format: readFormat,
+ data: bufferData.buffer});
+
+ gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null);
+
+ gl.readPixels(0, 0, width, height, readPixelsFormat, readPixelsType, readReference.getLevel(0).getDataPtr());
+
+ if (framebuffer)
+ gl.deleteFramebuffer(framebuffer);
+
+ if (renderbuffer)
+ gl.deleteRenderbuffer(renderbuffer);
+
+ var isOk = false;
+
+ if (floatCompare) {
+ // When converting between integers and floats, certain GPUs might have different behaviors
+ // from javascript in rounding (up vs down). Increase tolerance to allow both behaviors.
+ // Detailed discussion in Mesa upstream can be found at:
+ // https://bugs.freedesktop.org/show_bug.cgi?id=89314.
+ var threshold;
+ switch (this.m_renderbufferFormat) {
+ case gl.RGB10_A2:
+ case gl.RGB5_A1:
+ case gl.RGB565:
+ threshold = [0.004, 0.004, 0.004, 0.0];
+ break;
+ default:
+ threshold = [0.0, 0.0, 0.0, 0.0];
+ break;
+ }
+ isOk = tcuImageCompare.floatThresholdCompare('Result comparison', 'Result of read pixels to memory compared with result of read pixels to buffer', readReference.getLevel(0), readResult, threshold);
+ }
+ else
+ isOk = tcuImageCompare.intThresholdCompare('Result comparison', 'Result of read pixels to memory compared with result of read pixels to buffer', readReference.getLevel(0), readResult, [0, 0, 0, 0]);
+
+ gl.deleteBuffer(pixelBuffer);
+
+ assertMsgOptions(isOk, this.getDescription(), true, true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ es3fPixelBufferObjectTest.init = function() {
+ var state = tcuTestCase.runner;
+ /** @type {tcuTestCase.DeqpTest} */ var testGroup = state.testCases;
+
+ /** @type {tcuTestCase.DeqpTest} */ var nativeFramebufferGroup = tcuTestCase.newTest('native', 'Tests with reading from native framebuffer');
+
+ var nativeFramebufferTests = [{
+ name: 'clears',
+ description: 'Simple read pixels test with color clears',
+ useColorClear: true,
+ renderTriangles: false,
+ framebufferType: es3fPixelBufferObjectTest.FramebufferType.FRAMEBUFFERTYPE_NATIVE,
+ renderbufferFormat: gl.NONE
+ }, {
+ name: 'triangles',
+ description: 'Simple read pixels test rendering triangles',
+ useColorClear: false,
+ renderTriangles: true,
+ framebufferType: es3fPixelBufferObjectTest.FramebufferType.FRAMEBUFFERTYPE_NATIVE,
+ renderbufferFormat: gl.NONE
+ }
+ ];
+
+ for (var testNdx = 0; testNdx < nativeFramebufferTests.length; testNdx++)
+ nativeFramebufferGroup.addChild(new es3fPixelBufferObjectTest.ReadPixelsTest(nativeFramebufferTests[testNdx]));
+
+ testGroup.addChild(nativeFramebufferGroup);
+
+ /** @type {tcuTestCase.DeqpTest} */ var renderbufferGroup = tcuTestCase.newTest('renderbuffer', 'Tests with reading from renderbuffer');
+
+ var renderbufferFormats = [
+ gl.RGBA8,
+ gl.RGBA8I,
+ gl.RGBA8UI,
+ gl.RGBA16I,
+ gl.RGBA16UI,
+ gl.RGBA32I,
+ gl.RGBA32UI,
+
+ gl.SRGB8_ALPHA8,
+ gl.RGB10_A2,
+ gl.RGB10_A2UI,
+ gl.RGBA4,
+ gl.RGB5_A1,
+
+ gl.RGB8,
+ gl.RGB565,
+
+ gl.RG8,
+ gl.RG8I,
+ gl.RG8UI,
+ gl.RG16I,
+ gl.RG16UI,
+ gl.RG32I,
+ gl.RG32UI
+ ];
+
+ var renderbufferFormatsStr = [
+ 'rgba8',
+ 'rgba8i',
+ 'rgba8ui',
+ 'rgba16i',
+ 'rgba16ui',
+ 'rgba32i',
+ 'rgba32ui',
+
+ 'srgb8_alpha8',
+ 'rgb10_a2',
+ 'rgb10_a2ui',
+ 'rgba4',
+ 'rgb5_a1',
+
+ 'rgb8',
+ 'rgb565',
+
+ 'rg8',
+ 'rg8i',
+ 'rg8ui',
+ 'rg16i',
+ 'rg16ui',
+ 'rg32i',
+ 'rg32ui'
+ ];
+ es3fPixelBufferObjectTest.DE_STATIC_ASSERT(renderbufferFormatsStr.length == renderbufferFormats.length);
+
+ for (var formatNdx = 0; formatNdx < renderbufferFormats.length; formatNdx++) {
+ for (var trianglesClears = 0; trianglesClears < 2; trianglesClears++) {
+ var nameDescription = renderbufferFormatsStr[formatNdx] + '_' + (trianglesClears == 0 ? 'triangles' : 'clears');
+ var testSpec = new es3fPixelBufferObjectTest.TestSpec();
+ testSpec.name = nameDescription;
+ testSpec.description = nameDescription;
+ testSpec.useColorClear = trianglesClears == 1;
+ testSpec.renderTriangles = trianglesClears == 0;
+ testSpec.framebufferType = es3fPixelBufferObjectTest.FramebufferType.FRAMEBUFFERTYPE_RENDERBUFFER;
+ testSpec.renderbufferFormat = renderbufferFormats[formatNdx];
+
+ renderbufferGroup.addChild(new es3fPixelBufferObjectTest.ReadPixelsTest(testSpec));
+ }
+ }
+
+ testGroup.addChild(renderbufferGroup);
+ };
+
+ es3fPixelBufferObjectTest.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var testName = 'pixel_buffer_object';
+ var testDescription = 'Pixel Buffer Object Tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.testCases = tcuTestCase.newTest(testName, testDescription, null);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ es3fPixelBufferObjectTest.init();
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ bufferedLogToConsole(err);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fPrimitiveRestartTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fPrimitiveRestartTests.js
new file mode 100644
index 0000000000..ac0da2fe66
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fPrimitiveRestartTests.js
@@ -0,0 +1,709 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fPrimitiveRestartTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluTextureUtil');
+
+goog.scope(function() {
+
+var es3fPrimitiveRestartTests = functional.gles3.es3fPrimitiveRestartTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+var tcuSurface = framework.common.tcuSurface;
+var deMath = framework.delibs.debase.deMath;
+var deRandom = framework.delibs.debase.deRandom;
+var deString = framework.delibs.debase.deString;
+var tcuImageCompare = framework.common.tcuImageCompare;
+var gluTextureUtil = framework.opengl.gluTextureUtil;
+
+ /** @type {WebGL2RenderingContext} */ var gl;
+ /** @const @type {number} */ es3fPrimitiveRestartTests.MAX_RENDER_WIDTH = 256;
+ /** @const @type {number} */ es3fPrimitiveRestartTests.MAX_RENDER_HEIGHT = 256;
+
+ /** @const @type {number} */ es3fPrimitiveRestartTests.MAX_UNSIGNED_BYTE = 255;
+ /** @const @type {number} */ es3fPrimitiveRestartTests.MAX_UNSIGNED_SHORT = 65535;
+ /** @const @type {number} */ es3fPrimitiveRestartTests.MAX_UNSIGNED_INT = 4294967295;
+
+ /** @const @type {number} */ es3fPrimitiveRestartTests.RESTART_INDEX_UNSIGNED_BYTE = es3fPrimitiveRestartTests.MAX_UNSIGNED_BYTE;
+ /** @const @type {number} */ es3fPrimitiveRestartTests.RESTART_INDEX_UNSIGNED_SHORT = es3fPrimitiveRestartTests.MAX_UNSIGNED_SHORT;
+ /** @const @type {number} */ es3fPrimitiveRestartTests.RESTART_INDEX_UNSIGNED_INT = es3fPrimitiveRestartTests.MAX_UNSIGNED_INT;
+
+ var DE_ASSERT = function(expression) {
+ if (!expression) throw new Error('Assert failed');
+ };
+
+ /**
+ * @enum
+ */
+ es3fPrimitiveRestartTests.PrimitiveType = {
+ PRIMITIVE_POINTS: 0,
+ PRIMITIVE_LINE_STRIP: 1,
+ PRIMITIVE_LINE_LOOP: 2,
+ PRIMITIVE_LINES: 3,
+ PRIMITIVE_TRIANGLE_STRIP: 4,
+ PRIMITIVE_TRIANGLE_FAN: 5,
+ PRIMITIVE_TRIANGLES: 6
+ };
+
+ /**
+ * @enum
+ */
+ es3fPrimitiveRestartTests.IndexType = {
+ INDEX_UNSIGNED_BYTE: 0,
+ INDEX_UNSIGNED_SHORT: 1,
+ INDEX_UNSIGNED_INT: 2
+ };
+
+ /**
+ * @enum
+ */
+ es3fPrimitiveRestartTests.DrawFunction = {
+ FUNCTION_DRAW_ELEMENTS: 0,
+ FUNCTION_DRAW_ELEMENTS_INSTANCED: 1,
+ FUNCTION_DRAW_RANGE_ELEMENTS: 2
+ };
+
+ /**
+ * es3fPrimitiveRestartTests.PrimitiveRestartCase class, inherits from TestCase class
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {?string} name
+ * @param {string} description
+ * @param {es3fPrimitiveRestartTests.PrimitiveType} primType
+ * @param {es3fPrimitiveRestartTests.IndexType} indexType
+ * @param {es3fPrimitiveRestartTests.DrawFunction} _function
+ * @param {boolean} beginWithRestart
+ * @param {boolean} endWithRestart
+ * @param {boolean} duplicateRestarts
+ */
+ es3fPrimitiveRestartTests.PrimitiveRestartCase = function(name, description, primType, indexType, _function, beginWithRestart, endWithRestart, duplicateRestarts) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ /** @type {es3fPrimitiveRestartTests.PrimitiveType} */ this.m_primType = primType;
+ /** @type {es3fPrimitiveRestartTests.IndexType} */ this.m_indexType = indexType;
+ /** @type {es3fPrimitiveRestartTests.DrawFunction} */ this.m_function = _function;
+ /** @type {boolean} */ this.m_beginWithRestart = beginWithRestart; // Whether there will be restart indices at the beginning of the index array.
+ /** @type {boolean} */ this.m_endWithRestart = endWithRestart; // Whether there will be restart indices at the end of the index array.
+ /** @type {boolean} */ this.m_duplicateRestarts = duplicateRestarts; // Whether two consecutive restarts are used instead of one.
+ /** @type {gluShaderProgram.ShaderProgram} */ this.m_program = null;
+
+ // \note Only one of the following index vectors is used (according to m_indexType).
+ /** @type {Array<number>} */ this.m_indicesUB = []; //deUint8
+ /** @type {Array<number>} */ this.m_indicesUS = []; //deUint16
+ /** @type {Array<number>} */ this.m_indicesUI = []; //deUint32
+
+ /** @type {Array<number>} */ this.m_positions = [];
+ };
+
+ es3fPrimitiveRestartTests.PrimitiveRestartCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fPrimitiveRestartTests.PrimitiveRestartCase.prototype.constructor = es3fPrimitiveRestartTests.PrimitiveRestartCase;
+
+ /**
+ * Draw with the appropriate GLES3 draw function.
+ * @param {number} startNdx
+ * @param {number} count
+ */
+ es3fPrimitiveRestartTests.PrimitiveRestartCase.prototype.draw = function(startNdx, count) {
+ /** @type {number} */ var primTypeGL;
+
+ switch (this.m_primType) {
+ case es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_POINTS:
+ primTypeGL = gl.POINTS;
+ break;
+ case es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_LINE_STRIP:
+ primTypeGL = gl.LINE_STRIP;
+ break;
+ case es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_LINE_LOOP:
+ primTypeGL = gl.LINE_LOOP;
+ break;
+ case es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_LINES:
+ primTypeGL = gl.LINES;
+ break;
+ case es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_TRIANGLE_STRIP:
+ primTypeGL = gl.TRIANGLE_STRIP;
+ break;
+ case es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_TRIANGLE_FAN:
+ primTypeGL = gl.TRIANGLE_FAN;
+ break;
+ case es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_TRIANGLES:
+ primTypeGL = gl.TRIANGLES;
+ break;
+ default:
+ DE_ASSERT(false);
+ primTypeGL = 0;
+ }
+
+ /** @type {number} */ var indexTypeGL;
+
+ switch (this.m_indexType) {
+ case es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_BYTE:
+ indexTypeGL = gl.UNSIGNED_BYTE;
+ break;
+ case es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_SHORT:
+ indexTypeGL = gl.UNSIGNED_SHORT;
+ break;
+ case es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_INT:
+ indexTypeGL = gl.UNSIGNED_INT;
+ break;
+ default:
+ DE_ASSERT(false);
+ indexTypeGL = 0;
+ }
+
+ /** @type {number} */ var restartIndex = this.m_indexType == es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_BYTE ? es3fPrimitiveRestartTests.RESTART_INDEX_UNSIGNED_BYTE :
+ this.m_indexType == es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_SHORT ? es3fPrimitiveRestartTests.RESTART_INDEX_UNSIGNED_SHORT :
+ this.m_indexType == es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_INT ? es3fPrimitiveRestartTests.RESTART_INDEX_UNSIGNED_INT :
+ 0;
+
+ DE_ASSERT(restartIndex != 0);
+
+ var indexGLBuffer = gl.createBuffer();
+ var bufferIndex = this.getIndexPtr(startNdx);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexGLBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, bufferIndex, gl.STATIC_DRAW);
+
+ if (this.m_function == es3fPrimitiveRestartTests.DrawFunction.FUNCTION_DRAW_ELEMENTS) {
+ gl.drawElements(primTypeGL, count, indexTypeGL, 0);
+ } else if (this.m_function == es3fPrimitiveRestartTests.DrawFunction.FUNCTION_DRAW_ELEMENTS_INSTANCED) {
+ gl.drawElementsInstanced(primTypeGL, count, indexTypeGL, 0, 1);
+ } else {
+ DE_ASSERT(this.m_function == es3fPrimitiveRestartTests.DrawFunction.FUNCTION_DRAW_RANGE_ELEMENTS);
+
+ // Find the largest non-restart index in the index array (for glDrawRangeElements() end parameter).
+
+ /** @type {number} */ var max = 0;
+
+ /** @type {number} */ var numIndices = this.getNumIndices();
+ for (var i = 0; i < numIndices; i++) {
+ /** @type {number} */ var index = this.getIndex(i);
+ if (index != restartIndex && index > max)
+ max = index;
+ }
+ //TODO: drawRangeElements -> check getIndexPtr usage
+ gl.drawRangeElements(primTypeGL, 0, max, count, indexTypeGL, 0);
+ }
+ };
+
+ es3fPrimitiveRestartTests.PrimitiveRestartCase.prototype.renderWithRestart = function() {
+ // Primitive Restart is always on in WebGL2
+ //gl.enable(gl.PRIMITIVE_RESTART_FIXED_INDEX);
+
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ this.draw(0, this.getNumIndices());
+ };
+
+ es3fPrimitiveRestartTests.PrimitiveRestartCase.prototype.renderWithoutRestart = function() {
+ /** @type {number} */ var restartIndex = this.m_indexType == es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_BYTE ? es3fPrimitiveRestartTests.RESTART_INDEX_UNSIGNED_BYTE :
+ this.m_indexType == es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_SHORT ? es3fPrimitiveRestartTests.RESTART_INDEX_UNSIGNED_SHORT :
+ this.m_indexType == es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_INT ? es3fPrimitiveRestartTests.RESTART_INDEX_UNSIGNED_INT :
+ 0;
+
+ DE_ASSERT(restartIndex != 0);
+ // Primitive Restart is always on in WebGL2
+ //gl.disable(gl.PRIMITIVE_RESTART_FIXED_INDEX);
+
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ // Draw, emulating primitive restart.
+
+ /** @type {number} */ var numIndices = this.getNumIndices();
+
+ DE_ASSERT(numIndices >= 0);
+
+ /** @type {number} */ var indexArrayStartNdx = 0; // Keep track of the draw start index - first index after a primitive restart, or initially the first index altogether.
+
+ for (var indexArrayNdx = 0; indexArrayNdx <= numIndices; indexArrayNdx++) { // \note Goes one "too far" in order to detect end of array as well.
+ if (indexArrayNdx >= numIndices || this.getIndex(indexArrayNdx) == restartIndex) {// \note Handle end of array the same way as a restart index encounter.
+ if (indexArrayStartNdx < numIndices) {
+ // Draw from index indexArrayStartNdx to index indexArrayNdx-1 .
+
+ this.draw(indexArrayStartNdx, indexArrayNdx - indexArrayStartNdx);
+ }
+
+ indexArrayStartNdx = indexArrayNdx + 1; // Next draw starts just after this restart index.
+ }
+ }
+ };
+
+ /**
+ * @param {number} index
+ */
+ es3fPrimitiveRestartTests.PrimitiveRestartCase.prototype.addIndex = function(index) {
+ if (this.m_indexType == es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_BYTE) {
+ DE_ASSERT(deMath.deInRange32(index, 0, es3fPrimitiveRestartTests.MAX_UNSIGNED_BYTE));
+ this.m_indicesUB.push(index); // deUint8
+ } else if (this.m_indexType == es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_SHORT) {
+ DE_ASSERT(deMath.deInRange32(index, 0, es3fPrimitiveRestartTests.MAX_UNSIGNED_SHORT));
+ this.m_indicesUS.push(index); // deUint16
+ } else if (this.m_indexType == es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_INT) {
+ DE_ASSERT(deMath.deInRange32(index, 0, es3fPrimitiveRestartTests.MAX_UNSIGNED_INT));
+ this.m_indicesUI.push(index); // // deUint32
+ } else
+ DE_ASSERT(false);
+ };
+
+ /**
+ * @param {number} indexNdx
+ * @return {number}
+ */
+ es3fPrimitiveRestartTests.PrimitiveRestartCase.prototype.getIndex = function(indexNdx) {
+ switch (this.m_indexType) {
+ case es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_BYTE:
+ return this.m_indicesUB[indexNdx]; //deUint32
+ case es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_SHORT:
+ return this.m_indicesUS[indexNdx]; //deUint32
+ case es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_INT:
+ return this.m_indicesUI[indexNdx];
+ default:
+ DE_ASSERT(false);
+ return 0;
+ }
+ };
+
+ /**
+ * @return {number}
+ */
+ es3fPrimitiveRestartTests.PrimitiveRestartCase.prototype.getNumIndices = function() {
+ switch (this.m_indexType) {
+ case es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_BYTE:
+ return this.m_indicesUB.length;
+ case es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_SHORT:
+ return this.m_indicesUS.length;
+ case es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_INT:
+ return this.m_indicesUI.length;
+ default:
+ DE_ASSERT(false);
+ return 0;
+ }
+ };
+
+ /**
+ * Pointer to the index value at index indexNdx.
+ * @param {number} indexNdx
+ * @return {Uint8Array|Uint16Array|Uint32Array}
+ */
+ es3fPrimitiveRestartTests.PrimitiveRestartCase.prototype.getIndexPtr = function(indexNdx) {
+ //TODO: implement
+ switch (this.m_indexType) {
+ case es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_BYTE:
+ return new Uint8Array(this.m_indicesUB).subarray(indexNdx);
+ case es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_SHORT:
+ return new Uint16Array(this.m_indicesUS).subarray(indexNdx);
+ case es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_INT:
+ return new Uint32Array(this.m_indicesUI).subarray(indexNdx);
+ default:
+ DE_ASSERT(false);
+ return null;
+ }
+ };
+
+ es3fPrimitiveRestartTests.PrimitiveRestartCase.prototype.init = function() {
+ // Clear errors from previous tests
+ gl.getError();
+
+ // Create shader program.
+
+ /** @type {string} */ var vertShaderSource =
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ '\n' +
+ 'void main()\n' +
+ ' {\n' +
+ ' gl_Position = a_position;\n';
+
+ if (this.m_primType == es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_POINTS) {
+ vertShaderSource += ' gl_PointSize = 1.0;\n';
+ }
+
+ vertShaderSource += '}\n';
+
+ /** @type {string} */ var fragShaderSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ '\n' +
+ 'void main()\n' +
+ ' {\n' +
+ ' o_color = vec4(1.0f);\n' +
+ '}\n';
+
+ DE_ASSERT(!this.m_program);
+
+ this.m_program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertShaderSource, fragShaderSource));
+
+ if (!this.m_program.isOk()) {
+ //m_testCtx.getLog() << *this.m_program;
+ testFailedOptions('Failed to compile shader', true);
+ }
+
+ /** @type {number} */ var restartIndex = this.m_indexType == es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_BYTE ? es3fPrimitiveRestartTests.RESTART_INDEX_UNSIGNED_BYTE :
+ this.m_indexType == es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_SHORT ? es3fPrimitiveRestartTests.RESTART_INDEX_UNSIGNED_SHORT :
+ this.m_indexType == es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_INT ? es3fPrimitiveRestartTests.RESTART_INDEX_UNSIGNED_INT :
+ 0;
+
+ DE_ASSERT(restartIndex != 0);
+
+ DE_ASSERT(this.getNumIndices() == 0);
+
+ // If testing a case with restart at beginning, add it there.
+ if (this.m_beginWithRestart) {
+ this.addIndex(restartIndex);
+ if (this.m_duplicateRestarts)
+ this.addIndex(restartIndex);
+ }
+
+ // Generate vertex positions and indices depending on primitive type.
+ // \note At this point, restarts shall not be added to the start or the end of the index vector. Those are special cases, and are done above and after the following if-else chain, respectively.
+ /** @type {number} */ var curIndex;
+ /** @type {number} */ var numRows;
+ /** @type {number} */ var numCols;
+ /** @type {number} */ var fx;
+ /** @type {number} */ var fy;
+ /** @type {number} */ var centerY;
+ /** @type {number} */ var centerX;
+ /** @type {number} */ var numVertices;
+ /** @type {number} */ var numArcVertices;
+ /** @type {number} */ var numStrips;
+
+ if (this.m_primType == es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_POINTS) {
+ // Generate rows with different numbers of points.
+
+ curIndex = 0;
+ numRows = 20;
+
+ for (var row = 0; row < numRows; row++) {
+ for (var col = 0; col < row + 1; col++) {
+ fx = -1.0 + 2.0 * (col + 0.5) / numRows;
+ fy = -1.0 + 2.0 * (row + 0.5) / numRows;
+
+ this.m_positions.push(fx);
+ this.m_positions.push(fy);
+
+ this.addIndex(curIndex++);
+ }
+
+ if (row < numRows - 1) { // Add a restart after all but last row.
+ this.addIndex(restartIndex);
+ if (this.m_duplicateRestarts)
+ this.addIndex(restartIndex);
+ }
+ }
+ } else if (this.m_primType == es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_LINE_STRIP || this.m_primType == es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_LINE_LOOP || this.m_primType == es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_LINES) {
+ // Generate a numRows x numCols arrangement of line polygons of different vertex counts.
+
+ curIndex = 0;
+ numRows = 4;
+ numCols = 4;
+
+ for (var row = 0; row < numRows; row++) {
+ centerY = -1.0 + 2.0 * (row + 0.5) / numRows;
+
+ for (var col = 0; col < numCols; col++) {
+ centerX = -1.0 + 2.0 * (col + 0.5) / numCols;
+ numVertices = row * numCols + col + 1;
+
+ for (var i = 0; i < numVertices; i++) {
+ fx = centerX + 0.9 * Math.cos(i * 2.0 * Math.PI / numVertices) / numCols;
+ fy = centerY + 0.9 * Math.sin(i * 2.0 * Math.PI / numVertices) / numRows;
+
+ this.m_positions.push(fx);
+ this.m_positions.push(fy);
+
+ this.addIndex(curIndex++);
+ }
+
+ if (col < numCols - 1 || row < numRows - 1) {// Add a restart after all but last polygon.
+ this.addIndex(restartIndex);
+ if (this.m_duplicateRestarts)
+ this.addIndex(restartIndex);
+ }
+ }
+ }
+ } else if (this.m_primType == es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_TRIANGLE_STRIP) {
+ // Generate a number of horizontal triangle strips of different lengths.
+
+ curIndex = 0;
+ numStrips = 20;
+
+ for (var stripNdx = 0; stripNdx < numStrips; stripNdx++) {
+ numVertices = stripNdx + 1;
+
+ for (var i = 0; i < numVertices; i++) {
+ fx = -0.9 + 1.8 * (i / 2 * 2) / numStrips;
+ fy = -0.9 + 1.8 * (stripNdx + (i % 2 == 0 ? 0.0 : 0.8)) / numStrips;
+
+ this.m_positions.push(fx);
+ this.m_positions.push(fy);
+
+ this.addIndex(curIndex++);
+ }
+
+ if (stripNdx < numStrips - 1) { // Add a restart after all but last strip.
+ this.addIndex(restartIndex);
+ if (this.m_duplicateRestarts)
+ this.addIndex(restartIndex);
+ }
+ }
+ } else if (this.m_primType == es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_TRIANGLE_FAN) {
+ // Generate a numRows x numCols arrangement of triangle fan polygons of different vertex counts.
+
+ curIndex = 0;
+ numRows = 4;
+ numCols = 4;
+
+ for (var row = 0; row < numRows; row++) {
+ centerY = -1.0 + 2.0 * (row + 0.5) / numRows;
+
+ for (var col = 0; col < numCols; col++) {
+ centerX = -1.0 + 2.0 * (col + 0.5) / numCols;
+ numArcVertices = row * numCols + col;
+
+ this.m_positions.push(centerX);
+ this.m_positions.push(centerY);
+
+ this.addIndex(curIndex++);
+
+ for (var i = 0; i < numArcVertices; i++) {
+ fx = centerX + 0.9 * Math.cos(i * 2.0 * Math.PI / numArcVertices) / numCols;
+ fy = centerY + 0.9 * Math.sin(i * 2.0 * Math.PI / numArcVertices) / numRows;
+
+ this.m_positions.push(fx);
+ this.m_positions.push(fy);
+
+ this.addIndex(curIndex++);
+ }
+
+ if (col < numCols - 1 || row < numRows - 1) { // Add a restart after all but last polygon.
+ this.addIndex(restartIndex);
+ if (this.m_duplicateRestarts)
+ this.addIndex(restartIndex);
+ }
+ }
+ }
+ } else if (this.m_primType == es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_TRIANGLES) {
+ // Generate a number of rows with (potentially incomplete) triangles.
+
+ curIndex = 0;
+ numRows = 3 * 7;
+
+ for (var rowNdx = 0; rowNdx < numRows; rowNdx++) {
+ numVertices = rowNdx + 1;
+
+ for (var i = 0; i < numVertices; i++) {
+ fx = -0.9 + 1.8 * ((i / 3) + (i % 3 == 2 ? 0.8 : 0.0)) * 3 / numRows;
+ fy = -0.9 + 1.8 * (rowNdx + (i % 3 == 0 ? 0.0 : 0.8)) / numRows;
+
+ this.m_positions.push(fx);
+ this.m_positions.push(fy);
+
+ this.addIndex(curIndex++);
+ }
+
+ if (rowNdx < numRows - 1) { // Add a restart after all but last row.
+ this.addIndex(restartIndex);
+ if (this.m_duplicateRestarts)
+ this.addIndex(restartIndex);
+ }
+ }
+ } else
+ DE_ASSERT(false);
+
+ // If testing a case with restart at end, add it there.
+ if (this.m_endWithRestart) {
+ this.addIndex(restartIndex);
+ if (this.m_duplicateRestarts)
+ this.addIndex(restartIndex);
+ }
+
+ // Special case assertions.
+
+ /** @type {number} */ var numIndices = this.getNumIndices();
+
+ DE_ASSERT(numIndices > 0);
+ DE_ASSERT(this.m_beginWithRestart || this.getIndex(0) != restartIndex); // We don't want restarts at beginning unless the case is a special case.
+ DE_ASSERT(this.m_endWithRestart || this.getIndex(numIndices - 1) != restartIndex); // We don't want restarts at end unless the case is a special case.
+
+ if (!this.m_duplicateRestarts)
+ for (var i = 1; i < numIndices; i++)
+ DE_ASSERT(this.getIndex(i) != restartIndex || this.getIndex(i - 1) != restartIndex); // We don't want duplicate restarts unless the case is a special case.
+
+ };
+
+ es3fPrimitiveRestartTests.PrimitiveRestartCase.prototype.iterate = function() {
+ /** @type {number} */ var width = Math.min(gl.drawingBufferWidth, es3fPrimitiveRestartTests.MAX_RENDER_WIDTH);
+ /** @type {number} */ var height = Math.min(gl.drawingBufferHeight, es3fPrimitiveRestartTests.MAX_RENDER_HEIGHT);
+
+ /** @type {number} */ var xOffsetMax = gl.drawingBufferWidth - width;
+ /** @type {number} */ var yOffsetMax = gl.drawingBufferHeight - height;
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name));
+
+ /** @type {number} */ var xOffset = rnd.getInt(0, xOffsetMax);
+ /** @type {number} */ var yOffset = rnd.getInt(0, yOffsetMax);
+ /** @type {tcuSurface.Surface} */ var referenceImg = new tcuSurface.Surface(width, height);
+ /** @type {tcuSurface.Surface} */ var resultImg = new tcuSurface.Surface(width, height);
+
+ gl.viewport(xOffset, yOffset, width, height);
+ gl.clearColor(0.0, 0.0, 0.0, 1.0);
+
+ var program = this.m_program.getProgram();
+ gl.useProgram(program);
+
+ // Setup position attribute.
+
+ /** @type {number} */ var loc = gl.getAttribLocation(program, 'a_position');
+ gl.enableVertexAttribArray(loc);
+
+ var locGlBuffer = gl.createBuffer();
+ var bufferLoc = new Float32Array(this.m_positions);
+ gl.bindBuffer(gl.ARRAY_BUFFER, locGlBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, bufferLoc, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);
+
+ // Render result.
+ this.renderWithRestart();
+ var resImg = resultImg.getAccess();
+ var resImgTransferFormat = gluTextureUtil.getTransferFormat(resImg.getFormat());
+ gl.readPixels(xOffset, yOffset, resImg.m_width, resImg.m_height, resImgTransferFormat.format, resImgTransferFormat.dataType, resultImg.m_pixels);
+
+ // Render reference (same scene as the real deal, but emulate primitive restart without actually using it).
+ this.renderWithoutRestart();
+
+ var refImg = referenceImg.getAccess();
+ var refImgTransferFormat = gluTextureUtil.getTransferFormat(refImg.getFormat());
+
+ gl.readPixels(xOffset, yOffset, refImg.m_width, refImg.m_height, refImgTransferFormat.format, refImgTransferFormat.dataType, referenceImg.m_pixels);
+
+ // Compare.
+ /** @type {boolean} */ var testOk = tcuImageCompare.pixelThresholdCompare('ComparisonResult', 'Image comparison result', referenceImg, resultImg, [0, 0, 0, 0]);
+
+ assertMsgOptions(testOk, '', true, false);
+ gl.useProgram(null);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ es3fPrimitiveRestartTests.init = function() {
+ var testGroup = tcuTestCase.runner.testCases;
+ for (var isRestartBeginCaseI = 0; isRestartBeginCaseI <= 1; isRestartBeginCaseI++) {
+ for (var isRestartEndCaseI = 0; isRestartEndCaseI <= 1; isRestartEndCaseI++) {
+ for (var isDuplicateRestartCaseI = 0; isDuplicateRestartCaseI <= 1; isDuplicateRestartCaseI++) {
+ /** @type {boolean} */ var isRestartBeginCase = isRestartBeginCaseI != 0;
+ /** @type {boolean} */ var isRestartEndCase = isRestartEndCaseI != 0;
+ /** @type {boolean} */ var isDuplicateRestartCase = isDuplicateRestartCaseI != 0;
+
+ /** @type {string} */ var specialCaseGroupName = '';
+
+ if (isRestartBeginCase) specialCaseGroupName = 'begin_restart';
+ if (isRestartEndCase) specialCaseGroupName += (deString.deIsStringEmpty(specialCaseGroupName) ? '' : '_') + 'end_restart';
+ if (isDuplicateRestartCase) specialCaseGroupName += (deString.deIsStringEmpty(specialCaseGroupName) ? '' : '_') + 'duplicate_restarts';
+
+ if (deString.deIsStringEmpty(specialCaseGroupName))
+ specialCaseGroupName = 'basic';
+
+ /** @type {tcuTestCase.DeqpTest} */ var specialCaseGroup = tcuTestCase.newTest(specialCaseGroupName, '');
+ testGroup.addChild(specialCaseGroup);
+
+ for (var primType in es3fPrimitiveRestartTests.PrimitiveType) {
+ /** @type {string} */ var primTypeName = es3fPrimitiveRestartTests.PrimitiveType[primType] == es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_POINTS ? 'points' :
+ es3fPrimitiveRestartTests.PrimitiveType[primType] == es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_LINE_STRIP ? 'line_strip' :
+ es3fPrimitiveRestartTests.PrimitiveType[primType] == es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_LINE_LOOP ? 'line_loop' :
+ es3fPrimitiveRestartTests.PrimitiveType[primType] == es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_LINES ? 'lines' :
+ es3fPrimitiveRestartTests.PrimitiveType[primType] == es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_TRIANGLE_STRIP ? 'triangle_strip' :
+ es3fPrimitiveRestartTests.PrimitiveType[primType] == es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_TRIANGLE_FAN ? 'triangle_fan' :
+ es3fPrimitiveRestartTests.PrimitiveType[primType] == es3fPrimitiveRestartTests.PrimitiveType.PRIMITIVE_TRIANGLES ? 'triangles' :
+ '';
+
+ DE_ASSERT(primTypeName != null);
+
+ /** @type {tcuTestCase.DeqpTest} */ var primTypeGroup = tcuTestCase.newTest(primTypeName, '');
+ specialCaseGroup.addChild(primTypeGroup);
+
+ for (var indexType in es3fPrimitiveRestartTests.IndexType) {
+ /** @type {string} */ var indexTypeName = es3fPrimitiveRestartTests.IndexType[indexType] == es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_BYTE ? 'unsigned_byte' :
+ es3fPrimitiveRestartTests.IndexType[indexType] == es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_SHORT ? 'unsigned_short' :
+ es3fPrimitiveRestartTests.IndexType[indexType] == es3fPrimitiveRestartTests.IndexType.INDEX_UNSIGNED_INT ? 'unsigned_int' :
+ '';
+
+ DE_ASSERT(indexTypeName != null);
+
+ /** @type {tcuTestCase.DeqpTest} */ var indexTypeGroup = tcuTestCase.newTest(indexTypeName, '');
+ primTypeGroup.addChild(indexTypeGroup);
+
+ for (var _function in es3fPrimitiveRestartTests.DrawFunction) {
+ /** @type {?string} */ var functionName = es3fPrimitiveRestartTests.DrawFunction[_function] == es3fPrimitiveRestartTests.DrawFunction.FUNCTION_DRAW_ELEMENTS ? 'draw_elements' :
+ es3fPrimitiveRestartTests.DrawFunction[_function] == es3fPrimitiveRestartTests.DrawFunction.FUNCTION_DRAW_ELEMENTS_INSTANCED ? 'draw_elements_instanced' :
+ es3fPrimitiveRestartTests.DrawFunction[_function] == es3fPrimitiveRestartTests.DrawFunction.FUNCTION_DRAW_RANGE_ELEMENTS ? 'draw_range_elements' :
+ null;
+
+ DE_ASSERT(functionName != null);
+
+ indexTypeGroup.addChild(new es3fPrimitiveRestartTests.PrimitiveRestartCase(functionName,
+ '',
+ es3fPrimitiveRestartTests.PrimitiveType[primType],
+ es3fPrimitiveRestartTests.IndexType[indexType],
+ es3fPrimitiveRestartTests.DrawFunction[_function],
+ isRestartBeginCase,
+ isRestartEndCase,
+ isDuplicateRestartCase));
+ }
+ }
+ }
+ }
+ }
+ }
+ };
+
+ es3fPrimitiveRestartTests.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var testName = 'primitive_restart';
+ var testDescription = 'Primitive Restart Tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.setRoot(tcuTestCase.newTest(testName, testDescription, null));
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ es3fPrimitiveRestartTests.init();
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fPrimitiveRestartTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fRasterizerDiscardTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fRasterizerDiscardTests.js
new file mode 100644
index 0000000000..ce74648569
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fRasterizerDiscardTests.js
@@ -0,0 +1,485 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.0 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Rasterizer discard tests.
+ *//*--------------------------------------------------------------------*/
+
+goog.provide('functional.gles3.es3fRasterizerDiscardTests');
+goog.require('framework.common.tcuLogImage');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluDrawUtil');
+goog.require('framework.opengl.gluShaderProgram');
+
+goog.scope(function() {
+var es3fRasterizerDiscardTests = functional.gles3.es3fRasterizerDiscardTests;
+var deString = framework.delibs.debase.deString;
+var tcuTestCase = framework.common.tcuTestCase;
+var deRandom = framework.delibs.debase.deRandom;
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+var tcuSurface = framework.common.tcuSurface;
+var gluDrawUtil = framework.opengl.gluDrawUtil;
+var tcuLogImage = framework.common.tcuLogImage;
+
+/** @const */ var NUM_CASE_ITERATIONS = 1;
+/** @const */ var FAIL_COLOR_RED = [1, 0, 0.0, 1];
+/** @const */ var PASS_COLOR_BLUE = [0, 0, 0.5, 1];
+/** @const */ var BLACK_COLOR = [0, 0, 0.0, 1];
+/** @const */ var FAIL_DEPTH = 0;
+/** @const */ var FAIL_STENCIL = 1;
+/** @const */ var UNIT_SQUARE = [
+ 1, 1, 0.05, 1,
+ 1, -1, 0.05, 1,
+ -1, 1, 0.05, 1,
+ -1, -1, 0.05, 1
+];
+
+/** @type {WebGL2RenderingContext} */ var gl;
+
+/**
+ * @enum
+ */
+es3fRasterizerDiscardTests.CaseType = {
+ WRITE_DEPTH: 0,
+ WRITE_STENCIL: 1,
+ CLEAR_COLOR: 2,
+ CLEAR_DEPTH: 3,
+ CLEAR_STENCIL: 4
+};
+
+/**
+ * @enum {{useFBO: boolean, useScissor: boolean}}
+ */
+es3fRasterizerDiscardTests.CaseOptions = {
+ FBO: {useFBO: true, useScissor: false},
+ SCISSOR: {useFBO: false, useScissor: true}
+};
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} numPrimitives
+ * @param {es3fRasterizerDiscardTests.CaseType} caseType
+ * @param {?es3fRasterizerDiscardTests.CaseOptions} caseOptions
+ * @param {gluDrawUtil.primitiveType=} drawMode
+ */
+es3fRasterizerDiscardTests.RasterizerDiscardCase = function(name, description, numPrimitives, caseType, caseOptions, drawMode) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ this.m_numPrimitives = numPrimitives;
+ this.m_caseType = caseType;
+ this.m_caseOptions = caseOptions || {useFBO: false, useScissor: false};
+ this.m_drawMode = drawMode || gluDrawUtil.primitiveType.TRIANGLES;
+ this.m_program = null;
+ this.m_fbo = null;
+ this.m_colorBuf = null;
+ this.m_depthStencilBuf = null;
+ this.m_iterNdx = 0;
+ this.m_rnd = new deRandom.Random(deString.deStringHash(name));
+};
+
+es3fRasterizerDiscardTests.RasterizerDiscardCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fRasterizerDiscardTests.RasterizerDiscardCase.prototype.constructor = es3fRasterizerDiscardTests.RasterizerDiscardCase;
+
+/**
+ * @param {number} numPrimitives
+ * @param {deRandom.Random} rnd
+ * @param {gluDrawUtil.primitiveType} drawMode
+ * @return {Array<number>}
+ */
+es3fRasterizerDiscardTests.generateVertices = function(numPrimitives, rnd, drawMode) {
+ var dst = [];
+ var numVertices;
+
+ switch (drawMode) {
+ case gl.POINTS: numVertices = numPrimitives; break;
+ case gl.LINES: numVertices = 2 * numPrimitives; break;
+ case gl.LINE_STRIP: numVertices = numPrimitives + 1; break;
+ case gl.LINE_LOOP: numVertices = numPrimitives + 2; break;
+ case gl.TRIANGLES: numVertices = 3 * numPrimitives; break;
+ case gl.TRIANGLE_STRIP: numVertices = numPrimitives + 2; break;
+ case gl.TRIANGLE_FAN: numVertices = numPrimitives + 2; break;
+ default:
+ throw new Error('Invalid drawMode: ' + drawMode);
+ }
+
+ for (var i = 0; i < numVertices; i++) {
+ dst[i * 4] = rnd.getFloat(-1.0, 1.0); // x
+ dst[i * 4 + 1] = rnd.getFloat(-1.0, 1.0); // y
+ dst[i * 4 + 2] = rnd.getFloat(0.1, 0.9); // z
+ dst[i * 4 + 3] = 1.0; // w
+ }
+
+ return dst;
+};
+
+es3fRasterizerDiscardTests.RasterizerDiscardCase.prototype.setupFramebufferObject = function() {
+ var width = gl.drawingBufferWidth;
+ var height = gl.drawingBufferHeight;
+
+ // Create framebuffer object
+
+ this.m_fbo = gl.createFramebuffer();
+ this.m_colorBuf = gl.createTexture();
+ this.m_depthStencilBuf = gl.createRenderbuffer();
+
+ // Create color texture
+
+ gl.bindTexture(gl.TEXTURE_2D, this.m_colorBuf);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA8, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+
+ // Create depth and stencil buffers
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, this.m_depthStencilBuf);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH24_STENCIL8, width, height);
+
+ // Attach texture and buffers to FBO
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.m_fbo);
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.m_colorBuf, 0);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.m_depthStencilBuf);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, this.m_depthStencilBuf);
+
+ var fboStatus = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
+
+ if (fboStatus == gl.FRAMEBUFFER_UNSUPPORTED)
+ throw new Error('Framebuffer unsupported');
+ else if (fboStatus != gl.FRAMEBUFFER_COMPLETE)
+ throw new Error('Failed to create framebuffer object: ' + deString.enumToString(gl, fboStatus));
+};
+
+es3fRasterizerDiscardTests.RasterizerDiscardCase.prototype.deleteFramebufferObject = function() {
+ gl.deleteTexture(this.m_colorBuf);
+ gl.deleteRenderbuffer(this.m_depthStencilBuf);
+ gl.deleteFramebuffer(this.m_fbo);
+};
+
+es3fRasterizerDiscardTests.RasterizerDiscardCase.prototype.init = function() {
+ var vertShaderSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) in mediump vec4 a_position;\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ '}\n';
+
+ var fragShaderSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 dEQP_FragColor;\n' +
+ 'uniform mediump vec4 u_color;\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' mediump float depth_gradient = gl_FragCoord.z;\n' +
+ ' mediump float bias = 0.1;\n' +
+ ' dEQP_FragColor = vec4(u_color.xyz * (depth_gradient + bias), 1.0);\n' +
+ '}\n';
+
+ this.m_program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertShaderSource, fragShaderSource));
+
+ if (!this.m_program.isOk()) {
+ bufferedLogToConsole(this.m_program);
+ testFailedOptions('Failed to compile shader program', true);
+ }
+};
+
+es3fRasterizerDiscardTests.RasterizerDiscardCase.prototype.deinit = function() {
+ this.deleteFramebufferObject();
+ this.m_program = null;
+};
+
+es3fRasterizerDiscardTests.RasterizerDiscardCase.prototype.iterate = function() {
+ var program = this.m_program.getProgram();
+ var colorUnif = gl.getUniformLocation(program, 'u_color');
+ var failColorFound = false;
+ var passColorFound = false;
+ var vertices;
+
+ bufferedLogToConsole('Case iteration ' + (this.m_iterNdx + 1) + ' / ' + NUM_CASE_ITERATIONS);
+
+ // Create and bind FBO if needed
+
+ if (this.m_caseOptions.useFBO) {
+ this.setupFramebufferObject();
+ }
+
+ if (this.m_caseOptions.useScissor) {
+ gl.enable(gl.SCISSOR_TEST);
+ gl.scissor(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
+ bufferedLogToConsole('Scissor test enabled: glScissor(0, 0, ' + gl.drawingBufferWidth + ', ' + gl.drawingBufferHeight + ')');
+ }
+
+ gl.useProgram(this.m_program.getProgram());
+
+ gl.enable(gl.DEPTH_TEST);
+ gl.depthRange(0, 1);
+ gl.depthFunc(gl.LEQUAL);
+
+ gl.enable(gl.STENCIL_TEST);
+ gl.stencilFunc(gl.NOTEQUAL, 1, 0xFF);
+ gl.stencilOp(gl.REPLACE, gl.KEEP, gl.KEEP);
+
+ gl.clearColor(PASS_COLOR_BLUE[0], PASS_COLOR_BLUE[1], PASS_COLOR_BLUE[2], PASS_COLOR_BLUE[3]);
+ gl.clearDepth(1);
+ gl.clearStencil(0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+
+ // Generate vertices
+ vertices = es3fRasterizerDiscardTests.generateVertices(this.m_numPrimitives, this.m_rnd, this.m_drawMode);
+ var posLoc = gl.getAttribLocation(program, 'a_position');
+ var vertexArrays = [];
+ vertexArrays.push(new gluDrawUtil.VertexArrayBinding(gl.FLOAT, posLoc, 4, vertices.length / 4, vertices));
+ // Clear color to black for depth and stencil clear cases
+
+ if (this.m_caseType == es3fRasterizerDiscardTests.CaseType.CLEAR_DEPTH || this.m_caseType == es3fRasterizerDiscardTests.CaseType.CLEAR_STENCIL) {
+ gl.clearColor(BLACK_COLOR[0], BLACK_COLOR[1], BLACK_COLOR[2], BLACK_COLOR[3]);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ }
+
+ // Set fail values for color, depth and stencil
+
+ gl.uniform4fv(colorUnif, FAIL_COLOR_RED);
+ gl.clearColor(FAIL_COLOR_RED[0], FAIL_COLOR_RED[1], FAIL_COLOR_RED[2], FAIL_COLOR_RED[3]);
+ gl.clearDepth(FAIL_DEPTH);
+ gl.clearStencil(FAIL_STENCIL);
+
+ // Enable rasterizer discard
+
+ gl.enable(gl.RASTERIZER_DISCARD);
+ bufferedLogToConsole('Rasterizer discard enabled');
+
+ // Do to-be-discarded primitive draws and buffer clears
+
+ switch (this.m_caseType) {
+ case es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH:
+ gluDrawUtil.draw(gl, program, vertexArrays, new gluDrawUtil.PrimitiveList(this.m_drawMode, vertices.length / 4));
+ break;
+ case es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL:
+ gluDrawUtil.draw(gl, program, vertexArrays, new gluDrawUtil.PrimitiveList(this.m_drawMode, vertices.length / 4));
+ break;
+ case es3fRasterizerDiscardTests.CaseType.CLEAR_COLOR:
+ if (this.m_caseOptions.useFBO)
+ gl.clearBufferfv(gl.COLOR, 0, FAIL_COLOR_RED);
+ else
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ break;
+ case es3fRasterizerDiscardTests.CaseType.CLEAR_DEPTH:
+ if (this.m_caseOptions.useFBO)
+ gl.clearBufferfv(gl.DEPTH, 0, [FAIL_DEPTH]);
+ else
+ gl.clear(gl.DEPTH_BUFFER_BIT);
+ break;
+ case es3fRasterizerDiscardTests.CaseType.CLEAR_STENCIL:
+ if (this.m_caseOptions.useFBO)
+ gl.clearBufferiv(gl.STENCIL, 0, [FAIL_STENCIL]);
+ else
+ gl.clear(gl.STENCIL_BUFFER_BIT);
+ break;
+ default:
+ throw new Error('Invalid case type ' + this.m_caseType);
+ }
+
+ // Disable rasterizer discard
+
+ gl.disable(gl.RASTERIZER_DISCARD);
+ bufferedLogToConsole('Rasterizer discard disabled');
+
+ if (this.m_caseType == es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL) {
+ if (this.m_caseOptions.useFBO || gl.getContextAttributes().stencil) {
+ // Draw a full-screen square that colors all pixels red if they have stencil value 1.
+ var square = [new gluDrawUtil.VertexArrayBinding(gl.FLOAT, posLoc, 4, UNIT_SQUARE.length / 4, UNIT_SQUARE)];
+
+ gl.stencilFunc(gl.EQUAL, 1, 0xFF);
+ gluDrawUtil.draw(gl, program, square,
+ new gluDrawUtil.PrimitiveList(gluDrawUtil.primitiveType.TRIANGLE_STRIP, UNIT_SQUARE.length / 4));
+ }
+ // \note If no stencil buffers are present and test is rendering to default framebuffer, test will always pass.
+ } else if (this.m_caseType == es3fRasterizerDiscardTests.CaseType.CLEAR_DEPTH || this.m_caseType == es3fRasterizerDiscardTests.CaseType.CLEAR_STENCIL) {
+ // Draw pass-indicating primitives for depth and stencil clear cases
+
+ gl.uniform4fv(colorUnif, PASS_COLOR_BLUE);
+ gluDrawUtil.draw(gl, program, vertexArrays, new gluDrawUtil.PrimitiveList(this.m_drawMode, vertices.length / 4));
+ }
+
+ gl.finish();
+ gl.disable(gl.STENCIL_TEST);
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.SCISSOR_TEST);
+
+ // Read and check pixel data
+
+ var pixels = new tcuSurface.Surface();
+ pixels.readViewport(gl);
+
+ var width = pixels.getWidth();
+ var height = pixels.getHeight();
+
+ for (var y = 0; y < height; y++) {
+ for (var x = 0; x < width; x++) {
+ var pixel = pixels.getPixel(x, y);
+ if (pixel[2] != 0)
+ passColorFound = true;
+
+ if (pixel[0] != 0) {
+ failColorFound = true;
+ break;
+ }
+ }
+ if (failColorFound) break;
+ }
+
+ // Delete FBO if created
+
+ if (this.m_caseOptions.useFBO)
+ this.deleteFramebufferObject();
+
+ // Evaluate test result
+
+ var testOk = passColorFound && !failColorFound;
+
+ if (!testOk) {
+ tcuLogImage.logImage('Result image', '', pixels.getAccess());
+ testFailed('Primitive or buffer clear was not discarded.');
+ return tcuTestCase.IterateResult.STOP;
+ }
+ bufferedLogToConsole('Primitive or buffer clear was discarded correctly.');
+
+ if (++this.m_iterNdx < NUM_CASE_ITERATIONS)
+ return tcuTestCase.IterateResult.CONTINUE;
+
+ testPassed();
+ return tcuTestCase.IterateResult.STOP;
+};
+
+es3fRasterizerDiscardTests.init = function() {
+ var state = tcuTestCase.runner;
+ var testGroup = state.testCases;
+
+ var basic = tcuTestCase.newTest('basic', 'Rasterizer discard test for default framebuffer');
+ var scissor = tcuTestCase.newTest('scissor', 'Rasterizer discard test for default framebuffer with scissor test enabled');
+ var fbo = tcuTestCase.newTest('fbo', 'Rasterizer discard test for framebuffer object');
+
+ testGroup.addChild(basic);
+ testGroup.addChild(scissor);
+ testGroup.addChild(fbo);
+
+ // Default framebuffer cases
+
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_points', 'points', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, null, gluDrawUtil.primitiveType.POINTS));
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_lines', 'lines', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, null, gluDrawUtil.primitiveType.LINES));
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_line_strip', 'line_strip', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, null, gluDrawUtil.primitiveType.LINE_STRIP));
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_line_loop', 'line_loop', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, null, gluDrawUtil.primitiveType.LINE_LOOP));
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_triangles', 'triangles', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, null, gluDrawUtil.primitiveType.TRIANGLES));
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_triangle_strip', 'triangle_strip', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, null, gluDrawUtil.primitiveType.TRIANGLE_STRIP));
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_triangle_fan', 'triangle_fan', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, null, gluDrawUtil.primitiveType.TRIANGLE_FAN));
+
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_points', 'points', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, null, gluDrawUtil.primitiveType.POINTS));
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_lines', 'lines', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, null, gluDrawUtil.primitiveType.LINES));
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_line_strip', 'line_strip', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, null, gluDrawUtil.primitiveType.LINE_STRIP));
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_line_loop', 'line_loop', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, null, gluDrawUtil.primitiveType.LINE_LOOP));
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_triangles', 'triangles', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, null, gluDrawUtil.primitiveType.TRIANGLES));
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_triangle_strip', 'triangle_strip', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, null, gluDrawUtil.primitiveType.TRIANGLE_STRIP));
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_triangle_fan', 'triangle_fan', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, null, gluDrawUtil.primitiveType.TRIANGLE_FAN));
+
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('clear_color', 'clear_color', 4, es3fRasterizerDiscardTests.CaseType.CLEAR_COLOR, null));
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('clear_depth', 'clear_depth', 4, es3fRasterizerDiscardTests.CaseType.CLEAR_DEPTH, null));
+ basic.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('clear_stencil', 'clear_stencil', 4, es3fRasterizerDiscardTests.CaseType.CLEAR_STENCIL, null));
+
+ // Default framebuffer cases with scissor test enabled
+
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_points', 'points', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, es3fRasterizerDiscardTests.CaseOptions.SCISSOR, gluDrawUtil.primitiveType.POINTS));
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_lines', 'lines', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, es3fRasterizerDiscardTests.CaseOptions.SCISSOR, gluDrawUtil.primitiveType.LINES));
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_line_strip', 'line_strip', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, es3fRasterizerDiscardTests.CaseOptions.SCISSOR, gluDrawUtil.primitiveType.LINE_STRIP));
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_line_loop', 'line_loop', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, es3fRasterizerDiscardTests.CaseOptions.SCISSOR, gluDrawUtil.primitiveType.LINE_LOOP));
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_triangles', 'triangles', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, es3fRasterizerDiscardTests.CaseOptions.SCISSOR, gluDrawUtil.primitiveType.TRIANGLES));
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_triangle_strip', 'triangle_strip', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, es3fRasterizerDiscardTests.CaseOptions.SCISSOR, gluDrawUtil.primitiveType.TRIANGLE_STRIP));
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_triangle_fan', 'triangle_fan', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, es3fRasterizerDiscardTests.CaseOptions.SCISSOR, gluDrawUtil.primitiveType.TRIANGLE_FAN));
+
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_points', 'points', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, es3fRasterizerDiscardTests.CaseOptions.SCISSOR, gluDrawUtil.primitiveType.POINTS));
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_lines', 'lines', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, es3fRasterizerDiscardTests.CaseOptions.SCISSOR, gluDrawUtil.primitiveType.LINES));
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_line_strip', 'line_strip', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, es3fRasterizerDiscardTests.CaseOptions.SCISSOR, gluDrawUtil.primitiveType.LINE_STRIP));
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_line_loop', 'line_loop', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, es3fRasterizerDiscardTests.CaseOptions.SCISSOR, gluDrawUtil.primitiveType.LINE_LOOP));
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_triangles', 'triangles', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, es3fRasterizerDiscardTests.CaseOptions.SCISSOR, gluDrawUtil.primitiveType.TRIANGLES));
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_triangle_strip', 'triangle_strip', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, es3fRasterizerDiscardTests.CaseOptions.SCISSOR, gluDrawUtil.primitiveType.TRIANGLE_STRIP));
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_triangle_fan', 'triangle_fan', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, es3fRasterizerDiscardTests.CaseOptions.SCISSOR, gluDrawUtil.primitiveType.TRIANGLE_FAN));
+
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('clear_color', 'clear_color', 4, es3fRasterizerDiscardTests.CaseType.CLEAR_COLOR, es3fRasterizerDiscardTests.CaseOptions.SCISSOR));
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('clear_depth', 'clear_depth', 4, es3fRasterizerDiscardTests.CaseType.CLEAR_DEPTH, es3fRasterizerDiscardTests.CaseOptions.SCISSOR));
+ scissor.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('clear_stencil', 'clear_stencil', 4, es3fRasterizerDiscardTests.CaseType.CLEAR_STENCIL, es3fRasterizerDiscardTests.CaseOptions.SCISSOR));
+
+ // FBO cases
+
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_points', 'points', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, es3fRasterizerDiscardTests.CaseOptions.FBO, gluDrawUtil.primitiveType.POINTS));
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_lines', 'lines', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, es3fRasterizerDiscardTests.CaseOptions.FBO, gluDrawUtil.primitiveType.LINES));
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_line_strip', 'line_strip', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, es3fRasterizerDiscardTests.CaseOptions.FBO, gluDrawUtil.primitiveType.LINE_STRIP));
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_line_loop', 'line_loop', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, es3fRasterizerDiscardTests.CaseOptions.FBO, gluDrawUtil.primitiveType.LINE_LOOP));
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_triangles', 'triangles', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, es3fRasterizerDiscardTests.CaseOptions.FBO, gluDrawUtil.primitiveType.TRIANGLES));
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_triangle_strip', 'triangle_strip', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, es3fRasterizerDiscardTests.CaseOptions.FBO, gluDrawUtil.primitiveType.TRIANGLE_STRIP));
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_depth_triangle_fan', 'triangle_fan', 4, es3fRasterizerDiscardTests.CaseType.WRITE_DEPTH, es3fRasterizerDiscardTests.CaseOptions.FBO, gluDrawUtil.primitiveType.TRIANGLE_FAN));
+
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_points', 'points', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, es3fRasterizerDiscardTests.CaseOptions.FBO, gluDrawUtil.primitiveType.POINTS));
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_lines', 'lines', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, es3fRasterizerDiscardTests.CaseOptions.FBO, gluDrawUtil.primitiveType.LINES));
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_line_strip', 'line_strip', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, es3fRasterizerDiscardTests.CaseOptions.FBO, gluDrawUtil.primitiveType.LINE_STRIP));
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_line_loop', 'line_loop', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, es3fRasterizerDiscardTests.CaseOptions.FBO, gluDrawUtil.primitiveType.LINE_LOOP));
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_triangles', 'triangles', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, es3fRasterizerDiscardTests.CaseOptions.FBO, gluDrawUtil.primitiveType.TRIANGLES));
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_triangle_strip', 'triangle_strip', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, es3fRasterizerDiscardTests.CaseOptions.FBO, gluDrawUtil.primitiveType.TRIANGLE_STRIP));
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('write_stencil_triangle_fan', 'triangle_fan', 4, es3fRasterizerDiscardTests.CaseType.WRITE_STENCIL, es3fRasterizerDiscardTests.CaseOptions.FBO, gluDrawUtil.primitiveType.TRIANGLE_FAN));
+
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('clear_color', 'clear_color', 4, es3fRasterizerDiscardTests.CaseType.CLEAR_COLOR, es3fRasterizerDiscardTests.CaseOptions.FBO));
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('clear_depth', 'clear_depth', 4, es3fRasterizerDiscardTests.CaseType.CLEAR_DEPTH, es3fRasterizerDiscardTests.CaseOptions.FBO));
+ fbo.addChild(new es3fRasterizerDiscardTests.RasterizerDiscardCase('clear_stencil', 'clear_stencil', 4, es3fRasterizerDiscardTests.CaseType.CLEAR_STENCIL, es3fRasterizerDiscardTests.CaseOptions.FBO));
+};
+
+/**
+ * Create and execute the test cases
+ */
+es3fRasterizerDiscardTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var testName = 'rasterizer_discard';
+ var testDescription = 'Rasterizer Discard Tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.testCases = tcuTestCase.newTest(testName, testDescription, null);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ es3fRasterizerDiscardTests.init();
+ tcuTestCase.runTestCases();
+ } catch (err) {
+ testFailedOptions('Failed to run tests', false);
+ bufferedLogToConsole(err);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fRboStateQueryTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fRboStateQueryTests.js
new file mode 100644
index 0000000000..9903102990
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fRboStateQueryTests.js
@@ -0,0 +1,308 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fRboStateQueryTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('functional.gles3.es3fApiCase');
+goog.require('modules.shared.glsStateQuery');
+
+goog.scope(function() {
+var es3fRboStateQueryTests = functional.gles3.es3fRboStateQueryTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var glsStateQuery = modules.shared.glsStateQuery;
+var es3fApiCase = functional.gles3.es3fApiCase;
+var deRandom = framework.delibs.debase.deRandom;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+/**
+ * @this {es3fApiCase.ApiCase}
+ */
+var checkRenderbufferComponentSize = function(r, g, b, a, d, s) {
+ var referenceSizes = [r, g, b, a, d, s];
+ var paramNames = [
+ gl.RENDERBUFFER_RED_SIZE,
+ gl.RENDERBUFFER_GREEN_SIZE,
+ gl.RENDERBUFFER_BLUE_SIZE,
+ gl.RENDERBUFFER_ALPHA_SIZE,
+ gl.RENDERBUFFER_DEPTH_SIZE,
+ gl.RENDERBUFFER_STENCIL_SIZE
+ ];
+
+ for (var ndx = 0; ndx < referenceSizes.length; ++ndx) {
+ if (referenceSizes[ndx] == -1)
+ continue;
+ var value = /** @type {number} */ (gl.getRenderbufferParameter(gl.RENDERBUFFER, paramNames[ndx]));
+
+ this.check(value >= referenceSizes[ndx], 'Expected greater or equal to ' + referenceSizes[ndx] + ' got ' + value);
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fRboStateQueryTests.RboSizeCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fRboStateQueryTests.RboSizeCase, es3fApiCase.ApiCase);
+
+es3fRboStateQueryTests.RboSizeCase.prototype.test = function() {
+ var rnd = new deRandom.Random(0xabcdef);
+
+ var renderbufferID = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbufferID);
+
+ this.check(glsStateQuery.verifyRenderbuffer(gl.RENDERBUFFER_WIDTH, 0));
+ this.check(glsStateQuery.verifyRenderbuffer(gl.RENDERBUFFER_HEIGHT, 0));
+
+ var numIterations = 60;
+ for (var i = 0; i < numIterations; ++i) {
+ var w = rnd.getInt(0, 128);
+ var h = rnd.getInt(0, 128);
+
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGB8, w, h);
+
+ this.check(glsStateQuery.verifyRenderbuffer(gl.RENDERBUFFER_WIDTH, w));
+ this.check(glsStateQuery.verifyRenderbuffer(gl.RENDERBUFFER_HEIGHT, h));
+ }
+ gl.deleteRenderbuffer(renderbufferID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fRboStateQueryTests.RboInternalFormatCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fRboStateQueryTests.RboInternalFormatCase, es3fApiCase.ApiCase);
+
+es3fRboStateQueryTests.RboInternalFormatCase.prototype.test = function() {
+ var renderbufferID = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbufferID);
+
+ this.check(glsStateQuery.verifyRenderbuffer(gl.RENDERBUFFER_INTERNAL_FORMAT, gl.RGBA4));
+
+ var requiredColorformats = [
+ gl.R8, gl.RG8, gl.RGB8, gl.RGB565, gl.RGBA4, gl.RGB5_A1, gl.RGBA8, gl.RGB10_A2,
+ gl.RGB10_A2UI, gl.SRGB8_ALPHA8, gl.R8I, gl.R8UI, gl.R16I, gl.R16UI, gl.R32I, gl.R32UI,
+ gl.RG8I, gl.RG8UI, gl.RG16I, gl.RG16UI, gl.RG32I, gl.RG32UI, gl.RGBA8I, gl.RGBA8UI,
+ gl.RGBA16I, gl.RGBA16UI, gl.RGBA32I, gl.RGBA32UI
+ ];
+
+ for (var ndx = 0; ndx < requiredColorformats.length; ++ndx) {
+ gl.renderbufferStorage(gl.RENDERBUFFER, requiredColorformats[ndx], 128, 128);
+
+ this.check(glsStateQuery.verifyRenderbuffer(gl.RENDERBUFFER_INTERNAL_FORMAT, requiredColorformats[ndx]));
+ }
+ gl.deleteRenderbuffer(renderbufferID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fRboStateQueryTests.RboComponentSizeColorCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fRboStateQueryTests.RboComponentSizeColorCase, es3fApiCase.ApiCase);
+
+es3fRboStateQueryTests.RboComponentSizeColorCase.prototype.test = function() {
+ var renderbufferID = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbufferID);
+
+ checkRenderbufferComponentSize.bind(this, 0, 0, 0, 0, 0, 0);
+
+ var requiredColorFormats = [
+ // format, r, g, b, a
+ [gl.R8, 8, 0, 0, 0],
+ [gl.RG8, 8, 8, 0, 0],
+ [gl.RGB8, 8, 8, 8, 0],
+ [gl.RGB565, 5, 6, 5, 0],
+ [gl.RGBA4, 4, 4, 4, 4],
+ [gl.RGB5_A1, 5, 5, 5, 1],
+ [gl.RGBA8, 8, 8, 8, 8],
+ [gl.RGB10_A2, 10, 10, 10, 2],
+ [gl.RGB10_A2UI, 10, 10, 10, 2],
+ [gl.SRGB8_ALPHA8, 8, 8, 8, 8],
+ [gl.R8I, 8, 0, 0, 0],
+ [gl.R8UI, 8, 0, 0, 0],
+ [gl.R16I, 16, 0, 0, 0],
+ [gl.R16UI, 16, 0, 0, 0],
+ [gl.R32I, 32, 0, 0, 0],
+ [gl.R32UI, 32, 0, 0, 0],
+ [gl.RG8I, 8, 8, 0, 0],
+ [gl.RG8UI, 8, 8, 0, 0],
+ [gl.RG16I, 16, 16, 0, 0],
+ [gl.RG16UI, 16, 16, 0, 0],
+ [gl.RG32I, 32, 32, 0, 0],
+ [gl.RG32UI, 32, 32, 0, 0],
+ [gl.RGBA8I, 8, 8, 8, 8],
+ [gl.RGBA8UI, 8, 8, 8, 8],
+ [gl.RGBA16I, 16, 16, 16, 16],
+ [gl.RGBA16UI, 16, 16, 16, 16],
+ [gl.RGBA32I, 32, 32, 32, 32],
+ [gl.RGBA32UI, 32, 32, 32, 32]
+ ];
+
+ for (var ndx = 0; ndx < requiredColorFormats.length; ++ndx) {
+ gl.renderbufferStorage(gl.RENDERBUFFER, requiredColorFormats[ndx][0], 128, 128);
+
+ checkRenderbufferComponentSize.bind(this, requiredColorFormats[ndx][1], requiredColorFormats[ndx][2], requiredColorFormats[ndx][3], requiredColorFormats[ndx][4], -1, -1);
+ }
+ gl.deleteRenderbuffer(renderbufferID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fRboStateQueryTests.RboComponentSizeDepthCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fRboStateQueryTests.RboComponentSizeDepthCase, es3fApiCase.ApiCase);
+
+es3fRboStateQueryTests.RboComponentSizeDepthCase.prototype.test = function() {
+ var renderbufferID = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbufferID);
+
+ var requiredDepthFormats = [
+ // format, depth, stencil
+ [gl.DEPTH_COMPONENT16, 16, 0],
+ [gl.DEPTH_COMPONENT24, 24, 0],
+ [gl.DEPTH_COMPONENT32F, 32, 0],
+ [gl.DEPTH24_STENCIL8, 24, 8],
+ [gl.DEPTH32F_STENCIL8, 32, 8]
+ ];
+
+ for (var ndx = 0; ndx < requiredDepthFormats.length; ++ndx) {
+ gl.renderbufferStorage(gl.RENDERBUFFER, requiredDepthFormats[ndx][0], 128, 128);
+
+ checkRenderbufferComponentSize.bind(this, -1, -1, -1, -1, requiredDepthFormats[ndx][1], requiredDepthFormats[ndx][2]);
+ }
+
+ // STENCIL_INDEX8 is required, in that case sBits >= 8
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, 128, 128);
+
+ var value = /** @type {number} */ (gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_STENCIL_SIZE));
+ this.check(value >= 8, 'Expected greater or equal to 8; got ' + value);
+
+ gl.deleteRenderbuffer(renderbufferID);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fRboStateQueryTests.RboSamplesCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fRboStateQueryTests.RboSamplesCase, es3fApiCase.ApiCase);
+
+es3fRboStateQueryTests.RboSamplesCase.prototype.test = function() {
+ var rnd = new deRandom.Random(0xabcdef);
+
+ var renderbufferID = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbufferID);
+
+ this.check(glsStateQuery.verifyRenderbuffer(gl.RENDERBUFFER_SAMPLES, 0));
+
+ var max_samples = /** @type {number} */ (gl.getParameter(gl.MAX_SAMPLES));
+
+ // 0 samples is a special case
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 0, gl.RGBA8, 128, 128);
+
+ this.check(glsStateQuery.verifyRenderbuffer(gl.RENDERBUFFER_SAMPLES, 0));
+
+ // test [1, n] samples
+ for (var samples = 1; samples <= max_samples; ++samples) {
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, gl.RGBA8, 128, 128);
+ var value = /** @type {number} */ (gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_SAMPLES));
+ this.check(value >= samples, 'Expected greater or equal to ' + samples + ' got ' + value);
+ }
+
+ gl.deleteRenderbuffer(renderbufferID);
+};
+
+/**
+* @constructor
+* @extends {tcuTestCase.DeqpTest}
+*/
+es3fRboStateQueryTests.RboStateQueryTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'rbo', 'Rbo State Query tests');
+};
+
+es3fRboStateQueryTests.RboStateQueryTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fRboStateQueryTests.RboStateQueryTests.prototype.constructor = es3fRboStateQueryTests.RboStateQueryTests;
+
+es3fRboStateQueryTests.RboStateQueryTests.prototype.init = function() {
+ this.addChild(new es3fRboStateQueryTests.RboSizeCase('renderbuffer_size', 'RENDERBUFFER_WIDTH and RENDERBUFFER_HEIGHT'));
+ this.addChild(new es3fRboStateQueryTests.RboInternalFormatCase('renderbuffer_internal_format', 'RENDERBUFFER_INTERNAL_FORMAT'));
+ this.addChild(new es3fRboStateQueryTests.RboComponentSizeColorCase('renderbuffer_component_size_color', 'RENDERBUFFER_x_SIZE'));
+ this.addChild(new es3fRboStateQueryTests.RboComponentSizeDepthCase('renderbuffer_component_size_depth', 'RENDERBUFFER_x_SIZE'));
+ this.addChild(new es3fRboStateQueryTests.RboSamplesCase('renderbuffer_samples', 'RENDERBUFFER_SAMPLES'));
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fRboStateQueryTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fRboStateQueryTests.RboStateQueryTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fRboStateQueryTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fReadPixelTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fReadPixelTests.js
new file mode 100644
index 0000000000..7996c9196c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fReadPixelTests.js
@@ -0,0 +1,517 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fReadPixelTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluTextureUtil');
+
+goog.scope(function() {
+ var es3fReadPixelTests = functional.gles3.es3fReadPixelTests;
+ var tcuImageCompare = framework.common.tcuImageCompare;
+ var tcuRGBA = framework.common.tcuRGBA;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuTexture = framework.common.tcuTexture;
+ var tcuTextureUtil = framework.common.tcuTextureUtil;
+ var deString = framework.delibs.debase.deString;
+ var deRandom = framework.delibs.debase.deRandom;
+ var gluTextureUtil = framework.opengl.gluTextureUtil;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ * @param {boolean} chooseFormat
+ * @param {number} alignment
+ * @param {number} rowLength
+ * @param {number} skipRows
+ * @param {number} skipPixels
+ * @param {number=} format
+ * @param {number=} type
+ */
+ es3fReadPixelTests.ReadPixelsTest = function(name, description, chooseFormat, alignment, rowLength, skipRows, skipPixels, format, type) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+
+ /** @type {number} */ this.m_seed = deString.deStringHash(name);
+ /** @type {boolean} */ this.m_chooseFormat = chooseFormat;
+ /** @type {number} */ this.m_alignment = alignment;
+ /** @type {number} */ this.m_rowLength = rowLength;
+ /** @type {number} */ this.m_skipRows = skipRows;
+ /** @type {number} */ this.m_skipPixels = skipPixels;
+ /** @type {number} */ this.m_format = format !== undefined ? format : gl.RGBA;
+ /** @type {number} */ this.m_type = type !== undefined ? type : gl.UNSIGNED_BYTE;
+
+ /** @const {number} */ this.m_width = 13;
+ /** @const {number} */ this.m_height = 13;
+ };
+
+ es3fReadPixelTests.ReadPixelsTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fReadPixelTests.ReadPixelsTest.prototype.constructor = es3fReadPixelTests.ReadPixelsTest;
+
+ /**
+ * @param {tcuTexture.Texture2D} reference
+ */
+ es3fReadPixelTests.ReadPixelsTest.prototype.render = function(reference) {
+ var refType = /** @type {tcuTexture.ChannelType} */ (reference.getFormat().type);
+ /** @type {number} */ var width = reference.getWidth();
+ /** @type {number} */ var height = reference.getHeight();
+ /** @return {tcuTexture.PixelBufferAccess} */ var level0 = reference.getLevel(0);
+
+ // Create program
+ /** @type {string} */ var vertexSource = '#version 300 es\n' +
+ 'in mediump vec2 i_coord;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ '\tgl_Position = vec4(i_coord, 0.0, 1.0);\n' +
+ '}\n';
+
+ /** @type {string} */ var fragmentSource = '#version 300 es\n';
+
+ if (refType === tcuTexture.ChannelType.SIGNED_INT32)
+ fragmentSource += 'layout(location = 0) out mediump ivec4 o_color;\n';
+ else if (refType === tcuTexture.ChannelType.UNSIGNED_INT32)
+ fragmentSource += 'layout(location = 0) out mediump uvec4 o_color;\n';
+ else
+ fragmentSource += 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ fragmentSource += 'void main (void)\n' +
+ '{\n';
+
+ if (refType === tcuTexture.ChannelType.UNSIGNED_INT32)
+ fragmentSource += '\to_color = uvec4(0, 0, 0, 1000);\n';
+ else if (refType === tcuTexture.ChannelType.SIGNED_INT32)
+ fragmentSource += '\to_color = ivec4(0, 0, 0, 1000);\n';
+ else
+ fragmentSource += '\to_color = vec4(0.0, 0.0, 0.0, 1.0);\n';
+
+ fragmentSource += '}\n';
+
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexSource, fragmentSource));
+
+ assertMsgOptions(program.isOk(), 'Program failed', false, true);
+
+ gl.useProgram(program.getProgram());
+
+ // Render
+ /** @type {Array<number>} */ var coords = [
+ -0.5, -0.5,
+ 0.5, -0.5,
+ 0.5, 0.5,
+
+ 0.5, 0.5,
+ -0.5, 0.5,
+ -0.5, -0.5
+ ];
+ /** @type {number} */ var coordLoc;
+
+ coordLoc = gl.getAttribLocation(program.getProgram(), 'i_coord');
+
+ gl.enableVertexAttribArray(coordLoc);
+
+ /** @type {WebGLBuffer} */ var coordsGLBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, coordsGLBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(coords), gl.STATIC_DRAW);
+ gl.vertexAttribPointer(coordLoc, 2, gl.FLOAT, false, 0, 0);
+
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ gl.disableVertexAttribArray(coordLoc);
+
+ // Render reference
+
+ /** @type {number} */ var coordX1 = Math.floor((-0.5 * width / 2.0) + width / 2.0);
+ /** @type {number} */ var coordY1 = Math.floor((-0.5 * height / 2.0) + height / 2.0);
+ /** @type {number} */ var coordX2 = Math.floor((0.5 * width / 2.0) + width / 2.0);
+ /** @type {number} */ var coordY2 = Math.floor((0.5 * height / 2.0) + height / 2.0);
+
+ for (var x = 0; x < width; x++) {
+ if (x < coordX1 || x > coordX2)
+ continue;
+
+ for (var y = 0; y < height; y++) {
+ if (y >= coordY1 && y <= coordY2) {
+ if (refType === tcuTexture.ChannelType.SIGNED_INT32)
+ level0.setPixelInt([0, 0, 0, 1000], x, y);
+ else if (refType === tcuTexture.ChannelType.UNSIGNED_INT32)
+ level0.setPixelInt([0, 0, 0, 1000], x, y);
+ else
+ level0.setPixel([0.0, 0.0, 0.0, 1.0], x, y);
+ }
+ }
+ }
+ };
+
+ /**
+ * @return {{format: tcuTexture.TextureFormat, pixelSize: number, align: boolean}}
+ */
+ es3fReadPixelTests.ReadPixelsTest.prototype.getFormatInfo = function() {
+ if (this.m_chooseFormat) {
+ this.m_format = /** @type {number} */ (gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT));
+ this.m_type = /** @type {number} */ (gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE));
+ }
+
+ /** @type {tcuTexture.TextureFormat} */ var fmt = gluTextureUtil.mapGLTransferFormat(this.m_format, this.m_type);
+ /** @type {boolean} */ var align_;
+ switch (this.m_type) {
+ case gl.BYTE:
+ case gl.UNSIGNED_BYTE:
+ case gl.SHORT:
+ case gl.UNSIGNED_SHORT:
+ case gl.INT:
+ case gl.UNSIGNED_INT:
+ case gl.FLOAT:
+ case gl.HALF_FLOAT:
+ align_ = true;
+ break;
+
+ case gl.UNSIGNED_SHORT_5_6_5:
+ case gl.UNSIGNED_SHORT_4_4_4_4:
+ case gl.UNSIGNED_SHORT_5_5_5_1:
+ case gl.UNSIGNED_INT_2_10_10_10_REV:
+ case gl.UNSIGNED_INT_10F_11F_11F_REV:
+ case gl.UNSIGNED_INT_24_8:
+ case gl.FLOAT_32_UNSIGNED_INT_24_8_REV:
+ case gl.UNSIGNED_INT_5_9_9_9_REV:
+ align_ = false;
+ break;
+
+ default:
+ throw new Error('Unsupported format');
+ }
+
+ /** @type {number} */ var pxSize = fmt.getPixelSize();
+
+ return {format: fmt, pixelSize: pxSize, align: align_};
+ };
+
+ /**
+ * @param {tcuTexture.Texture2D} reference
+ * @param {boolean} align
+ * @param {number} pixelSize
+ * @return {goog.TypedArray}
+ */
+ es3fReadPixelTests.ReadPixelsTest.prototype.clearColor = function(reference, align, pixelSize) {
+ /** @type {number} */ var width = reference.getWidth();
+ /** @type {number} */ var height = reference.getHeight();
+ /** @return {tcuTexture.PixelBufferAccess} */ var level0 = reference.getLevel(0);
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(this.m_seed);
+ /** @type {WebGLFramebuffer} */ var framebuffer;
+ /** @type {WebGLRenderbuffer} */ var renderbuffer;
+ /** @type {number} */ var red;
+ /** @type {number} */ var green;
+ /** @type {number} */ var blue;
+ /** @type {number} */ var alpha;
+ /** @type {Array<number>} */ var color;
+
+ if (this.m_format === gl.RGBA_INTEGER) {
+ if (this.m_type === gl.UNSIGNED_INT) {
+ renderbuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA32UI, this.m_width, this.m_height);
+ } else if (this.m_type === gl.INT) {
+ renderbuffer = gl.createRenderbuffer();
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA32I, this.m_width, this.m_height);
+ } else
+ throw new Error('Type not supported');
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
+ framebuffer = gl.createFramebuffer();
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbuffer);
+ } else if (this.m_format === gl.RGBA || /*this.m_format === gl.BGRA ||*/ this.m_format === gl.RGB) {
+ // Empty
+ } else
+ throw new Error('Format not supported');
+
+ gl.viewport(0, 0, width, height);
+
+ // Clear color
+ if (this.m_format === gl.RGBA || this.m_format === gl.RGB) {
+ red = rnd.getFloat();
+ green = rnd.getFloat();
+ blue = rnd.getFloat();
+ alpha = rnd.getFloat();
+
+ color = [red, green, blue, alpha];
+ // Clear target
+ gl.clearColor(red, green, blue, alpha);
+ bufferedLogToConsole('ClearColor: (' + red + ', ' + green + ', ' + blue + ')');
+
+ gl.clearBufferfv(gl.COLOR, 0, color);
+
+ // Clear reference
+ level0.clear(color);
+ } else if (this.m_format === gl.RGBA_INTEGER) {
+ if (this.m_type === gl.INT) {
+ red = Math.abs(rnd.getInt());
+ green = Math.abs(rnd.getInt());
+ blue = Math.abs(rnd.getInt());
+ alpha = Math.abs(rnd.getInt());
+
+ color = [red, green, blue, alpha];
+ bufferedLogToConsole('ClearColor: (' + red + ', ' + green + ', ' + blue + ')');
+
+ gl.clearBufferiv(gl.COLOR, 0, color);
+
+ // Clear reference
+ level0.clear([red, green, blue, alpha]);
+ } else if (this.m_type === gl.UNSIGNED_INT) {
+ red = Math.abs(rnd.getInt());
+ green = Math.abs(rnd.getInt());
+ blue = Math.abs(rnd.getInt());
+ alpha = Math.abs(rnd.getInt());
+
+ color = [red, green, blue, alpha];
+ bufferedLogToConsole('ClearColor: (' + red + ', ' + green + ', ' + blue + ')');
+
+ gl.clearBufferuiv(gl.COLOR, 0, color);
+
+ // Clear reference
+ level0.clear(color);
+ } else
+ throw new Error('Type not supported.');
+ } else
+ throw new Error('Format not supported.');
+
+ this.render(reference);
+
+ /** @type {number} */ var rowWidth = (this.m_rowLength === 0 ? this.m_width : this.m_rowLength) + this.m_skipPixels;
+ /** @type {number} */ var rowPitch = (align ? this.m_alignment * Math.ceil(pixelSize * rowWidth / this.m_alignment) : rowWidth * pixelSize);
+
+ var arrayType = tcuTexture.getTypedArray(reference.getFormat().type);
+ /** @type {goog.TypedArray} */ var pixelData = new arrayType(rowPitch * (this.m_height + this.m_skipRows));
+ gl.readPixels(0, 0, this.m_width, this.m_height, this.m_format, this.m_type, pixelData);
+
+ if (framebuffer)
+ gl.deleteFramebuffer(framebuffer);
+
+ if (renderbuffer)
+ gl.deleteRenderbuffer(renderbuffer);
+
+ return pixelData;
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fReadPixelTests.ReadPixelsTest.prototype.iterate = function() {
+ /** @type {tcuTexture.TextureFormat} */ var format = new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8);
+ /** @type {number} */ var pixelSize;
+ /** @type {boolean} */ var align;
+
+ /** @type {{format: tcuTexture.TextureFormat, pixelSize: number, align: boolean}} */ var formatInfo = this.getFormatInfo();
+ format = formatInfo.format;
+ align = formatInfo.align;
+ pixelSize = formatInfo.pixelSize;
+
+ bufferedLogToConsole('Format: ' + this.m_format + ', Type: ' + this.m_type);
+
+ /** @type {tcuTexture.Texture2D} */ var reference = new tcuTexture.Texture2D(format, this.m_width, this.m_height);
+ reference.allocLevel(0);
+ /** @return {tcuTexture.PixelBufferAccess} */ var level0 = reference.getLevel(0);
+
+ this.m_alignment = /** @type {number} */ (gl.getParameter(gl.PACK_ALIGNMENT));
+ bufferedLogToConsole('gl.PACK_ALIGNMENT: ' + this.m_alignment);
+
+ this.m_rowLength = /** @type {number} */ (gl.getParameter(gl.PACK_ROW_LENGTH));
+ bufferedLogToConsole('gl.PACK_ROW_LENGTH: ' + this.m_rowLength);
+
+ this.m_skipRows = /** @type {number} */ (gl.getParameter(gl.PACK_SKIP_ROWS));
+ bufferedLogToConsole('gl.PACK_SKIP_ROWS: ' + this.m_skipRows);
+
+ this.m_skipPixels = /** @type {number} */ (gl.getParameter(gl.PACK_SKIP_PIXELS));
+ bufferedLogToConsole('gl.PACK_SKIP_PIXELS: ' + this.m_skipPixels);
+
+ gl.viewport(0, 0, this.m_width, this.m_height);
+
+ /** @type {goog.TypedArray} */ var pixelData = this.clearColor(reference, align, pixelSize);
+
+ /** @type {number} */ var rowWidth = (this.m_rowLength === 0 ? this.m_width : this.m_rowLength);
+ /** @type {number} */ var rowPitch = (align ? this.m_alignment * Math.ceil(pixelSize * rowWidth / this.m_alignment) : rowWidth * pixelSize);
+ /** @type {Array<number>} */ var formatBitDepths = [];
+ /** @type {number} */ var redThreshold;
+ /** @type {number} */ var greenThreshold;
+ /** @type {number} */ var blueThreshold;
+ /** @type {number} */ var alphaThreshold;
+ var redBits = /** @type {number} */ (gl.getParameter(gl.RED_BITS));
+ var blueBits = /** @type {number} */ (gl.getParameter(gl.BLUE_BITS));
+ var greenBits = /** @type {number} */ (gl.getParameter(gl.GREEN_BITS));
+ var alphaBits = /** @type {number} */ (gl.getParameter(gl.ALPHA_BITS));
+ /** @type {(tcuRGBA.RGBA|Array<number>)} */ var threshold;
+ /** @type {tcuTexture.PixelBufferAccess} */ var result;
+ // \note gl.RGBA_INTEGER uses always renderbuffers that are never multisampled. Otherwise default framebuffer is used.
+ if (this.m_format !== gl.RGBA_INTEGER && /** @type {number} */ (gl.getParameter(gl.SAMPLES)) > 1) {
+ formatBitDepths = tcuTextureUtil.getTextureFormatBitDepth(format);
+ redThreshold = Math.ceil(256.0 * (2.0 / (1 << Math.min(redBits, formatBitDepths[0]))));
+ greenThreshold = Math.ceil(256.0 * (2.0 / (1 << Math.min(greenBits, formatBitDepths[1]))));
+ blueThreshold = Math.ceil(256.0 * (2.0 / (1 << Math.min(blueBits, formatBitDepths[2]))));
+ alphaThreshold = Math.ceil(256.0 * (2.0 / (1 << Math.min(alphaBits, formatBitDepths[3]))));
+
+ result = tcuTexture.PixelBufferAccess.newFromTextureFormat(format, this.m_width, this.m_height, 1, rowPitch, 0, pixelData.buffer);
+ threshold = new tcuRGBA.RGBA([redThreshold, greenThreshold, blueThreshold, alphaThreshold]);
+ if (tcuImageCompare.bilinearCompare('Result', 'Result', level0, result, threshold))
+ testPassedOptions('Pass', true);
+ else
+ testFailedOptions('Fail', false);
+ } else {
+ formatBitDepths = tcuTextureUtil.getTextureFormatBitDepth(format);
+ redThreshold = 2.0 / (1 << Math.min(redBits, formatBitDepths[0]));
+ greenThreshold = 2.0 / (1 << Math.min(greenBits, formatBitDepths[1]));
+ blueThreshold = 2.0 / (1 << Math.min(blueBits, formatBitDepths[2]));
+ alphaThreshold = 2.0 / (1 << Math.min(alphaBits, formatBitDepths[3]));
+
+ // Compare
+ result = new tcuTexture.PixelBufferAccess({
+ format: format,
+ width: this.m_width,
+ height: this.m_height,
+ rowPitch: rowPitch,
+ data: pixelData.buffer,
+ offset: pixelSize * this.m_skipPixels + this.m_skipRows * rowPitch
+ });
+
+ threshold = [redThreshold, greenThreshold, blueThreshold, alphaThreshold];
+ if (tcuImageCompare.floatThresholdCompare('Result', 'Result', level0, result, threshold))
+ testPassedOptions('Pass', true);
+ else
+ testFailedOptions('Fail', false);
+ }
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fReadPixelTests.ReadPixelTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'read_pixels', 'ReadPixel tests');
+ };
+
+ es3fReadPixelTests.ReadPixelTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fReadPixelTests.ReadPixelTests.prototype.constructor = es3fReadPixelTests.ReadPixelTests;
+
+ es3fReadPixelTests.ReadPixelTests.prototype.init = function() {
+ /** @type {tcuTestCase.DeqpTest} */ var groupAlignment = tcuTestCase.newTest('alignment', 'Read pixels pack alignment parameter tests');
+
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_ubyte_1', '', false, 1, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE));
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_ubyte_2', '', false, 2, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE));
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_ubyte_4', '', false, 4, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE));
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_ubyte_8', '', false, 8, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE));
+
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_int_1', '', false, 1, 0, 0, 0, gl.RGBA_INTEGER, gl.INT));
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_int_2', '', false, 2, 0, 0, 0, gl.RGBA_INTEGER, gl.INT));
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_int_4', '', false, 4, 0, 0, 0, gl.RGBA_INTEGER, gl.INT));
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_int_8', '', false, 8, 0, 0, 0, gl.RGBA_INTEGER, gl.INT));
+
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_uint_1', '', false, 1, 0, 0, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT));
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_uint_2', '', false, 2, 0, 0, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT));
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_uint_4', '', false, 4, 0, 0, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT));
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_uint_8', '', false, 8, 0, 0, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT));
+
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('choose_1', '', true, 1, 0, 0, 0));
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('choose_2', '', true, 2, 0, 0, 0));
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('choose_4', '', true, 4, 0, 0, 0));
+ groupAlignment.addChild(new es3fReadPixelTests.ReadPixelsTest('choose_8', '', true, 8, 0, 0, 0));
+
+ this.addChild(groupAlignment);
+
+ /** @type {tcuTestCase.DeqpTest} */ var groupRowLength = tcuTestCase.newTest('rowlength', 'Read pixels rowlength test');
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_ubyte_17', '', false, 4, 17, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE));
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_ubyte_19', '', false, 4, 19, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE));
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_ubyte_23', '', false, 4, 23, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE));
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_ubyte_29', '', false, 4, 29, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE));
+
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_int_17', '', false, 4, 17, 0, 0, gl.RGBA_INTEGER, gl.INT));
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_int_19', '', false, 4, 19, 0, 0, gl.RGBA_INTEGER, gl.INT));
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_int_23', '', false, 4, 23, 0, 0, gl.RGBA_INTEGER, gl.INT));
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_int_29', '', false, 4, 29, 0, 0, gl.RGBA_INTEGER, gl.INT));
+
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_uint_17', '', false, 4, 17, 0, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT));
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_uint_19', '', false, 4, 19, 0, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT));
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_uint_23', '', false, 4, 23, 0, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT));
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_uint_29', '', false, 4, 29, 0, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT));
+
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('choose_17', '', true, 4, 17, 0, 0));
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('choose_19', '', true, 4, 19, 0, 0));
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('choose_23', '', true, 4, 23, 0, 0));
+ groupRowLength.addChild(new es3fReadPixelTests.ReadPixelsTest('choose_29', '', true, 4, 29, 0, 0));
+
+ this.addChild(groupRowLength);
+
+ /** @type {tcuTestCase.DeqpTest} */ var groupSkip = tcuTestCase.newTest('skip', 'Read pixels skip pixels and rows test');
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_ubyte_0_3', '', false, 4, 17, 0, 3, gl.RGBA, gl.UNSIGNED_BYTE));
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_ubyte_3_0', '', false, 4, 17, 3, 0, gl.RGBA, gl.UNSIGNED_BYTE));
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_ubyte_3_3', '', false, 4, 17, 3, 3, gl.RGBA, gl.UNSIGNED_BYTE));
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_ubyte_3_5', '', false, 4, 17, 3, 5, gl.RGBA, gl.UNSIGNED_BYTE));
+
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_int_0_3', '', false, 4, 17, 0, 3, gl.RGBA_INTEGER, gl.INT));
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_int_3_0', '', false, 4, 17, 3, 0, gl.RGBA_INTEGER, gl.INT));
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_int_3_3', '', false, 4, 17, 3, 3, gl.RGBA_INTEGER, gl.INT));
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_int_3_5', '', false, 4, 17, 3, 5, gl.RGBA_INTEGER, gl.INT));
+
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_uint_0_3', '', false, 4, 17, 0, 3, gl.RGBA_INTEGER, gl.UNSIGNED_INT));
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_uint_3_0', '', false, 4, 17, 3, 0, gl.RGBA_INTEGER, gl.UNSIGNED_INT));
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_uint_3_3', '', false, 4, 17, 3, 3, gl.RGBA_INTEGER, gl.UNSIGNED_INT));
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('rgba_uint_3_5', '', false, 4, 17, 3, 5, gl.RGBA_INTEGER, gl.UNSIGNED_INT));
+
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('choose_0_3', '', true, 4, 17, 0, 3));
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('choose_3_0', '', true, 4, 17, 3, 0));
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('choose_3_3', '', true, 4, 17, 3, 3));
+ groupSkip.addChild(new es3fReadPixelTests.ReadPixelsTest('choose_3_5', '', true, 4, 17, 3, 5));
+
+ this.addChild(groupSkip);
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fReadPixelTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fReadPixelTests.ReadPixelTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fReadPixelTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fSamplerObjectTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fSamplerObjectTests.js
new file mode 100644
index 0000000000..271a2186ae
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fSamplerObjectTests.js
@@ -0,0 +1,313 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fSamplerObjectTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('modules.shared.glsSamplerObjectTest');
+
+goog.scope(function() {
+
+var es3fSamplerObjectTests = functional.gles3.es3fSamplerObjectTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var glsSamplerObjectTest = modules.shared.glsSamplerObjectTest;
+
+ /** @type {WebGL2RenderingContext} */ var gl;
+
+ // TODO: implement glsSamplerObjectTest and validate constructors
+ es3fSamplerObjectTests.init = function() {
+ var testGroup = tcuTestCase.runner.testCases;
+ /** @type {Array<glsSamplerObjectTest.TestSpec>} */ var simpleTestCases = [
+ new glsSamplerObjectTest.TestSpec('diff_wrap_t', 'Different gl.TEXTURE_WRAP_T', gl.TEXTURE_2D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_wrap_s', 'Different gl.TEXTURE_WRAP_S', gl.TEXTURE_2D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_wrap_r', 'Different gl.TEXTURE_WRAP_R', gl.TEXTURE_2D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_min_filter', 'Different gl.TEXTURE_MIN_FILTER', gl.TEXTURE_2D,
+ new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_mag_filter', 'Different gl.TEXTURE_MAG_FILTER', gl.TEXTURE_2D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_max_lod', 'Different gl.TEXTURE_MAX_LOD', gl.TEXTURE_2D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, -999.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_min_lod', 'Different gl.TEXTURE_MIN_LOD', gl.TEXTURE_2D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 100.0, 1000.0)
+ )
+ ];
+
+ /** @type {tcuTestCase.DeqpTest} */ var simpleTexture2D = tcuTestCase.newTest('single_tex_2d', 'Simple 2D texture with sampler');
+
+ for (var testNdx = 0; testNdx < simpleTestCases.length; testNdx++)
+ simpleTexture2D.addChild(new glsSamplerObjectTest.TextureSamplerTest(simpleTestCases[testNdx]));
+
+ testGroup.addChild(simpleTexture2D);
+
+ /** @type {Array<glsSamplerObjectTest.TestSpec>} */ var multiTestCases = [
+ new glsSamplerObjectTest.TestSpec('diff_wrap_t', 'Different gl.TEXTURE_WRAP_T', gl.TEXTURE_2D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_wrap_s', 'Different gl.TEXTURE_WRAP_S', gl.TEXTURE_2D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_wrap_r', 'Different gl.TEXTURE_WRAP_R', gl.TEXTURE_2D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_min_filter', 'Different gl.TEXTURE_MIN_FILTER', gl.TEXTURE_2D,
+ new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_mag_filter', 'Different gl.TEXTURE_MAG_FILTER', gl.TEXTURE_2D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_max_lod', 'Different gl.TEXTURE_MAX_LOD', gl.TEXTURE_2D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, -999.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_min_lod', 'Different gl.TEXTURE_MIN_LOD', gl.TEXTURE_2D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 100.0, 1000.0)
+ )
+ ];
+
+ /** @type {tcuTestCase.DeqpTest} */ var multiTexture2D = tcuTestCase.newTest('multi_tex_2d', 'Multiple texture units 2D texture with sampler');
+
+ for (var testNdx = 0; testNdx < multiTestCases.length; testNdx++)
+ multiTexture2D.addChild(new glsSamplerObjectTest.MultiTextureSamplerTest(multiTestCases[testNdx]));
+
+ testGroup.addChild(multiTexture2D);
+
+ /** @type {Array<glsSamplerObjectTest.TestSpec>} */ var simpleTestCases3D = [
+ new glsSamplerObjectTest.TestSpec('diff_wrap_t', 'Different gl.TEXTURE_WRAP_T', gl.TEXTURE_3D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_wrap_s', 'Different gl.TEXTURE_WRAP_S', gl.TEXTURE_3D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_wrap_r', 'Different gl.TEXTURE_WRAP_R', gl.TEXTURE_3D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_min_filter', 'Different gl.TEXTURE_MIN_FILTER', gl.TEXTURE_3D,
+ new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_mag_filter', 'Different gl.TEXTURE_MAG_FILTER', gl.TEXTURE_3D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_max_lod', 'Different gl.TEXTURE_MAX_LOD', gl.TEXTURE_3D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, -999.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_min_lod', 'Different gl.TEXTURE_MIN_LOD', gl.TEXTURE_3D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 100.0, 1000.0)
+ )
+ ];
+
+ /** @type {tcuTestCase.DeqpTest} */ var simpleTexture3D = tcuTestCase.newTest('single_tex_3d', 'Simple 3D texture with sampler');
+
+ for (var testNdx = 0; testNdx < simpleTestCases3D.length; testNdx++)
+ simpleTexture3D.addChild(new glsSamplerObjectTest.TextureSamplerTest(simpleTestCases3D[testNdx]));
+
+ testGroup.addChild(simpleTexture3D);
+
+ /** @type {Array<glsSamplerObjectTest.TestSpec>} */ var multiTestCases3D = [
+ new glsSamplerObjectTest.TestSpec('diff_wrap_t', 'Different gl.TEXTURE_WRAP_T', gl.TEXTURE_3D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_wrap_s', 'Different gl.TEXTURE_WRAP_S', gl.TEXTURE_3D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_wrap_r', 'Different gl.TEXTURE_WRAP_R', gl.TEXTURE_3D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_min_filter', 'Different gl.TEXTURE_MIN_FILTER', gl.TEXTURE_3D,
+ new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_mag_filter', 'Different gl.TEXTURE_MAG_FILTER', gl.TEXTURE_3D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_max_lod', 'Different gl.TEXTURE_MAX_LOD', gl.TEXTURE_3D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, -999.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_min_lod', 'Different gl.TEXTURE_MIN_LOD', gl.TEXTURE_3D,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 100.0, 1000.0)
+ )
+ ];
+
+ /** @type {tcuTestCase.DeqpTest} */ var multiTexture3D = tcuTestCase.newTest('multi_tex_3d', 'Multiple texture units 3D texture with sampler');
+
+ for (var testNdx = 0; testNdx < multiTestCases3D.length; testNdx++)
+ multiTexture3D.addChild(new glsSamplerObjectTest.MultiTextureSamplerTest(multiTestCases3D[testNdx]));
+
+ testGroup.addChild(multiTexture3D);
+
+ /** @type {Array<glsSamplerObjectTest.TestSpec>} */ var simpleTestCasesCube = [
+ new glsSamplerObjectTest.TestSpec('diff_wrap_t', 'Different gl.TEXTURE_WRAP_T', gl.TEXTURE_CUBE_MAP,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_wrap_s', 'Different gl.TEXTURE_WRAP_S', gl.TEXTURE_CUBE_MAP,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_wrap_r', 'Different gl.TEXTURE_WRAP_R', gl.TEXTURE_CUBE_MAP,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_min_filter', 'Different gl.TEXTURE_MIN_FILTER', gl.TEXTURE_CUBE_MAP,
+ new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_mag_filter', 'Different gl.TEXTURE_MAG_FILTER', gl.TEXTURE_CUBE_MAP,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_max_lod', 'Different gl.TEXTURE_MAX_LOD', gl.TEXTURE_CUBE_MAP,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, -999.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_min_lod', 'Different gl.TEXTURE_MIN_LOD', gl.TEXTURE_CUBE_MAP,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 100.0, 1000.0)
+ )
+ ];
+
+ /** @type {tcuTestCase.DeqpTest} */ var simpleTextureCube = tcuTestCase.newTest('single_cubemap', 'Simple cubemap texture with sampler');
+
+ for (var testNdx = 0; testNdx < simpleTestCasesCube.length; testNdx++)
+ simpleTextureCube.addChild(new glsSamplerObjectTest.TextureSamplerTest(simpleTestCasesCube[testNdx]));
+
+ testGroup.addChild(simpleTextureCube);
+
+ /** @type {Array<glsSamplerObjectTest.TestSpec>} */ var multiTestCasesCube = [
+ new glsSamplerObjectTest.TestSpec('diff_wrap_t', 'Different gl.TEXTURE_WRAP_T', gl.TEXTURE_CUBE_MAP,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.MIRRORED_REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_wrap_s', 'Different gl.TEXTURE_WRAP_S', gl.TEXTURE_CUBE_MAP,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.MIRRORED_REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_wrap_r', 'Different gl.TEXTURE_WRAP_R', gl.TEXTURE_CUBE_MAP,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.MIRRORED_REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_min_filter', 'Different gl.TEXTURE_MIN_FILTER', gl.TEXTURE_CUBE_MAP,
+ new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.LINEAR, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_mag_filter', 'Different gl.TEXTURE_MAG_FILTER', gl.TEXTURE_CUBE_MAP,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.LINEAR, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_max_lod', 'Different gl.TEXTURE_MAX_LOD', gl.TEXTURE_CUBE_MAP,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, -1000.0, -999.0)
+ ),
+ new glsSamplerObjectTest.TestSpec('diff_min_lod', 'Different gl.TEXTURE_MIN_LOD', gl.TEXTURE_CUBE_MAP,
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 0.0, 1000.0),
+ new glsSamplerObjectTest.SamplingState(gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST, gl.REPEAT, gl.REPEAT, gl.REPEAT, 100.0, 1000.0)
+ )
+ ];
+
+ /** @type {tcuTestCase.DeqpTest} */ var multiTextureCube = tcuTestCase.newTest('multi_cubemap', 'Multiple texture units cubemap textures with sampler');
+
+ for (var testNdx = 0; testNdx < multiTestCasesCube.length; testNdx++)
+ multiTextureCube.addChild(new glsSamplerObjectTest.MultiTextureSamplerTest(multiTestCasesCube[testNdx]));
+
+ testGroup.addChild(multiTextureCube);
+ };
+
+ es3fSamplerObjectTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var testName = 'sampler_object';
+ var testDescription = 'Sampler Object Tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.setRoot(tcuTestCase.newTest(testName, testDescription, null));
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ es3fSamplerObjectTests.init();
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fSamplerObjectTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fSamplerStateQueryTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fSamplerStateQueryTests.js
new file mode 100644
index 0000000000..22cfde12aa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fSamplerStateQueryTests.js
@@ -0,0 +1,205 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fSamplerStateQueryTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('functional.gles3.es3fApiCase');
+goog.require('modules.shared.glsStateQuery');
+
+goog.scope(function() {
+var es3fSamplerStateQueryTests = functional.gles3.es3fSamplerStateQueryTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var glsStateQuery = modules.shared.glsStateQuery;
+var es3fApiCase = functional.gles3.es3fApiCase;
+var deRandom = framework.delibs.debase.deRandom;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fSamplerStateQueryTests.SamplerCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {WebGLSampler} */ this.m_sampler;
+};
+
+setParentClass(es3fSamplerStateQueryTests.SamplerCase, es3fApiCase.ApiCase);
+
+es3fSamplerStateQueryTests.SamplerCase.prototype.testSampler = function() {
+ throw new Error('Virtual function. Please override.');
+};
+
+es3fSamplerStateQueryTests.SamplerCase.prototype.test = function() {
+ this.m_sampler = gl.createSampler();
+
+ this.testSampler();
+
+ gl.deleteSampler(this.m_sampler);
+};
+
+/**
+ * @constructor
+ * @extends {es3fSamplerStateQueryTests.SamplerCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} valueName
+ * @param {number} initialValue
+ * @param {Array<number>} valueRange
+ */
+es3fSamplerStateQueryTests.SamplerModeCase = function(name, description, valueName, initialValue, valueRange) {
+ es3fSamplerStateQueryTests.SamplerCase.call(this, name, description);
+ this.m_valueName = valueName;
+ this.m_initialValue = initialValue;
+ this.m_valueRange = valueRange;
+};
+
+setParentClass(es3fSamplerStateQueryTests.SamplerModeCase, es3fSamplerStateQueryTests.SamplerCase);
+
+es3fSamplerStateQueryTests.SamplerModeCase.prototype.testSampler = function() {
+ this.check(glsStateQuery.verifySampler(this.m_sampler, this.m_valueName, this.m_initialValue));
+
+ for (var ndx = 0; ndx < this.m_valueRange.length; ++ndx) {
+ gl.samplerParameteri(this.m_sampler, this.m_valueName, this.m_valueRange[ndx]);
+
+ this.check(glsStateQuery.verifySampler(this.m_sampler, this.m_valueName, this.m_valueRange[ndx]));
+ }
+
+ //check unit conversions with float
+
+ for (var ndx = 0; ndx < this.m_valueRange.length; ++ndx) {
+ gl.samplerParameterf(this.m_sampler, this.m_valueName, this.m_valueRange[ndx]);
+
+ this.check(glsStateQuery.verifySampler(this.m_sampler, this.m_valueName, this.m_valueRange[ndx]));
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fSamplerStateQueryTests.SamplerCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} lodTarget
+ * @param {number} initialValue
+ */
+es3fSamplerStateQueryTests.SamplerLODCase = function(name, description, lodTarget, initialValue) {
+ es3fSamplerStateQueryTests.SamplerCase.call(this, name, description);
+ this.m_lodTarget = lodTarget;
+ this.m_initialValue = initialValue;
+};
+
+setParentClass(es3fSamplerStateQueryTests.SamplerLODCase, es3fSamplerStateQueryTests.SamplerCase);
+
+es3fSamplerStateQueryTests.SamplerLODCase.prototype.testSampler = function() {
+ var rnd = new deRandom.Random(0xabcdef);
+
+ this.check(glsStateQuery.verifySampler(this.m_sampler, this.m_lodTarget, this.m_initialValue));
+ var numIterations = 60;
+ for (var ndx = 0; ndx < numIterations; ++ndx) {
+ var ref = rnd.getFloat(-64000, 64000);
+
+ gl.samplerParameterf(this.m_sampler, this.m_lodTarget, ref);
+
+ this.check(glsStateQuery.verifySampler(this.m_sampler, this.m_lodTarget, ref));
+ }
+
+ // check unit conversions with int
+
+ for (var ndx = 0; ndx < numIterations; ++ndx) {
+ var ref = rnd.getInt(-64000, 64000);
+
+ gl.samplerParameteri(this.m_sampler, this.m_lodTarget, ref);
+
+ this.check(glsStateQuery.verifySampler(this.m_sampler, this.m_lodTarget, ref));
+ }
+};
+
+/**
+* @constructor
+* @extends {tcuTestCase.DeqpTest}
+*/
+es3fSamplerStateQueryTests.SamplerStateQueryTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'sampler', 'Sampler State Query tests');
+};
+
+es3fSamplerStateQueryTests.SamplerStateQueryTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fSamplerStateQueryTests.SamplerStateQueryTests.prototype.constructor = es3fSamplerStateQueryTests.SamplerStateQueryTests;
+
+es3fSamplerStateQueryTests.SamplerStateQueryTests.prototype.init = function() {
+ var wrapValues = [gl.CLAMP_TO_EDGE, gl.REPEAT, gl.MIRRORED_REPEAT];
+ this.addChild(new es3fSamplerStateQueryTests.SamplerModeCase('sampler_texture_wrap_s' , 'TEXTURE_WRAP_S',
+ gl.TEXTURE_WRAP_S, gl.REPEAT, wrapValues));
+ this.addChild(new es3fSamplerStateQueryTests.SamplerModeCase('sampler_texture_wrap_t' , 'TEXTURE_WRAP_T',
+ gl.TEXTURE_WRAP_T, gl.REPEAT, wrapValues));
+ this.addChild(new es3fSamplerStateQueryTests.SamplerModeCase('sampler_texture_wrap_r' , 'TEXTURE_WRAP_R',
+ gl.TEXTURE_WRAP_R, gl.REPEAT, wrapValues));
+
+ var magValues = [gl.NEAREST, gl.LINEAR];
+ this.addChild(new es3fSamplerStateQueryTests.SamplerModeCase('sampler_texture_mag_filter' , 'TEXTURE_MAG_FILTER',
+ gl.TEXTURE_MAG_FILTER, gl.LINEAR, magValues));
+
+ var minValues = [gl.NEAREST, gl.LINEAR, gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST_MIPMAP_LINEAR, gl.LINEAR_MIPMAP_NEAREST, gl.LINEAR_MIPMAP_LINEAR];
+ this.addChild(new es3fSamplerStateQueryTests.SamplerModeCase('sampler_texture_min_filter' , 'TEXTURE_MIN_FILTER',
+ gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR, minValues));
+
+ this.addChild(new es3fSamplerStateQueryTests.SamplerLODCase('sampler_texture_min_lod' , 'TEXTURE_MIN_LOD', gl.TEXTURE_MIN_LOD, -1000));
+ this.addChild(new es3fSamplerStateQueryTests.SamplerLODCase('sampler_texture_max_lod' , 'TEXTURE_MAX_LOD', gl.TEXTURE_MAX_LOD, 1000));
+
+ var modes = [gl.COMPARE_REF_TO_TEXTURE, gl.NONE];
+ this.addChild(new es3fSamplerStateQueryTests.SamplerModeCase('sampler_texture_compare_mode' , 'TEXTURE_COMPARE_MODE',
+ gl.TEXTURE_COMPARE_MODE, gl.NONE, modes));
+
+ var compareFuncs = [gl.LEQUAL, gl.GEQUAL, gl.LESS, gl.GREATER, gl.EQUAL, gl.NOTEQUAL, gl.ALWAYS, gl.NEVER];
+ this.addChild(new es3fSamplerStateQueryTests.SamplerModeCase('sampler_texture_compare_func' , 'TEXTURE_COMPARE_FUNC',
+ gl.TEXTURE_COMPARE_FUNC, gl.LEQUAL, compareFuncs));
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fSamplerStateQueryTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fSamplerStateQueryTests.SamplerStateQueryTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fSamplerStateQueryTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderApiTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderApiTests.js
new file mode 100644
index 0000000000..2768f0325b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderApiTests.js
@@ -0,0 +1,650 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fShaderApiTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('functional.gles3.es3fApiCase');
+
+goog.scope(function() {
+var es3fShaderApiTests = functional.gles3.es3fShaderApiTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var es3fApiCase = functional.gles3.es3fApiCase;
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+var deRandom = framework.delibs.debase.deRandom;
+var deString = framework.delibs.debase.deString;
+
+/** @type {WebGL2RenderingContext} */ var gl;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+var getSimpleShaderSource = function(shaderType) {
+ var simpleVertexShaderSource =
+ '#version 300 es\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(0.0);\n' +
+ '}\n';
+
+ var simpleFragmentShaderSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 o_fragColor;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ switch (shaderType) {
+ case gluShaderProgram.shaderType.VERTEX:
+ return simpleVertexShaderSource;
+ case gluShaderProgram.shaderType.FRAGMENT:
+ return simpleFragmentShaderSource;
+ default:
+ throw new Error('Invalid shader type');
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+es3fShaderApiTests.CreateShaderCase = function(name, description, shaderType) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ this.m_shaderType = shaderType;
+};
+
+setParentClass(es3fShaderApiTests.CreateShaderCase, es3fApiCase.ApiCase);
+
+es3fShaderApiTests.CreateShaderCase.prototype.test = function() {
+ var shaderObject = gl.createShader(gluShaderProgram.getGLShaderType(gl, this.m_shaderType));
+ this.check(shaderObject != null);
+ gl.deleteShader(shaderObject);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+es3fShaderApiTests.CompileShaderCase = function(name, description, shaderType) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ this.m_shaderType = shaderType;
+};
+
+setParentClass(es3fShaderApiTests.CompileShaderCase, es3fApiCase.ApiCase);
+
+es3fShaderApiTests.CompileShaderCase.prototype.checkCompileStatus = function(shader) {
+ var status = /** @type {boolean} */ (gl.getShaderParameter(shader, gl.COMPILE_STATUS));
+ return status;
+};
+
+es3fShaderApiTests.CompileShaderCase.prototype.test = function() {
+ var shaderObject = gl.createShader(gluShaderProgram.getGLShaderType(gl, this.m_shaderType));
+ var shaderSource = getSimpleShaderSource(this.m_shaderType);
+
+ this.check(shaderObject != null);
+
+ gl.shaderSource(shaderObject, shaderSource);
+ gl.compileShader(shaderObject);
+
+ this.check(this.checkCompileStatus(shaderObject));
+
+ gl.deleteShader(shaderObject);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+es3fShaderApiTests.ShaderSourceReplaceCase = function(name, description, shaderType) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ this.m_shaderType = shaderType;
+};
+
+setParentClass(es3fShaderApiTests.ShaderSourceReplaceCase, es3fApiCase.ApiCase);
+
+es3fShaderApiTests.ShaderSourceReplaceCase.prototype.generateFirstSource = function() {
+ return getSimpleShaderSource(this.m_shaderType);
+};
+
+es3fShaderApiTests.ShaderSourceReplaceCase.prototype.generateSecondSource = function() {
+ var source = '#version 300 es\n' +
+ 'precision mediump float;\n';
+
+ if (this.m_shaderType == gluShaderProgram.shaderType.FRAGMENT)
+ source += 'layout(location = 0) out mediump vec4 o_fragColor;\n';
+
+ source += 'void main()\n'+
+ '{\n'+
+ ' float variable = 1.0f;\n';
+
+ if (this.m_shaderType == gluShaderProgram.shaderType.VERTEX) source += ' gl_Position = vec4(variable);\n';
+ else if (this.m_shaderType == gluShaderProgram.shaderType.FRAGMENT) source += ' o_fragColor = vec4(variable);\n';
+
+ source += '}\n';
+
+ return source;
+};
+
+es3fShaderApiTests.ShaderSourceReplaceCase.prototype.test = function() {
+ var shaderObject = gl.createShader(gluShaderProgram.getGLShaderType(gl, this.m_shaderType));
+ var firstSource = this.generateFirstSource();
+ var secondSource = this.generateSecondSource();
+
+ this.check(shaderObject != null);
+
+ gl.shaderSource(shaderObject, firstSource);
+ this.check(firstSource == gl.getShaderSource(shaderObject));
+
+ gl.shaderSource(shaderObject, secondSource);
+ this.check(secondSource == gl.getShaderSource(shaderObject));
+
+ gl.deleteShader(shaderObject);
+};
+
+/**
+ * @constructor
+ */
+es3fShaderApiTests.SourceGenerator = function() {};
+
+/**
+ * @param {gluShaderProgram.shaderType} shaderType
+ * @return {string}
+ */
+es3fShaderApiTests.SourceGenerator.prototype.next = function(shaderType) {
+ throw new Error('Virtual function. Please override');
+};
+
+/**
+ * @param {gluShaderProgram.shaderType} shaderType
+ * @return {boolean}
+ */
+es3fShaderApiTests.SourceGenerator.prototype.finished = function(shaderType) {
+ throw new Error('Virtual function. Please override');
+};
+
+/**
+ * @constructor
+ * @extends {es3fShaderApiTests.SourceGenerator}
+ */
+es3fShaderApiTests.ConstantShaderGenerator = function(rnd) {
+ es3fShaderApiTests.SourceGenerator.call(this);
+ this.m_rnd = rnd;
+};
+
+setParentClass(es3fShaderApiTests.ConstantShaderGenerator, es3fShaderApiTests.SourceGenerator);
+
+es3fShaderApiTests.SourceGenerator.prototype.next = function(shaderType) {
+ var value = this.m_rnd.getFloat(0.0, 1.0);
+ var outputName = (shaderType == gluShaderProgram.shaderType.VERTEX) ? 'gl_Position' : 'o_fragColor';
+
+ var out = '#version 300 es\n';
+
+ if (shaderType == gluShaderProgram.shaderType.FRAGMENT)
+ out += 'layout(location = 0) out mediump vec4 o_fragColor;\n';
+
+ out += 'void main (void)\n';
+ out += '{\n';
+ out += ' ' + outputName + ' = vec4(' + value + ');\n';
+ out += '}\n';
+
+ return out;
+};
+
+es3fShaderApiTests.SourceGenerator.prototype.finished = function(shaderType) {
+ return false;
+};
+
+// Shader allocation utility
+
+/**
+ * @constructor
+ * @param {es3fShaderApiTests.SourceGenerator} generator
+ */
+es3fShaderApiTests.ShaderAllocator = function(generator) {
+ this.m_srcGen = generator;
+ this.m_shaders = {};
+};
+
+/**
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+es3fShaderApiTests.ShaderAllocator.prototype.createShader = function(shaderType) {
+ var shader = new gluShaderProgram.Shader(gl, shaderType);
+ this.m_shaders[shaderType] = shader;
+ this.setSource(shaderType);
+ return shader;
+};
+
+/**
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+es3fShaderApiTests.ShaderAllocator.prototype.deleteShader = function(shaderType) {
+ this.m_shaders[shaderType].destroy();
+ this.m_shaders[shaderType] = null;
+};
+
+/**
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+es3fShaderApiTests.ShaderAllocator.prototype.setSource = function(shaderType) {
+ var source = this.m_srcGen.next(shaderType);
+ this.m_shaders[shaderType].setSources(source);
+};
+
+/**
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+es3fShaderApiTests.ShaderAllocator.prototype.get = function(shaderType) {
+ return this.m_shaders[shaderType];
+};
+
+// Base class for simple program API tests
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderApiTests.SimpleProgramCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ this.m_vertShader = null;
+ this.m_fragShader = null;
+ this.m_program = null;
+};
+
+setParentClass(es3fShaderApiTests.SimpleProgramCase, es3fApiCase.ApiCase);
+
+es3fShaderApiTests.SimpleProgramCase.prototype.compileShaders = function() {
+ var vertSource = getSimpleShaderSource(gluShaderProgram.shaderType.VERTEX);
+ var fragSource = getSimpleShaderSource(gluShaderProgram.shaderType.FRAGMENT);
+
+ var vertShader = gl.createShader(gl.VERTEX_SHADER);
+ var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
+
+ this.check(vertShader != null);
+ this.check(fragShader != null);
+
+ gl.shaderSource(vertShader, vertSource);
+ gl.compileShader(vertShader);
+
+ gl.shaderSource(fragShader, fragSource);
+ gl.compileShader(fragShader);
+
+ this.m_vertShader = vertShader;
+ this.m_fragShader = fragShader;
+};
+
+es3fShaderApiTests.SimpleProgramCase.prototype.linkProgram = function() {
+ var program = gl.createProgram();
+
+ this.check(program != null);
+
+ gl.attachShader(program, this.m_vertShader);
+ gl.attachShader(program, this.m_fragShader);
+
+ gl.linkProgram(program);
+
+ this.m_program = program;
+};
+
+es3fShaderApiTests.SimpleProgramCase.prototype.cleanup = function() {
+ gl.deleteShader(this.m_vertShader);
+ gl.deleteShader(this.m_fragShader);
+ gl.deleteProgram(this.m_program);
+};
+
+/**
+ * @constructor
+ * @extends {es3fShaderApiTests.SimpleProgramCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderApiTests.DeleteShaderCase = function(name, description) {
+ es3fShaderApiTests.SimpleProgramCase.call(this, name, description);
+};
+
+setParentClass(es3fShaderApiTests.DeleteShaderCase, es3fShaderApiTests.SimpleProgramCase);
+
+es3fShaderApiTests.DeleteShaderCase.prototype.checkDeleteStatus = function(shader) {
+ var status = /** @type {boolean} */ (gl.getShaderParameter(shader, gl.DELETE_STATUS));
+ return status;
+};
+
+es3fShaderApiTests.DeleteShaderCase.prototype.deleteShaders = function() {
+ gl.deleteShader(this.m_vertShader);
+ gl.deleteShader(this.m_fragShader);
+};
+
+es3fShaderApiTests.DeleteShaderCase.prototype.test = function() {
+ this.compileShaders();
+ this.linkProgram();
+
+ this.deleteShaders();
+
+ this.check(this.checkDeleteStatus(this.m_vertShader) && this.checkDeleteStatus(this.m_fragShader));
+
+ gl.deleteProgram(this.m_program);
+
+ this.check(!(gl.isShader(this.m_vertShader) || gl.isShader(this.m_fragShader)));
+};
+
+/**
+ * @constructor
+ * @extends {es3fShaderApiTests.SimpleProgramCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderApiTests.LinkVertexFragmentCase = function(name, description) {
+ es3fShaderApiTests.SimpleProgramCase.call(this, name, description);
+};
+
+setParentClass(es3fShaderApiTests.LinkVertexFragmentCase, es3fShaderApiTests.SimpleProgramCase);
+
+es3fShaderApiTests.LinkVertexFragmentCase.prototype.checkLinkStatus = function(program) {
+ var status = /** @type {boolean} */ (gl.getProgramParameter(program, gl.LINK_STATUS));
+ return status;
+};
+
+es3fShaderApiTests.LinkVertexFragmentCase.prototype.test = function() {
+ this.compileShaders();
+ this.linkProgram();
+
+ this.check(this.checkLinkStatus(this.m_program), 'Fail, expected LINK_STATUS to be TRUE.');
+
+ this.cleanup();
+};
+
+// Base class for program state persistence cases
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+es3fShaderApiTests.ProgramStateCase = function(name, description, shaderType) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ this.m_shaderType = shaderType;
+ this.m_rnd = new deRandom.Random(deString.deStringHash(name) ^ 0x713de0ca);
+};
+
+setParentClass(es3fShaderApiTests.ProgramStateCase, es3fApiCase.ApiCase);
+
+/**
+ * @param {gluShaderProgram.Program} program
+ * @param {es3fShaderApiTests.ShaderAllocator} shaders
+ */
+es3fShaderApiTests.ProgramStateCase.prototype.buildProgram = function(program, shaders) {
+ var vertShader = shaders.createShader(gluShaderProgram.shaderType.VERTEX);
+ var fragShader = shaders.createShader(gluShaderProgram.shaderType.FRAGMENT);
+
+ vertShader.compile();
+ fragShader.compile();
+
+ program.attachShader(vertShader.getShader());
+ program.attachShader(fragShader.getShader());
+ program.link();
+};
+
+/**
+ * @param {gluShaderProgram.Program} program
+ * @param {gluShaderProgram.ProgramInfo} reference
+ */
+es3fShaderApiTests.ProgramStateCase.prototype.verify = function(program, reference) {
+ var programInfo = program.getInfo();
+ this.check(programInfo.linkOk, 'Fail, link status may only change as a result of linking');
+
+ this.check(programInfo.linkTimeUs == reference.linkTimeUs, 'Fail, reported link time changed.');
+
+ this.check(programInfo.infoLog == reference.infoLog, 'Fail, program infolog changed.');
+};
+
+es3fShaderApiTests.ProgramStateCase.prototype.test = function() {
+ var sourceGen = new es3fShaderApiTests.ConstantShaderGenerator(this.m_rnd);
+
+ var shaders = new es3fShaderApiTests.ShaderAllocator(sourceGen);
+ var program = new gluShaderProgram.Program(gl);
+
+ this.buildProgram(program, shaders);
+
+ if (program.getLinkStatus()) {
+ var programInfo = program.getInfo();
+
+ this.executeForProgram(program, shaders);
+
+ this.verify(program, programInfo);
+
+ } else{
+ this.check(false, "Fail, couldn't link program.");
+ }
+
+};
+
+/**
+ * @constructor
+ * @extends {es3fShaderApiTests.ProgramStateCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+es3fShaderApiTests.ProgramStateDetachShaderCase = function(name, description, shaderType) {
+ es3fShaderApiTests.ProgramStateCase.call(this, name, description, shaderType);
+};
+
+setParentClass(es3fShaderApiTests.ProgramStateDetachShaderCase, es3fShaderApiTests.ProgramStateCase);
+
+es3fShaderApiTests.ProgramStateDetachShaderCase.prototype.executeForProgram = function(program, shaders) {
+ var caseShader = shaders.get(this.m_shaderType);
+ program.detachShader(caseShader.getShader());
+};
+
+/**
+ * @constructor
+ * @extends {es3fShaderApiTests.ProgramStateCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+es3fShaderApiTests.ProgramStateReattachShaderCase = function(name, description, shaderType) {
+ es3fShaderApiTests.ProgramStateCase.call(this, name, description, shaderType);
+};
+
+setParentClass(es3fShaderApiTests.ProgramStateReattachShaderCase, es3fShaderApiTests.ProgramStateCase);
+
+es3fShaderApiTests.ProgramStateReattachShaderCase.prototype.executeForProgram = function(program, shaders) {
+ var caseShader = shaders.get(this.m_shaderType);
+ program.detachShader(caseShader.getShader());
+ program.attachShader(caseShader.getShader());
+};
+
+/**
+ * @constructor
+ * @extends {es3fShaderApiTests.ProgramStateCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+es3fShaderApiTests.ProgramStateDeleteShaderCase = function(name, description, shaderType) {
+ es3fShaderApiTests.ProgramStateCase.call(this, name, description, shaderType);
+};
+
+setParentClass(es3fShaderApiTests.ProgramStateDeleteShaderCase, es3fShaderApiTests.ProgramStateCase);
+
+es3fShaderApiTests.ProgramStateDeleteShaderCase.prototype.executeForProgram = function(program, shaders) {
+ var caseShader = shaders.get(this.m_shaderType);
+ program.detachShader(caseShader.getShader());
+ shaders.deleteShader(this.m_shaderType);
+};
+
+/**
+ * @constructor
+ * @extends {es3fShaderApiTests.ProgramStateCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+es3fShaderApiTests.ProgramStateReplaceShaderCase = function(name, description, shaderType) {
+ es3fShaderApiTests.ProgramStateCase.call(this, name, description, shaderType);
+};
+
+setParentClass(es3fShaderApiTests.ProgramStateReplaceShaderCase, es3fShaderApiTests.ProgramStateCase);
+
+es3fShaderApiTests.ProgramStateReplaceShaderCase.prototype.executeForProgram = function(program, shaders) {
+ var caseShader = shaders.get(this.m_shaderType);
+ program.detachShader(caseShader.getShader());
+ shaders.deleteShader(this.m_shaderType);
+ program.attachShader(shaders.createShader(this.m_shaderType).getShader());
+};
+
+/**
+ * @constructor
+ * @extends {es3fShaderApiTests.ProgramStateCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+es3fShaderApiTests.ProgramStateRecompileShaderCase = function(name, description, shaderType) {
+ es3fShaderApiTests.ProgramStateCase.call(this, name, description, shaderType);
+};
+
+setParentClass(es3fShaderApiTests.ProgramStateRecompileShaderCase, es3fShaderApiTests.ProgramStateCase);
+
+es3fShaderApiTests.ProgramStateRecompileShaderCase.prototype.executeForProgram = function(program, shaders) {
+ var caseShader = shaders.get(this.m_shaderType);
+ caseShader.compile();
+};
+
+/**
+ * @constructor
+ * @extends {es3fShaderApiTests.ProgramStateCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+es3fShaderApiTests.ProgramStateReplaceSourceCase = function(name, description, shaderType) {
+ es3fShaderApiTests.ProgramStateCase.call(this, name, description, shaderType);
+};
+
+setParentClass(es3fShaderApiTests.ProgramStateReplaceSourceCase, es3fShaderApiTests.ProgramStateCase);
+
+es3fShaderApiTests.ProgramStateReplaceSourceCase.prototype.executeForProgram = function(program, shaders) {
+ var caseShader = shaders.get(this.m_shaderType);
+ shaders.setSource(this.m_shaderType);
+ caseShader.compile();
+};
+
+/**
+* @constructor
+* @extends {tcuTestCase.DeqpTest}
+*/
+es3fShaderApiTests.ShaderApiTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'shader_api', 'Shader API Cases');
+};
+
+es3fShaderApiTests.ShaderApiTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fShaderApiTests.ShaderApiTests.prototype.constructor = es3fShaderApiTests.ShaderApiTests;
+
+es3fShaderApiTests.ShaderApiTests.prototype.init = function() {
+ // create and delete shaders
+ var createDeleteGroup = new tcuTestCase.DeqpTest('create_delete', 'glCreateShader() tests');
+ this.addChild(createDeleteGroup);
+
+ createDeleteGroup.addChild(new es3fShaderApiTests.CreateShaderCase('create_vertex_shader', 'Create vertex shader object', gluShaderProgram.shaderType.VERTEX));
+ createDeleteGroup.addChild(new es3fShaderApiTests.CreateShaderCase('create_fragment_shader', 'Create fragment shader object', gluShaderProgram.shaderType.FRAGMENT));
+
+ createDeleteGroup.addChild(new es3fShaderApiTests.DeleteShaderCase('delete_vertex_fragment', 'Delete vertex shader and fragment shader'));
+
+ // compile and link
+ var compileLinkGroup = new tcuTestCase.DeqpTest('compile_link', 'Compile and link tests');
+ this.addChild(compileLinkGroup);
+
+ compileLinkGroup.addChild(new es3fShaderApiTests.CompileShaderCase('compile_vertex_shader', 'Compile vertex shader', gluShaderProgram.shaderType.VERTEX));
+ compileLinkGroup.addChild(new es3fShaderApiTests.CompileShaderCase('compile_fragment_shader', 'Compile fragment shader', gluShaderProgram.shaderType.FRAGMENT));
+
+ compileLinkGroup.addChild(new es3fShaderApiTests.LinkVertexFragmentCase('link_vertex_fragment', 'Link vertex and fragment shaders'));
+
+ // shader source
+ var shaderSourceGroup = new tcuTestCase.DeqpTest('shader_source', 'glShaderSource() tests');
+ this.addChild(shaderSourceGroup);
+ shaderSourceGroup.addChild(new es3fShaderApiTests.ShaderSourceReplaceCase('replace_source_vertex', 'Replace source code of vertex shader', gluShaderProgram.shaderType.VERTEX));
+ shaderSourceGroup.addChild(new es3fShaderApiTests.ShaderSourceReplaceCase('replace_source_fragment', 'Replace source code of fragment shader', gluShaderProgram.shaderType.FRAGMENT));
+
+ // link status and infolog
+ var linkStatusGroup = new tcuTestCase.DeqpTest('program_state', 'Program state persistence tests');
+ this.addChild(linkStatusGroup);
+
+ linkStatusGroup.addChild(new es3fShaderApiTests.ProgramStateDetachShaderCase('detach_shader_vertex', 'detach vertex shader', gluShaderProgram.shaderType.VERTEX));
+ linkStatusGroup.addChild(new es3fShaderApiTests.ProgramStateReattachShaderCase('reattach_shader_vertex', 'reattach vertex shader', gluShaderProgram.shaderType.VERTEX));
+ linkStatusGroup.addChild(new es3fShaderApiTests.ProgramStateDeleteShaderCase('delete_shader_vertex', 'delete vertex shader', gluShaderProgram.shaderType.VERTEX));
+ linkStatusGroup.addChild(new es3fShaderApiTests.ProgramStateReplaceShaderCase('replace_shader_vertex', 'replace vertex shader object', gluShaderProgram.shaderType.VERTEX));
+ linkStatusGroup.addChild(new es3fShaderApiTests.ProgramStateRecompileShaderCase('recompile_shader_vertex', 'recompile vertex shader', gluShaderProgram.shaderType.VERTEX));
+ linkStatusGroup.addChild(new es3fShaderApiTests.ProgramStateReplaceSourceCase('replace_source_vertex', 'replace vertex shader source', gluShaderProgram.shaderType.VERTEX));
+
+ linkStatusGroup.addChild(new es3fShaderApiTests.ProgramStateDetachShaderCase('detach_shader_fragment', 'detach fragment shader', gluShaderProgram.shaderType.FRAGMENT));
+ linkStatusGroup.addChild(new es3fShaderApiTests.ProgramStateReattachShaderCase('reattach_shader_fragment', 'reattach fragment shader', gluShaderProgram.shaderType.FRAGMENT));
+ linkStatusGroup.addChild(new es3fShaderApiTests.ProgramStateDeleteShaderCase('delete_shader_fragment', 'delete fragment shader', gluShaderProgram.shaderType.FRAGMENT));
+ linkStatusGroup.addChild(new es3fShaderApiTests.ProgramStateReplaceShaderCase('replace_shader_fragment', 'replace fragment shader object', gluShaderProgram.shaderType.FRAGMENT));
+ linkStatusGroup.addChild(new es3fShaderApiTests.ProgramStateRecompileShaderCase('recompile_shader_fragment', 'recompile fragment shader', gluShaderProgram.shaderType.FRAGMENT));
+ linkStatusGroup.addChild(new es3fShaderApiTests.ProgramStateReplaceSourceCase('replace_source_fragment', 'replace fragment shader source', gluShaderProgram.shaderType.FRAGMENT));
+
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fShaderApiTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fShaderApiTests.ShaderApiTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fShaderApiTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderBuiltinVarTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderBuiltinVarTests.js
new file mode 100644
index 0000000000..c696c6c12e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderBuiltinVarTests.js
@@ -0,0 +1,1109 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fShaderBuiltinVarTests');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuLogImage');
+goog.require('framework.common.tcuPixelFormat');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.opengl.gluDrawUtil');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluVarType');
+goog.require('framework.opengl.simplereference.sglrReferenceContext');
+goog.require('framework.opengl.simplereference.sglrShaderProgram');
+goog.require('framework.referencerenderer.rrFragmentOperations');
+goog.require('framework.referencerenderer.rrGenericVector');
+goog.require('framework.referencerenderer.rrMultisamplePixelBufferAccess');
+goog.require('framework.referencerenderer.rrRenderer');
+goog.require('framework.referencerenderer.rrRenderState');
+goog.require('framework.referencerenderer.rrShadingContext');
+goog.require('framework.referencerenderer.rrVertexAttrib');
+goog.require('framework.referencerenderer.rrVertexPacket');
+goog.require('modules.shared.glsShaderRenderCase');
+goog.require('modules.shared.glsShaderExecUtil');
+
+goog.scope(function() {
+ var es3fShaderBuiltinVarTests = functional.gles3.es3fShaderBuiltinVarTests;
+ var deMath = framework.delibs.debase.deMath;
+ var deString = framework.delibs.debase.deString;
+ var deRandom = framework.delibs.debase.deRandom;
+ var glsShaderExecUtil = modules.shared.glsShaderExecUtil;
+ var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluDrawUtil = framework.opengl.gluDrawUtil;
+ var gluVarType = framework.opengl.gluVarType;
+ var tcuPixelFormat = framework.common.tcuPixelFormat;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuTexture = framework.common.tcuTexture;
+ var tcuLogImage = framework.common.tcuLogImage;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuImageCompare = framework.common.tcuImageCompare;
+ var tcuRGBA = framework.common.tcuRGBA;
+ var rrGenericVector = framework.referencerenderer.rrGenericVector;
+ var rrFragmentOperations = framework.referencerenderer.rrFragmentOperations;
+ var rrMultisamplePixelBufferAccess = framework.referencerenderer.rrMultisamplePixelBufferAccess;
+ var rrRenderer = framework.referencerenderer.rrRenderer;
+ var rrRenderState = framework.referencerenderer.rrRenderState;
+ var rrShadingContext = framework.referencerenderer.rrShadingContext;
+ var rrVertexAttrib = framework.referencerenderer.rrVertexAttrib;
+ var rrVertexPacket = framework.referencerenderer.rrVertexPacket;
+ var sglrShaderProgram = framework.opengl.simplereference.sglrShaderProgram;
+ var sglrReferenceContext = framework.opengl.simplereference.sglrReferenceContext;
+
+ /** @typedef {function():number} */ es3fShaderBuiltinVarTests.GetConstantValueFunc;
+
+ /**
+ * @param {number} pname
+ * @return {number} getParameter returns values of any kind
+ */
+ es3fShaderBuiltinVarTests.getInteger = function(pname) {
+ return /** @type {number} */ (gl.getParameter(pname));
+ };
+
+ /**
+ * @param {number} pname
+ * @return {number} forcing number
+ */
+ es3fShaderBuiltinVarTests.getVectorsFromComps = function(pname) {
+ var value = /** @type {number} */ (gl.getParameter(pname));
+ assertMsgOptions(value%4 === 0, 'Expected value to be divisible by 4.', false, true);
+ return value / 4;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * @param {string} varName
+ * @param {es3fShaderBuiltinVarTests.GetConstantValueFunc} getValue
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase = function(name, desc, varName, getValue, shaderType) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ /** @type {string} */ this.m_varName = varName;
+ /** @type {es3fShaderBuiltinVarTests.GetConstantValueFunc} */ this.m_getValue = getValue;
+ /** @type {gluShaderProgram.shaderType} */ this.m_shaderType = shaderType;
+ };
+
+ es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase.prototype.constructor = es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase;
+
+ es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase.prototype.deinit = function() {
+ // an attempt to cleanup the GL state when the test fails
+ bufferedLogToConsole('ShaderBuildInConstantCase.deinit()');
+ gl.useProgram(null);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null);
+ };
+
+ /**
+ * @param {gluShaderProgram.shaderType} shaderType
+ * @param {string} varName
+ * @return {glsShaderExecUtil.ShaderExecutor}
+ */
+ es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase.prototype.createGetConstantExecutor = function(shaderType, varName) {
+ /** @type {glsShaderExecUtil.ShaderSpec} */ var shaderSpec = new glsShaderExecUtil.ShaderSpec();
+ shaderSpec.version = gluShaderUtil.GLSLVersion.V300_ES;
+ shaderSpec.source = 'result = ' + varName + ';\n';
+ shaderSpec.outputs.push(new glsShaderExecUtil.Symbol('result',
+ gluVarType.newTypeBasic(gluShaderUtil.DataType.INT, gluShaderUtil.precision.PRECISION_HIGHP)));
+ return glsShaderExecUtil.createExecutor(shaderType, shaderSpec);
+
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase.prototype.iterate = function() {
+ /** @type {glsShaderExecUtil.ShaderExecutor} */
+ var shaderExecutor = this.createGetConstantExecutor(this.m_shaderType, this.m_varName);
+ /** @type {number} */ var reference = this.m_getValue();
+ /** @type {goog.NumberArray} */ var shaderExecutorResult;
+ /** @type {number} */ var result;
+
+ if (!shaderExecutor.isOk())
+ assertMsgOptions(false, 'Compile failed', false, true);
+
+ shaderExecutor.useProgram();
+
+ shaderExecutorResult = shaderExecutor.execute(1, null);
+ result = new Int32Array(shaderExecutorResult[0].buffer)[0];
+
+ bufferedLogToConsole(this.m_varName + ' = ' + result);
+
+ if (result != reference) {
+ bufferedLogToConsole('ERROR: Expected ' + this.m_varName + ' = ' + reference + '\n' +
+ 'Test shader:' + shaderExecutor.m_program.getProgramInfo().infoLog);
+ testFailedOptions('Invalid builtin constant value', false);
+ } else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @struct
+ * @constructor
+ * @param {number=} near
+ * @param {number=} far
+ */
+ es3fShaderBuiltinVarTests.DepthRangeParams = function(near, far) {
+ /** @type {number} */ this.zNear = near === undefined ? 0.0 : near;
+ /** @type {number} */ this.zFar = far === undefined ? 1.0 : far;
+ };
+
+ /**
+ * @constructor
+ * @extends {glsShaderRenderCase.ShaderEvaluator}
+ * @param {es3fShaderBuiltinVarTests.DepthRangeParams} params
+ */
+ es3fShaderBuiltinVarTests.DepthRangeEvaluator = function(params) {
+ /** @type {es3fShaderBuiltinVarTests.DepthRangeParams} */ this.m_params = params;
+ };
+
+ es3fShaderBuiltinVarTests.DepthRangeEvaluator.prototype = Object.create(glsShaderRenderCase.ShaderEvaluator.prototype);
+ es3fShaderBuiltinVarTests.DepthRangeEvaluator.prototype.constructor = es3fShaderBuiltinVarTests.DepthRangeEvaluator;
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ */
+ es3fShaderBuiltinVarTests.DepthRangeEvaluator.prototype.evaluate = function(c) {
+ /** @type {number} */ var zNear = deMath.clamp(this.m_params.zNear, 0.0, 1.0);
+ /** @type {number} */ var zFar = deMath.clamp(this.m_params.zFar, 0.0, 1.0);
+ /** @type {number} */ var diff = zFar - zNear;
+ c.color[0] = zNear;
+ c.color[1] = zFar;
+ c.color[2] = diff * 0.5 + 0.5;
+ };
+
+ /**
+ * @constructor
+ * @extends {glsShaderRenderCase.ShaderRenderCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {boolean} isVertexCase
+ */
+ es3fShaderBuiltinVarTests.ShaderDepthRangeTest = function(name, desc, isVertexCase) {
+ glsShaderRenderCase.ShaderRenderCase.call(this, name, desc, isVertexCase);
+ /** @type {es3fShaderBuiltinVarTests.DepthRangeParams} */ this.m_depthRange = new es3fShaderBuiltinVarTests.DepthRangeParams();
+ /** @type {es3fShaderBuiltinVarTests.DepthRangeEvaluator} */ this.m_evaluator = new es3fShaderBuiltinVarTests.DepthRangeEvaluator(this.m_depthRange);
+ /** @type {number} */ this.m_iterNdx = 0;
+ };
+
+ es3fShaderBuiltinVarTests.ShaderDepthRangeTest.prototype = Object.create(glsShaderRenderCase.ShaderRenderCase.prototype);
+ es3fShaderBuiltinVarTests.ShaderDepthRangeTest.prototype.constructor = es3fShaderBuiltinVarTests.ShaderDepthRangeTest;
+
+ es3fShaderBuiltinVarTests.ShaderDepthRangeTest.prototype.init = function() {
+ /** @type {string} */ var defaultVertSrc = '' +
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ '}\n';
+ /** @type {string} */ var defaultFragSrc = '' +
+ '#version 300 es\n' +
+ 'in mediump vec4 v_color;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = v_color;\n' +
+ '}\n';
+
+ // Construct shader.
+ /** @type {string} */ var src = '#version 300 es\n';
+ if (this.m_isVertexCase)
+ src += 'in highp vec4 a_position;\n' +
+ 'out mediump vec4 v_color;\n';
+ else
+ src += 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ src += 'void main (void)\n{\n' +
+ '\t' + (this.m_isVertexCase ? 'v_color' : 'o_color') + ' = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff*0.5 + 0.5, 1.0);\n';
+
+ if (this.m_isVertexCase)
+ src += '\tgl_Position = a_position;\n';
+
+ src += '}\n';
+
+ this.m_vertShaderSource = this.m_isVertexCase ? src : defaultVertSrc;
+ this.m_fragShaderSource = this.m_isVertexCase ? defaultFragSrc : src;
+
+ this.postinit();
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderBuiltinVarTests.ShaderDepthRangeTest.prototype.iterate = function() {
+ /** @type {Array<es3fShaderBuiltinVarTests.DepthRangeParams>} */ var cases = [
+ new es3fShaderBuiltinVarTests.DepthRangeParams(0.0, 1.0)
+ ];
+
+ this.m_depthRange = cases[this.m_iterNdx];
+ bufferedLogToConsole('gl.depthRange(' + this.m_depthRange.zNear + ', ' + this.m_depthRange.zFar + ')');
+ gl.depthRange(this.m_depthRange.zNear, this.m_depthRange.zFar);
+
+ this.postiterate();
+ this.m_iterNdx += 1;
+
+ if (this.m_iterNdx == cases.length)
+ return tcuTestCase.IterateResult.STOP;
+ else
+ return tcuTestCase.IterateResult.CONTINUE;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderBuiltinVarTests.FragCoordXYZCase = function() {
+ tcuTestCase.DeqpTest.call(this, 'fragcoord_xyz', 'gl_FragCoord.xyz Test');
+ };
+
+ es3fShaderBuiltinVarTests.FragCoordXYZCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderBuiltinVarTests.FragCoordXYZCase.prototype.constructor = es3fShaderBuiltinVarTests.FragCoordXYZCase;
+
+ es3fShaderBuiltinVarTests.FragCoordXYZCase.prototype.iterate = function() {
+ /** @type {number} */ var width = gl.drawingBufferWidth;
+ /** @type {number} */ var height = gl.drawingBufferHeight;
+ /** @type {Array<number>} */ var threshold = deMath.add([1, 1, 1, 1], tcuPixelFormat.PixelFormatFromContext(gl).getColorThreshold());
+ /** @type {Array<number>} */ var scale = [1. / width, 1. / height, 1.0];
+
+ /** @type {tcuSurface.Surface} */ var testImg = new tcuSurface.Surface(width, height);
+ /** @type {tcuSurface.Surface} */ var refImg = new tcuSurface.Surface(width, height);
+
+ /** @type {string} */ var vtxSource = '' +
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ '}\n';
+ /** @type {string} */ var fragSource = '' +
+ '#version 300 es\n' +
+ 'uniform highp vec3 u_scale;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = vec4(gl_FragCoord.xyz*u_scale, 1.0);\n' +
+ '}\n';
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vtxSource, fragSource));
+
+ bufferedLogToConsole(program.getProgramInfo().infoLog);
+
+ if (!program.isOk())
+ throw new Error('Compile failed');
+
+ // Draw with GL.
+ /** @type {Array<number>} */ var positions = [
+ -1.0, 1.0, -1.0, 1.0,
+ -1.0, -1.0, 0.0, 1.0,
+ 1.0, 1.0, 0.0, 1.0,
+ 1.0, -1.0, 1.0, 1.0
+ ];
+ /** @type {Array<number>} */ var indices = [0, 1, 2, 2, 1, 3];
+
+ /** @type {WebGLUniformLocation} */ var scaleLoc = gl.getUniformLocation(program.getProgram(), 'u_scale');
+ /** @type {gluDrawUtil.VertexArrayBinding} */ var posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, positions);
+
+ gl.useProgram(program.getProgram());
+ gl.uniform3fv(scaleLoc, scale);
+
+ gl.viewport(0, 0, width, height);
+ gluDrawUtil.draw(gl, program.getProgram(), [posBinding], gluDrawUtil.triangles(indices));
+
+ testImg.readViewport(gl, [0, 0, width, height]);
+
+ // Draw reference
+ for (var y = 0; y < refImg.getHeight(); y++) {
+ for (var x = 0; x < refImg.getWidth(); x++) {
+ /** @type {number} */ var xf = (x + .5) / refImg.getWidth();
+ /** @type {number} */ var yf = (refImg.getHeight() - y - 1 + .5) / refImg.getHeight();
+ /** @type {number} */ var z = (xf + yf) / 2.0;
+ /** @type {Array<number>} */ var fragCoord = [x + .5, y + .5, z];
+ /** @type {Array<number>} */ var scaledFC = deMath.multiply(fragCoord, scale);
+ /** @type {Array<number>} */
+ var color = [
+ deMath.clamp(Math.floor(scaledFC[0] * 255 + 0.5), 0, 255),
+ deMath.clamp(Math.floor(scaledFC[1] * 255 + 0.5), 0, 255),
+ deMath.clamp(Math.floor(scaledFC[2] * 255 + 0.5), 0, 255),
+ 255];
+ refImg.setPixel(x, y, color);
+ }
+ }
+
+ // Compare
+ /** @type {boolean} */ var isOk = tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', refImg, testImg, threshold);
+
+ if (!isOk)
+ testFailedOptions('Image comparison failed', false);
+ else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @param {Array<number>} s
+ * @param {Array<number>} w
+ * @param {number} nx
+ * @param {number} ny
+ * @return {number}
+ */
+ es3fShaderBuiltinVarTests.projectedTriInterpolate = function(s, w, nx, ny) {
+ return (s[0] * (1.0 - nx - ny)/w[0] + s[1] * ny / w[1] + s[2] * nx / w[2]) / ((1.0 - nx - ny) / w[0] + ny / w[1] + nx / w[2]);
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderBuiltinVarTests.FragCoordWCase = function() {
+ tcuTestCase.DeqpTest.call(this, 'fragcoord_w', 'gl_FragCoord.w Test');
+ };
+
+ es3fShaderBuiltinVarTests.FragCoordWCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderBuiltinVarTests.FragCoordWCase.prototype.constructor = es3fShaderBuiltinVarTests.FragCoordWCase;
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderBuiltinVarTests.FragCoordWCase.prototype.iterate = function() {
+ /** @type {number} */ var width = gl.drawingBufferWidth;
+ /** @type {number} */ var height = gl.drawingBufferHeight;
+ /** @type {Array<number>} */ var threshold = deMath.add([1, 1, 1, 1], tcuPixelFormat.PixelFormatFromContext(gl).getColorThreshold());
+
+ /** @type {tcuSurface.Surface} */ var testImg = new tcuSurface.Surface(width, height);
+ /** @type {tcuSurface.Surface} */ var refImg = new tcuSurface.Surface(width, height);
+
+ /** @type {Array<number>} */ var w = [1.7, 2.0, 1.2, 1.0];
+
+ /** @type {string} */ var vtxSource = '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ '}\n';
+
+ /** @type {string} */ var fragSource = '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = vec4(0.0, 1.0/gl_FragCoord.w - 1.0, 0.0, 1.0);\n' +
+ '}\n';
+
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vtxSource, fragSource));
+ bufferedLogToConsole(program.getProgramInfo().infoLog);
+
+ if (!program.isOk())
+ throw new Error('Compile failed');
+
+ // Draw with GL.
+ /** @type {Array<number>} */ var positions = [
+ -w[0], w[0], 0.0, w[0],
+ -w[1], -w[1], 0.0, w[1],
+ w[2], w[2], 0.0, w[2],
+ w[3], -w[3], 0.0, w[3]
+ ];
+ /** @type {Array<number>} */ var indices = [0, 1, 2, 2, 1, 3];
+
+ /** @type {gluDrawUtil.VertexArrayBinding} */ var posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, positions);
+ gl.useProgram(program.getProgram());
+
+ gluDrawUtil.draw(gl, program.getProgram(), [posBinding], gluDrawUtil.triangles(indices));
+ testImg.readViewport(gl, [0, 0, width, height]);
+
+ // Draw reference
+ for (var y = 0; y < refImg.getHeight(); y++) {
+ for (var x = 0; x < refImg.getWidth(); x++) {
+ /** @type {number} */ var xf = (x + 0.5) / refImg.getWidth();
+ /** @type {number} */ var yf = (refImg.getHeight() - y - 1 + 0.5) / refImg.getHeight();
+ /** @type {number} */ var oow = ((xf + yf) < 1.0) ?
+ es3fShaderBuiltinVarTests.projectedTriInterpolate([w[0], w[1], w[2]], [w[0], w[1], w[2]], xf, yf) :
+ es3fShaderBuiltinVarTests.projectedTriInterpolate([w[3], w[2], w[1]], [w[3], w[2], w[1]], 1.0 - xf, 1.0 - yf);
+ /** @type {Array<number>} */
+ var color = [
+ 0,
+ deMath.clamp(Math.floor((oow - 1.0) * 255 + 0.5), 0, 255),
+ 0,
+ 255];
+ refImg.setPixel(x, y, color);
+ }
+ }
+
+ // Compare
+ /** @type {boolean} */ var isOk = tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', refImg, testImg, threshold);
+
+ if (!isOk) {
+ testFailedOptions('Image comparison failed', false);
+ } else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderBuiltinVarTests.PointCoordCase = function() {
+ tcuTestCase.DeqpTest.call(this, 'pointcoord', 'gl_PointCoord Test');
+ };
+
+ es3fShaderBuiltinVarTests.PointCoordCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderBuiltinVarTests.PointCoordCase.prototype.constructor = es3fShaderBuiltinVarTests.PointCoordCase;
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderBuiltinVarTests.PointCoordCase.prototype.iterate = function() {
+ /** @type {number} */ var width = Math.min(256, gl.drawingBufferWidth);
+ /** @type {number} */ var height = Math.min(256, gl.drawingBufferHeight);
+ /** @type {number} */ var threshold = 0.02;
+
+ /** @type {number} */ var numPoints = 8;
+
+ /** @type {Array<number>} */ var coords = [];
+ /** @type {Array<number>} */ var pointSizeRange = [0.0, 0.0];
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0x145fa);
+ /** @type {tcuSurface.Surface} */ var testImg = new tcuSurface.Surface(width, height);
+ /** @type {tcuSurface.Surface} */ var refImg = new tcuSurface.Surface(width, height);
+
+ pointSizeRange = /** @type {Array<number>} */ (gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE));
+
+ if (pointSizeRange[0] <= 0.0 || pointSizeRange[1] <= 0.0 || pointSizeRange[1] < pointSizeRange[0])
+ throw new Error('Invalid gl.ALIASED_POINT_SIZE_RANGE');
+
+ // Compute coordinates.
+ for (var i = 0; i < numPoints; i++)
+ coords.push([
+ rnd.getFloat(-0.9, 0.9),
+ rnd.getFloat(-0.9, 0.9),
+ rnd.getFloat(pointSizeRange[0], pointSizeRange[1])
+ ]);
+
+ /** @type {string} */ var vtxSource = '#version 300 es\n' +
+ 'in highp vec3 a_positionSize;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(a_positionSize.xy, 0.0, 1.0);\n' +
+ ' gl_PointSize = a_positionSize.z;\n' +
+ '}\n';
+
+ /** @type {string} */ var fragSource = '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = vec4(gl_PointCoord, 0.0, 1.0);\n' +
+ '}\n';
+
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vtxSource, fragSource));
+ bufferedLogToConsole(program.getProgramInfo().infoLog);
+
+ if (!program.isOk())
+ throw new Error('Compile failed');
+
+ // Draw with GL.
+ var newCoords = [].concat.apply([], coords);
+
+ // /** @type {gluDrawUtil.VertexArrayBinding} */ var posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_positionSize', 3, coords.length, 0, coords);
+ /** @type {gluDrawUtil.VertexArrayBinding} */
+ var posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_positionSize', 3, coords.length, 12, newCoords);
+ /** @type {number} */ var viewportX = rnd.getInt(0, gl.drawingBufferWidth - width);
+ /** @type {number} */ var viewportY = rnd.getInt(0, gl.drawingBufferHeight - height);
+
+ gl.viewport(viewportX, viewportY, width, height);
+ gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ gl.useProgram(program.getProgram());
+
+ gluDrawUtil.draw(gl, program.getProgram(), [posBinding], gluDrawUtil.pointsFromElements(coords.length));
+ testImg.readViewport(gl, [viewportX, viewportY, width, height]);
+
+ // Draw reference
+ refImg.getAccess().clear([0.0, 0.0, 0.0, 1.0]);
+ for (var i = 0; i < coords.length; i++) {
+ /** @type {number} */ var x0 = Math.round(width * (coords[i][0] * 0.5 + 0.5) - coords[i][2] * 0.5);
+ /** @type {number} */ var y0 = Math.round(height* (coords[i][1] * 0.5 + 0.5) - coords[i][2] * 0.5);
+ /** @type {number} */ var x1 = Math.round(width * (coords[i][0] * 0.5 + 0.5) + coords[i][2] * 0.5);
+ /** @type {number} */ var y1 = Math.round(height * (coords[i][1] * 0.5 + 0.5) + coords[i][2] * 0.5);
+ /** @type {number} */ var w = x1 - x0;
+ /** @type {number} */ var h = y1 - y0;
+
+ for (var yo = 0; yo < h; yo++) {
+ for (var xo = 0; xo < w; xo++) {
+ /** @type {number} */ var xf = (xo + 0.5) / w;
+ /** @type {number} */ var yf = ((h - yo - 1) + 0.5) / h;
+ /** @type {number} */ var dx = x0 + xo;
+ /** @type {number} */ var dy = y0 + yo;
+ /** @type {Array<number>} */
+ var color = [
+ deMath.clamp(Math.floor(xf * 255 + 0.5), 0, 255),
+ deMath.clamp(Math.floor(yf * 255 + 0.5), 0, 255),
+ 0,
+ 255];
+ if (deMath.deInBounds32(dx, 0, refImg.getWidth()) && deMath.deInBounds32(dy, 0, refImg.getHeight()))
+ refImg.setPixel(dx, dy, color);
+ }
+ }
+ }
+
+ // Compare
+ /** @type {boolean} */ var isOk = tcuImageCompare.fuzzyCompare('Result', 'Image comparison result', refImg.getAccess(), testImg.getAccess(), threshold);
+
+ if (!isOk) {
+ testFailedOptions('Image comparison failed', false);
+ } else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderBuiltinVarTests.FrontFacingCase = function() {
+ tcuTestCase.DeqpTest.call(this, 'frontfacing', 'gl_FrontFacing Test');
+ };
+
+ es3fShaderBuiltinVarTests.FrontFacingCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderBuiltinVarTests.FrontFacingCase.prototype.constructor = es3fShaderBuiltinVarTests.FrontFacingCase;
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderBuiltinVarTests.FrontFacingCase.prototype.iterate = function() {
+ // Test case renders two adjecent quads, where left is has front-facing
+ // triagles and right back-facing. Color is selected based on gl_FrontFacing
+ // value.
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0x89f2c);
+ /** @type {number} */ var width = Math.min(64, gl.drawingBufferWidth);
+ /** @type {number} */ var height = Math.min(64, gl.drawingBufferHeight);
+ /** @type {number} */ var viewportX = rnd.getInt(0, gl.drawingBufferWidth - width);
+ /** @type {number} */ var viewportY = rnd.getInt(0, gl.drawingBufferHeight - height);
+ /** @type {Array<number>} */ var threshold = deMath.add([1, 1, 1, 1], tcuPixelFormat.PixelFormatFromContext(gl).getColorThreshold());
+
+ /** @type {tcuSurface.Surface} */ var testImg = new tcuSurface.Surface(width, height);
+ /** @type {tcuSurface.Surface} */ var refImg = new tcuSurface.Surface(width, height);
+
+ /** @type {string} */ var vtxSource = '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ '}\n';
+
+ /** @type {string} */ var fragSource = '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' if (gl_FrontFacing)\n' +
+ ' o_color = vec4(0.0, 1.0, 0.0, 1.0);\n' +
+ ' else\n' +
+ ' o_color = vec4(0.0, 0.0, 1.0, 1.0);\n' +
+ '}\n';
+
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vtxSource, fragSource));
+
+ bufferedLogToConsole(program.getProgramInfo().infoLog);
+
+ if (!program.isOk())
+ throw new Error('Compile failed');
+
+ // Draw with GL.
+ /** @type {Array<number>} */ var positions = [
+ -1.0, 1.0, 0.0, 1.0,
+ -1.0, -1.0, 0.0, 1.0,
+ 1.0, 1.0, 0.0, 1.0,
+ 1.0, -1.0, 0.0, 1.0
+ ];
+
+ /** @type {Array<number>} */ var indicesCCW = [0, 1, 2, 2, 1, 3];
+ /** @type {Array<number>} */ var indicesCW = [2, 1, 0, 3, 1, 2];
+
+ /** @type {gluDrawUtil.VertexArrayBinding} */ var posBinding = gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, positions);
+
+ gl.useProgram(program.getProgram());
+
+ gl.viewport(viewportX, viewportY, Math.floor(width / 2), height);
+
+ gluDrawUtil.draw(gl, program.getProgram(), [posBinding], gluDrawUtil.triangles(indicesCCW));
+
+ gl.viewport(viewportX + Math.floor(width / 2), viewportY, width - Math.floor(width / 2), height);
+ gluDrawUtil.draw(gl, program.getProgram(), [posBinding], gluDrawUtil.triangles(indicesCW));
+ testImg.readViewport(gl, [viewportX, viewportY, width, height]);
+ // Draw reference
+ for (var y = 0; y < refImg.getHeight(); y++) {
+ for (var x = 0; x < Math.floor(refImg.getWidth() / 2); x++)
+ refImg.setPixel(x, y, tcuRGBA.RGBA.green.toIVec());
+
+ for (var x = Math.floor(refImg.getWidth() / 2); x < refImg.getWidth(); x++)
+ refImg.setPixel(x, y, tcuRGBA.RGBA.blue.toIVec());
+ }
+
+ // Compare
+ /** @type {boolean} */ var isOk = tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', refImg, testImg, threshold);
+
+ if (!isOk) {
+ testFailedOptions('Image comparison failed', false);
+ } else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderBuiltinVarTests.VertexIDCase = function() {
+ tcuTestCase.DeqpTest.call(this, 'vertex_id', 'gl_VertexID Test');
+ /** @type {?gluShaderProgram.ShaderProgram} */ this.m_program = null;
+ /** @type {WebGLBuffer} */ this.m_positionBuffer = null;
+ /** @type {WebGLBuffer} */ this.m_elementBuffer = null;
+ /** @type {number} */ this.m_viewportW = 0;
+ /** @type {number} */ this.m_viewportH = 0;
+ /** @type {number} */ this.m_iterNdx = 0;
+ /** @type {Array<Array<number>>} */ this.m_positions = [];
+ /** @type {Array<Array<number>>} */ this.m_colors = [];
+ };
+
+ es3fShaderBuiltinVarTests.VertexIDCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderBuiltinVarTests.VertexIDCase.prototype.constructor = es3fShaderBuiltinVarTests.VertexIDCase;
+
+ es3fShaderBuiltinVarTests.VertexIDCase.MAX_VERTICES = 24; //!< 8 triangles, totals 24 vertices
+
+ es3fShaderBuiltinVarTests.VertexIDCase.prototype.init = function() {
+ /** @type {number} */ var width = gl.drawingBufferWidth;
+ /** @type {number} */ var height = gl.drawingBufferHeight;
+
+ /** @type {number} */ var quadWidth = 32;
+ /** @type {number} */ var quadHeight = 32;
+
+ if (width < quadWidth)
+ throw new Error('Too small render target');
+
+ /** @type {number} */ var maxQuadsX = Math.floor(width / quadWidth);
+ /** @type {number} */ var numVertices = es3fShaderBuiltinVarTests.VertexIDCase.MAX_VERTICES;
+
+ /** @type {number} */ var numQuads = Math.floor(numVertices / 6) + (numVertices % 6 != 0 ? 1 : 0);
+ /** @type {number} */ var viewportW = Math.min(numQuads, maxQuadsX)*quadWidth;
+ /** @type {number} */ var viewportH = (Math.floor(numQuads/maxQuadsX) + (numQuads % maxQuadsX != 0 ? 1 : 0)) * quadHeight;
+
+ if (viewportH > height)
+ throw new Error('Too small render target');
+
+ assertMsgOptions(viewportW <= width && viewportH <= height, 'Unexpected viewport dimensions.', false, true);
+
+ assertMsgOptions(!this.m_program, 'Program should not be defined at this point.', false, true);
+
+ /** @type {string} */ var vtxSource = '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'out mediump vec4 v_color;\n' +
+ 'uniform highp vec4 u_colors[24];\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ ' v_color = u_colors[gl_VertexID];\n' +
+ '}\n';
+
+ /** @type {string} */ var fragSource = '#version 300 es\n' +
+ 'in mediump vec4 v_color;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = v_color;\n' +
+ '}\n';
+
+ this.m_program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vtxSource, fragSource));
+ bufferedLogToConsole(this.m_program.getProgramInfo().infoLog);
+
+ if (!this.m_program.isOk()) {
+ this.m_program = null;
+ throw new Error('Compile failed');
+ }
+
+ this.m_positionBuffer = gl.createBuffer();
+ this.m_elementBuffer = gl.createBuffer();
+
+ // Set colors (in dynamic memory to save static data space).
+ this.m_colors[0] = [0.0, 0.0, 0.0, 1.0];
+ this.m_colors[1] = [0.5, 1.0, 0.5, 1.0];
+ this.m_colors[2] = [0.0, 0.5, 1.0, 1.0];
+ this.m_colors[3] = [0.0, 1.0, 0.0, 1.0];
+ this.m_colors[4] = [0.0, 1.0, 1.0, 1.0];
+ this.m_colors[5] = [0.5, 0.0, 0.0, 1.0];
+ this.m_colors[6] = [0.5, 0.0, 1.0, 1.0];
+ this.m_colors[7] = [0.5, 0.0, 0.5, 1.0];
+ this.m_colors[8] = [1.0, 0.0, 0.0, 1.0];
+ this.m_colors[9] = [0.5, 1.0, 0.0, 1.0];
+ this.m_colors[10] = [0.0, 0.5, 0.0, 1.0];
+ this.m_colors[11] = [0.5, 1.0, 1.0, 1.0];
+ this.m_colors[12] = [0.0, 0.0, 1.0, 1.0];
+ this.m_colors[13] = [1.0, 0.0, 0.5, 1.0];
+ this.m_colors[14] = [0.0, 0.5, 0.5, 1.0];
+ this.m_colors[15] = [1.0, 1.0, 0.5, 1.0];
+ this.m_colors[16] = [1.0, 0.0, 1.0, 1.0];
+ this.m_colors[17] = [1.0, 0.5, 0.0, 1.0];
+ this.m_colors[18] = [0.0, 1.0, 0.5, 1.0];
+ this.m_colors[19] = [1.0, 0.5, 1.0, 1.0];
+ this.m_colors[20] = [1.0, 1.0, 0.0, 1.0];
+ this.m_colors[21] = [1.0, 0.5, 0.5, 1.0];
+ this.m_colors[22] = [0.0, 0.0, 0.5, 1.0];
+ this.m_colors[23] = [1.0, 1.0, 1.0, 1.0];
+
+ // Compute positions.
+ assertMsgOptions(numVertices % 3 == 0, 'Number of vertices should be multiple of 3.', false, true);
+
+ for (var vtxNdx = 0; vtxNdx < numVertices; vtxNdx += 3) {
+ /** @type {number} */ var h = 2.0 * quadHeight / viewportH;
+ /** @type {number} */ var w = 2.0 * quadWidth / viewportW;
+
+ /** @type {number} */ var triNdx = Math.floor(vtxNdx / 3);
+ /** @type {number} */ var quadNdx = Math.floor(triNdx / 2);
+ /** @type {number} */ var quadY = Math.floor(quadNdx / maxQuadsX);
+ /** @type {number} */ var quadX = quadNdx % maxQuadsX;
+
+ /** @type {number} */ var x0 = -1.0 + quadX * w;
+ /** @type {number} */ var y0 = -1.0 + quadY * h;
+
+ if (triNdx % 2 === 0) {
+ this.m_positions[vtxNdx + 0] = [x0, y0, 0.0, 1.0];
+ this.m_positions[vtxNdx + 1] = [x0+w, y0+h, 0.0, 1.0];
+ this.m_positions[vtxNdx + 2] = [x0, y0+h, 0.0, 1.0];
+ } else {
+ this.m_positions[vtxNdx + 0] = [x0 + w, y0 + h, 0.0, 1.0];
+ this.m_positions[vtxNdx + 1] = [x0, y0, 0.0, 1.0];
+ this.m_positions[vtxNdx + 2] = [x0+w, y0, 0.0, 1.0];
+ }
+ }
+
+ this.m_viewportW = viewportW;
+ this.m_viewportH = viewportH;
+ this.m_iterNdx = 0;
+
+ };
+
+ es3fShaderBuiltinVarTests.VertexIDCase.prototype.deinit = function() {
+ this.m_program = null;
+
+ if (this.m_positionBuffer) {
+ gl.deleteBuffer(this.m_positionBuffer);
+ this.m_positionBuffer = null;
+ }
+
+ if (this.m_elementBuffer) {
+ gl.deleteBuffer(this.m_elementBuffer);
+ this.m_elementBuffer = null;
+ }
+
+ this.m_positions = [];
+ this.m_colors = [];
+ };
+
+ /**
+ * @constructor
+ * @extends {sglrShaderProgram.ShaderProgram}
+ */
+ es3fShaderBuiltinVarTests.VertexIDReferenceShader = function() {
+ /** @type {sglrShaderProgram.ShaderProgramDeclaration} */ var declaration = new sglrShaderProgram.ShaderProgramDeclaration();
+ declaration.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('', rrGenericVector.GenericVecType.FLOAT));
+ declaration.pushVertexAttribute(new sglrShaderProgram.VertexAttribute('', rrGenericVector.GenericVecType.FLOAT));
+ declaration.pushVertexToFragmentVarying(new sglrShaderProgram.VertexToFragmentVarying(rrGenericVector.GenericVecType.FLOAT, new sglrShaderProgram.VaryingFlags()));
+ declaration.pushFragmentOutput(new sglrShaderProgram.FragmentOutput(rrGenericVector.GenericVecType.FLOAT));
+ declaration.pushVertexSource(new sglrShaderProgram.VertexSource('')); // ShaderProgram fails if we don't push a source, even though GLSL source is not used
+ declaration.pushFragmentSource(new sglrShaderProgram.FragmentSource(''));
+ sglrShaderProgram.ShaderProgram.call(this, declaration);
+ };
+
+ es3fShaderBuiltinVarTests.VertexIDReferenceShader.prototype = Object.create(sglrShaderProgram.ShaderProgram.prototype);
+ es3fShaderBuiltinVarTests.VertexIDReferenceShader.prototype.constructor = es3fShaderBuiltinVarTests.VertexIDReferenceShader;
+
+ /** @const {number} */ es3fShaderBuiltinVarTests.VertexIDReferenceShader.VARYINGLOC_COLOR = 0;
+
+ /**
+ * @param {Array<rrVertexAttrib.VertexAttrib>} inputs
+ * @param {Array<rrVertexPacket.VertexPacket>} packets
+ */
+ es3fShaderBuiltinVarTests.VertexIDReferenceShader.prototype.shadeVertices = function(inputs, packets) {
+ for (var packetNdx = 0; packetNdx < packets.length; ++packetNdx) {
+ /** @type {number} */ var positionAttrLoc = 0;
+ /** @type {number} */ var colorAttrLoc = 1;
+
+ /** @type {rrVertexPacket.VertexPacket} */ var packet = packets[packetNdx];
+
+ // Transform to position
+ packet.position = rrVertexAttrib.readVertexAttrib(inputs[positionAttrLoc], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
+
+ // Pass color to FS
+ packet.outputs[es3fShaderBuiltinVarTests.VertexIDReferenceShader.VARYINGLOC_COLOR] = rrVertexAttrib.readVertexAttrib(inputs[colorAttrLoc], packet.instanceNdx, packet.vertexNdx, rrGenericVector.GenericVecType.FLOAT);
+ }
+ };
+
+ /**
+ * @param {Array<rrFragmentOperations.Fragment>} packets
+ * @param {rrShadingContext.FragmentShadingContext} context
+ */
+ es3fShaderBuiltinVarTests.VertexIDReferenceShader.prototype.shadeFragments = function(packets, context) {
+ for (var packetNdx = 0; packetNdx < packets.length; ++packetNdx) {
+ /** @type {rrFragmentOperations.Fragment} */ var packet = packets[packetNdx];
+ packet.value = rrShadingContext.readVarying(packet, context, es3fShaderBuiltinVarTests.VertexIDReferenceShader.VARYINGLOC_COLOR);
+ }
+ };
+
+ /**
+ * @param {tcuTexture.PixelBufferAccess} dst
+ * @param {Array<number>} indices
+ * @param {goog.NumberArray} positions
+ * @param {goog.NumberArray} colors
+ */
+ es3fShaderBuiltinVarTests.VertexIDCase.prototype.renderReference = function(dst, indices, positions, colors) {
+ /** @type {rrRenderState.RenderState} */
+ var referenceState = new rrRenderState.RenderState(
+ new rrRenderState.ViewportState(rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(dst))
+ );
+
+ /** @type {rrRenderer.RenderTarget} */
+ var referenceTarget = new rrRenderer.RenderTarget(
+ rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess.fromSinglesampleAccess(dst)
+ );
+
+ /** @type {es3fShaderBuiltinVarTests.VertexIDReferenceShader} */
+ var referenceShaderProgram = new es3fShaderBuiltinVarTests.VertexIDReferenceShader();
+
+ /** @type {Array<rrVertexAttrib.VertexAttrib>} */ var attribs = [];
+ attribs[0] = new rrVertexAttrib.VertexAttrib();
+ attribs[0].type = rrVertexAttrib.VertexAttribType.FLOAT;
+ attribs[0].size = 4;
+ attribs[0].stride = 0;
+ attribs[0].instanceDivisor = 0;
+ attribs[0].pointer = positions.buffer;
+
+ attribs[1] = new rrVertexAttrib.VertexAttrib();
+ attribs[1].type = rrVertexAttrib.VertexAttribType.FLOAT;
+ attribs[1].size = 4;
+ attribs[1].stride = 0;
+ attribs[1].instanceDivisor = 0;
+ attribs[1].pointer = colors.buffer;
+ rrRenderer.drawTriangles(referenceState, referenceTarget, referenceShaderProgram,
+ attribs, rrRenderer.PrimitiveType.TRIANGLES, 0, indices.length, /*instanceID = */ 0);
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderBuiltinVarTests.VertexIDCase.prototype.iterate = function() {
+ /** @type {number} */ var width = gl.drawingBufferWidth;
+ /** @type {number} */ var height = gl.drawingBufferHeight;
+ /** @type {number} */ var viewportW = this.m_viewportW;
+ /** @type {number} */ var viewportH = this.m_viewportH;
+
+ /** @type {number} */ var threshold = 0.02;
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(0xcf23ab1 ^ deString.deStringHash(this.m_iterNdx.toString()));
+ /** @type {tcuSurface.Surface} */ var refImg = new tcuSurface.Surface(viewportW, viewportH);
+ /** @type {tcuSurface.Surface} */ var testImg = new tcuSurface.Surface(viewportW, viewportH);
+
+ /** @type {number} */ var viewportX = rnd.getInt(0, width - viewportW);
+ /** @type {number} */ var viewportY = rnd.getInt(0, height - viewportH);
+
+ /** @type {number} */ var posLoc = gl.getAttribLocation(this.m_program.getProgram(), 'a_position');
+ /** @type {WebGLUniformLocation} */ var colorsLoc = gl.getUniformLocation(this.m_program.getProgram(), 'u_colors[0]');
+ /** @type {Array<number>} */ var clearColor = [0.0, 0.0, 0.0, 1.0];
+ /** @type {Array<number>} */ var indices = [];
+ /** @type {Array<Array<number>>} */ var mappedPos = [];
+ /** @type {goog.NumberArray} */ var flatColorArray;
+ /** @type {goog.NumberArray} */ var flatPosArray;
+ // Setup common state.
+ gl.viewport(viewportX, viewportY, viewportW, viewportH);
+ gl.useProgram(this.m_program.getProgram());
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.m_positionBuffer);
+ gl.enableVertexAttribArray(posLoc);
+ gl.vertexAttribPointer(posLoc, 4, gl.FLOAT, false, 0, 0);
+ gl.uniform4fv(colorsLoc, [].concat.apply([], this.m_colors));
+
+ // Clear render target to black.
+ gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ refImg.getAccess().clear(clearColor);
+
+ if (this.m_iterNdx === 0) {
+ bufferedLogToConsole('Iter0: glDrawArrays()');
+
+ flatPosArray = new Float32Array([].concat.apply([], this.m_positions));
+ flatColorArray = new Float32Array([].concat.apply([], this.m_colors));
+ gl.bufferData(gl.ARRAY_BUFFER, flatPosArray.buffer, gl.DYNAMIC_DRAW);
+ gl.drawArrays(gl.TRIANGLES, 0, Math.floor(flatPosArray.length / 4));
+
+ //glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, testImg.getAccess());
+ testImg.readViewport(gl, [viewportX, viewportY, viewportW, viewportH]);
+ // Reference indices
+ for (var ndx = 0; ndx < this.m_positions.length; ndx++)
+ indices.push(ndx);
+
+ this.renderReference(refImg.getAccess(), indices, flatPosArray, flatColorArray);
+ } else if (this.m_iterNdx === 1) {
+ bufferedLogToConsole('Iter1: glDrawElements(), indices in buffer');
+
+ // Compute initial indices and suffle
+ for (var ndx = 0; ndx < this.m_positions.length; ndx++)
+ indices.push(ndx);
+ // deRandom.shuffle(rnd, indices);
+ // \note [2015-08-05 dag] The original test shuffles the indices array but the reference renderer cannot handle triangles with sides not parallel to the axes.
+
+ // Use indices to re-map positions.
+ for (var ndx = 0; ndx < indices.length; ndx++)
+ mappedPos[indices[ndx]] = this.m_positions[ndx];
+
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.m_elementBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, (new Uint16Array(indices)).buffer, gl.DYNAMIC_DRAW);
+
+ flatPosArray = new Float32Array([].concat.apply([], mappedPos));
+ flatColorArray = new Float32Array([].concat.apply([], this.m_colors));
+ gl.bufferData(gl.ARRAY_BUFFER, flatPosArray.buffer, gl.DYNAMIC_DRAW);
+ gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
+
+ //glu::readPixels(m_context.getRenderContext(), viewportX, viewportY, testImg.getAccess());
+ testImg.readViewport(gl, [viewportX, viewportY, viewportW, viewportH]);
+ refImg.getAccess().clear(clearColor);
+ this.renderReference(refImg.getAccess(), indices, flatPosArray, flatColorArray);
+ } else
+ throw new Error('Iteration count exceeded.');
+
+ if (!tcuImageCompare.fuzzyCompare('Result', 'Image comparison result', refImg.getAccess(), testImg.getAccess(), threshold))
+ testFailedOptions('Image comparison failed', false);
+ else
+ testPassedOptions('Pass', true);
+
+ this.m_iterNdx += 1;
+ return (this.m_iterNdx < 2) ? tcuTestCase.IterateResult.CONTINUE : tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderBuiltinVarTests.ShaderBuiltinVarTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'builtin_variable', 'Built-in Variable Tests');
+ };
+
+ es3fShaderBuiltinVarTests.ShaderBuiltinVarTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderBuiltinVarTests.ShaderBuiltinVarTests.prototype.constructor = es3fShaderBuiltinVarTests.ShaderBuiltinVarTests;
+
+ es3fShaderBuiltinVarTests.ShaderBuiltinVarTests.prototype.init = function() {
+ var testGroup = tcuTestCase.runner.testCases;
+ // Builtin constants.
+ /**
+ * @struct
+ * @constructor
+ * @param {string} caseName
+ * @param {string} varName
+ * @param {es3fShaderBuiltinVarTests.GetConstantValueFunc} getValue
+ */
+ var BuiltinConstant = function(caseName, varName, getValue) {
+ /** @type {string} */ this.caseName = caseName;
+ /** @type {string} */ this.varName = varName;
+ /** @type {es3fShaderBuiltinVarTests.GetConstantValueFunc} */ this.getValue = getValue;
+
+ };
+
+ /** @type {Array<BuiltinConstant>} */ var builtinConstants = [
+ // GLES 2.
+
+ new BuiltinConstant('max_vertex_attribs', 'gl_MaxVertexAttribs', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_VERTEX_ATTRIBS); }),
+ new BuiltinConstant('max_vertex_uniform_vectors', 'gl_MaxVertexUniformVectors', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_VERTEX_UNIFORM_VECTORS); }),
+ new BuiltinConstant('max_fragment_uniform_vectors', 'gl_MaxFragmentUniformVectors', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_FRAGMENT_UNIFORM_VECTORS); }),
+ new BuiltinConstant('max_texture_image_units', 'gl_MaxTextureImageUnits', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_TEXTURE_IMAGE_UNITS); }),
+ new BuiltinConstant('max_vertex_texture_image_units', 'gl_MaxVertexTextureImageUnits', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS); }),
+ new BuiltinConstant('max_combined_texture_image_units', 'gl_MaxCombinedTextureImageUnits', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS); }),
+ new BuiltinConstant('max_draw_buffers', 'gl_MaxDrawBuffers', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_DRAW_BUFFERS); }),
+
+ // GLES 3.
+
+ new BuiltinConstant('max_vertex_output_vectors', 'gl_MaxVertexOutputVectors', function() { return es3fShaderBuiltinVarTests.getVectorsFromComps(gl.MAX_VERTEX_OUTPUT_COMPONENTS); }),
+ new BuiltinConstant('max_fragment_input_vectors', 'gl_MaxFragmentInputVectors', function() { return es3fShaderBuiltinVarTests.getVectorsFromComps(gl.MAX_FRAGMENT_INPUT_COMPONENTS); }),
+ new BuiltinConstant('min_program_texel_offset', 'gl_MinProgramTexelOffset', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MIN_PROGRAM_TEXEL_OFFSET); }),
+ new BuiltinConstant('max_program_texel_offset', 'gl_MaxProgramTexelOffset', function() { return es3fShaderBuiltinVarTests.getInteger(gl.MAX_PROGRAM_TEXEL_OFFSET); })
+ ];
+
+ for (var ndx = 0; ndx < builtinConstants.length; ndx++) {
+ /** @type {string} */ var caseName = builtinConstants[ndx].caseName;
+ /** @type {string} */ var varName = builtinConstants[ndx].varName;
+ /** @type {es3fShaderBuiltinVarTests.GetConstantValueFunc} */ var getValue = builtinConstants[ndx].getValue;
+
+ testGroup.addChild(new es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase(caseName + '_vertex', varName, varName, getValue, gluShaderProgram.shaderType.VERTEX));
+ testGroup.addChild(new es3fShaderBuiltinVarTests.ShaderBuiltinConstantCase(caseName + '_fragment', varName, varName, getValue, gluShaderProgram.shaderType.FRAGMENT));
+ }
+
+ testGroup.addChild(new es3fShaderBuiltinVarTests.ShaderDepthRangeTest('depth_range_vertex', 'gl_DepthRange', true));
+ testGroup.addChild(new es3fShaderBuiltinVarTests.ShaderDepthRangeTest('depth_range_fragment', 'gl_DepthRange', false));
+
+ // Vertex shader builtin variables.
+ testGroup.addChild(new es3fShaderBuiltinVarTests.VertexIDCase());
+ // \todo [2013-03-20 pyry] gl_InstanceID -- tested in instancing tests quite thoroughly.
+
+ // Fragment shader builtin variables.
+ testGroup.addChild(new es3fShaderBuiltinVarTests.FragCoordXYZCase());
+ testGroup.addChild(new es3fShaderBuiltinVarTests.FragCoordWCase());
+ testGroup.addChild(new es3fShaderBuiltinVarTests.PointCoordCase());
+ testGroup.addChild(new es3fShaderBuiltinVarTests.FrontFacingCase());
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fShaderBuiltinVarTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fShaderBuiltinVarTests.ShaderBuiltinVarTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fShaderBuiltinVarTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderCommonFunctionTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderCommonFunctionTests.js
new file mode 100644
index 0000000000..5c24c73f90
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderCommonFunctionTests.js
@@ -0,0 +1,1973 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fShaderCommonFunctionTests');
+goog.require('framework.common.tcuFloat');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluVarType');
+goog.require('modules.shared.glsShaderExecUtil');
+goog.scope(function() {
+ var es3fShaderCommonFunctionTests = functional.gles3.es3fShaderCommonFunctionTests;
+ var tcuFloat = framework.common.tcuFloat;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluVarType = framework.opengl.gluVarType;
+ var deRandom = framework.delibs.debase.deRandom;
+ var deMath = framework.delibs.debase.deMath;
+ var deString = framework.delibs.debase.deString;
+ var glsShaderExecUtil = modules.shared.glsShaderExecUtil;
+
+ /** @typedef {function(new: es3fShaderCommonFunctionTests.CommonFunctionCase, gluShaderUtil.DataType, gluShaderUtil.precision, gluShaderProgram.shaderType)} */ es3fShaderCommonFunctionTests.TestClass;
+
+ /**
+ * @enum
+ */
+ es3fShaderCommonFunctionTests.Types = {
+ FLOAT: 0,
+ INT: 1,
+ UINT: 2
+ };
+
+ /**
+ * @param {Array<number>} values
+ */
+ es3fShaderCommonFunctionTests.vecToFloat16 = function(values) {
+ for (var ndx = 0; ndx < values.length; ndx++)
+ values[ndx] = tcuFloat.newFloat16(values[ndx]).getValue();
+ };
+
+ /**
+ * @param {es3fShaderCommonFunctionTests.Types} type
+ * @param {deRandom.Random} rnd
+ * @param {number} minValue
+ * @param {number} maxValue
+ * @return {number}
+ */
+ es3fShaderCommonFunctionTests.randomScalar = function(type, rnd, minValue, maxValue) {
+ switch (type) {
+ case es3fShaderCommonFunctionTests.Types.FLOAT: return rnd.getFloat(minValue, maxValue);
+ case es3fShaderCommonFunctionTests.Types.INT: return rnd.getInt(minValue, maxValue);
+ case es3fShaderCommonFunctionTests.Types.UINT: return Math.abs(rnd.getInt(minValue, maxValue));
+ default: throw new Error('Only FLOAT, INT, and UINT are supported.');
+ }
+ };
+
+ /**
+ * @param {es3fShaderCommonFunctionTests.Types} type
+ * @param {Array<number>} size
+ * @param {deRandom.Random} rnd
+ * @param {Array<number>} minValue
+ * @param {Array<number>} maxValue
+ * @return {Array<number>}
+ */
+ es3fShaderCommonFunctionTests.randomVector = function(type, size, rnd, minValue, maxValue) {
+ /** @type {Array<number>} */ var res = [];
+ for (var ndx = 0; ndx < size; ndx++)
+ res.push(es3fShaderCommonFunctionTests.randomScalar(type, rnd, minValue[ndx], maxValue[ndx]));
+ return res;
+ };
+
+ /**
+ * @param {es3fShaderCommonFunctionTests.Types} type
+ * @param {Array<number>} size
+ * @param {deRandom.Random} rnd
+ * @param {Array<number>} minValue
+ * @param {Array<number>} maxValue
+ * @param {number} numValues
+ * @param {number=} offset
+ * @return {Array<Array<number>>}
+ */
+ es3fShaderCommonFunctionTests.fillRandomVectors = function(type, size, rnd, minValue, maxValue, numValues, offset) {
+ offset = offset === undefined ? 0 : offset;
+ /** @type {Array<Array<number>>} */ var access;
+ for (var ndx = 0; ndx < numValues; ndx++)
+ access[offset + ndx] = es3fShaderCommonFunctionTests.randomVector(type, size, rnd, minValue, maxValue);
+ return access;
+ };
+
+ /**
+ * @param {es3fShaderCommonFunctionTests.Types} type
+ * @param {deRandom.Random} rnd
+ * @param {number} minValue
+ * @param {number} maxValue
+ * @param {number} numValues
+ * @param {number=} offset
+ * @return {Array<number>}
+ */
+ es3fShaderCommonFunctionTests.fillRandomScalars = function(type, rnd, minValue, maxValue, numValues, offset) {
+ offset = offset === undefined ? 0 : offset;
+ /** @type {Array<number>} */ var access = [];
+ for (var ndx = 0; ndx < numValues; ndx++)
+ access[offset + ndx] = es3fShaderCommonFunctionTests.randomScalar(type, rnd, minValue, maxValue);
+ return access;
+ };
+
+ /**
+ * @param {number} input
+ * @param {number} output
+ * @return {number}
+ */
+ es3fShaderCommonFunctionTests.numBitsLostInOp = function(input, output) {
+ /** @type {number} */ var inExp = tcuFloat.newFloat32(input).exponent();
+ /** @type {number} */ var outExp = tcuFloat.newFloat32(output).exponent();
+ return Math.max(0, inExp - outExp); // Lost due to mantissa shift.
+ };
+
+ /**
+ * @param {number} a
+ * @param {number} b
+ * @return {number}
+ */
+ es3fShaderCommonFunctionTests.getUlpDiff = function(a, b) {
+ /** @type {number} */ var aBits = tcuFloat.newFloat32(a).bits();
+ /** @type {number} */ var bBits = tcuFloat.newFloat32(b).bits();
+ return aBits > bBits ? aBits - bBits : bBits - aBits;
+ };
+
+ /**
+ * @param {number} a
+ * @param {number} b
+ * @return {number}
+ */
+ es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign = function(a, b) {
+ if (tcuFloat.newFloat32(a).isZero())
+ return es3fShaderCommonFunctionTests.getUlpDiff(new tcuFloat.deFloat().construct(tcuFloat.newFloat32(b).sign(), 0, 0).getValue(), b);
+ else if (tcuFloat.newFloat32(b).isZero())
+ return es3fShaderCommonFunctionTests.getUlpDiff(a, new tcuFloat.deFloat().construct(tcuFloat.newFloat32(a).sign(), 0, 0).getValue());
+ else
+ return es3fShaderCommonFunctionTests.getUlpDiff(a, b);
+ };
+
+ /**
+ * @param {gluShaderUtil.precision} precision
+ * @return {boolean}
+ */
+ es3fShaderCommonFunctionTests.supportsSignedZero = function(precision) {
+ // \note GLSL ES 3.0 doesn't really require support for -0, but we require it for highp
+ // as it is very widely supported.
+ return precision == gluShaderUtil.precision.PRECISION_HIGHP;
+ };
+
+ /**
+ * @param {number} value
+ * @param {number} ulpDiff
+ * @return {number}
+ */
+ es3fShaderCommonFunctionTests.getEpsFromMaxUlpDiff = function(value, ulpDiff) {
+ /** @type {number} */ var exp = tcuFloat.newFloat32(value).exponent();
+ return new tcuFloat.deFloat().construct(+1, exp, (1 << 23) | ulpDiff).getValue() - new tcuFloat.deFloat().construct(+1, exp, 1 << 23).getValue();
+ };
+
+ /**
+ * @param {number} numAccurateBits
+ * @return {number}
+ */
+ es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits = function(numAccurateBits) {
+ /** @type {number} */ var numGarbageBits = 23 - numAccurateBits;
+ /** @type {number} */ var mask = (1 << numGarbageBits) - 1;
+
+ return mask;
+ };
+
+ /**
+ * @param {number} value
+ * @param {number} numAccurateBits
+ * @return {number}
+ */
+ es3fShaderCommonFunctionTests.getEpsFromBits = function(value, numAccurateBits) {
+ return es3fShaderCommonFunctionTests.getEpsFromMaxUlpDiff(value, es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(numAccurateBits));
+ };
+
+ /**
+ * @param {gluShaderUtil.precision} precision
+ * @return {number}
+ */
+ es3fShaderCommonFunctionTests.getMinMantissaBits = function(precision) {
+ /** @type {Array<number>} */ var bits = [
+ 7, // lowp
+ 10, // mediump
+ 23 // highp
+ ];
+
+ assertMsgOptions(deMath.deInBounds32(precision, 0, bits.length), 'Unexpected precision option.', false, true);
+ return bits[precision];
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderCommonFunctionTests.CommonFunctionCase = function(name, description, shaderType) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ /** @type {gluShaderProgram.shaderType} */ this.m_shaderType = shaderType;
+ /** @type {number} */ this.m_numValues = 100;
+ /** @type {glsShaderExecUtil.ShaderExecutor} */ this.m_executor = null;
+ /** @type {glsShaderExecUtil.ShaderSpec} */ this.m_spec = new glsShaderExecUtil.ShaderSpec();
+ this.m_spec.version = gluShaderUtil.GLSLVersion.V300_ES;
+ /** @type {string} */ this.m_failMsg; //!< Comparison failure help message.
+ };
+
+ es3fShaderCommonFunctionTests.CommonFunctionCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderCommonFunctionTests.CommonFunctionCase.prototype.constructor = es3fShaderCommonFunctionTests.CommonFunctionCase;
+
+ es3fShaderCommonFunctionTests.CommonFunctionCase.prototype.init = function() {
+ assertMsgOptions(!this.m_executor, 'Shader executor should be null at this point', false, true);
+ this.m_executor = glsShaderExecUtil.createExecutor(this.m_shaderType, this.m_spec);
+ if (!this.m_executor.isOk())
+ throw new Error('Compile failed');
+ };
+
+ es3fShaderCommonFunctionTests.CommonFunctionCase.prototype.deinit = function() {
+ this.m_executor = null;
+ };
+
+ /**
+ * @param {Array<glsShaderExecUtil.Symbol>} symbols
+ * @return {Array<number>}
+ */
+ es3fShaderCommonFunctionTests.getScalarSizes = function(symbols) {
+ /** @type {Array<number>} */ var sizes = [];
+ for (var ndx = 0; ndx < symbols.length; ++ndx)
+ sizes.push(symbols[ndx].varType.getScalarSize());
+ return sizes;
+ };
+
+ /**
+ * @param {Array<glsShaderExecUtil.Symbol>} symbols
+ * @return {number}
+ */
+ es3fShaderCommonFunctionTests.computeTotalScalarSize = function(symbols) {
+ /** @type {number} */ var totalSize = 0;
+ for (var sym in symbols)
+ totalSize += symbols[sym].varType.getScalarSize();
+ return totalSize;
+ };
+
+ /**
+ * @param {boolean} value
+ * @return {string}
+ */
+ es3fShaderCommonFunctionTests.ToBoolString = function(value) {
+ return value ? "true" : "false";
+ };
+
+ /**
+ * @param {gluVarType.VarType} varType
+ * @param {Array<*>} values
+ * @return {string}
+ */
+ es3fShaderCommonFunctionTests.VarValue = function(varType, values) {
+ /** @type {gluShaderUtil.DataType} */ var basicType = varType.getBasicType();
+ /** @type {gluShaderUtil.DataType} */ var scalarType = gluShaderUtil.getDataTypeScalarTypeAsDataType(basicType);
+ /** @type {number} */ var numComponents = gluShaderUtil.getDataTypeScalarSize(basicType);
+ /** @type {string} */ var outputStr = "";
+
+ if (numComponents > 1) {
+ outputStr += gluShaderUtil.getDataTypeName(basicType) + "(";
+ }
+
+ for (var compNdx = 0; compNdx < numComponents; ++compNdx) {
+ if (compNdx != 0) {
+ outputStr += ", ";
+ }
+
+ // tcu::toHex() is all commented out in this project.
+ // e.g. Line 199 of es3fShaderPackingFunctionTests.js
+ switch (scalarType) {
+ case gluShaderUtil.DataType.FLOAT:
+ case gluShaderUtil.DataType.INT:
+ case gluShaderUtil.DataType.UINT:
+ outputStr += values[compNdx];
+ break;
+ case gluShaderUtil.DataType.BOOL:
+ outputStr += es3fShaderCommonFunctionTests.ToBoolString(values[compNdx]);
+ break;
+
+ default:
+ throw Error('Unrecognized dataType ' + scalarType);
+ }
+ }
+
+ if (numComponents > 1) {
+ outputStr += ")";
+ }
+
+ return outputStr;
+ }
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderCommonFunctionTests.CommonFunctionCase.prototype.iterate = function() {
+ /** @type {number} */ var numInputScalars = es3fShaderCommonFunctionTests.computeTotalScalarSize(this.m_spec.inputs);
+ /** @type {number} */ var numOutputScalars = es3fShaderCommonFunctionTests.computeTotalScalarSize(this.m_spec.outputs);
+ /** @type {Array<goog.TypedArray>} */ var inputData = [];
+ /** @type {Array<goog.TypedArray>} */ var outputData = [];
+ /** @type {gluShaderUtil.DataType} */ var inputType = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.DataType} */ var outputType = this.m_spec.outputs[0].varType.getBasicType();
+ /** @type {Array<Array<number>>} */ var inputValues;
+ /** @type {ArrayBuffer} */ var outputValues;
+ inputValues = this.getInputValues(this.m_numValues);
+
+ for (var inNdx = 0; inNdx < inputValues.length; inNdx++) {
+ var data = inputType >= gluShaderUtil.DataType.FLOAT && inputType <= gluShaderUtil.DataType.FLOAT_VEC4 ? new Float32Array(inputValues[inNdx]) :
+ inputType >= gluShaderUtil.DataType.INT && inputType <= gluShaderUtil.DataType.INT_VEC4 ? new Int32Array(inputValues[inNdx]) :
+ inputType >= gluShaderUtil.DataType.UINT && inputType <= gluShaderUtil.DataType.UINT_VEC4 ? new Uint32Array(inputValues[inNdx]) :
+ null;
+ inputData.push(data);
+ }
+
+ // Execute shader.
+ this.m_executor.useProgram();
+ outputValues = this.m_executor.execute(this.m_numValues, inputData);
+ for (var outNdx = 0; outNdx < outputValues.length; outNdx++) {
+ var data = outputType >= gluShaderUtil.DataType.FLOAT && outputType <= gluShaderUtil.DataType.FLOAT_VEC4 ? new Float32Array(outputValues[outNdx].buffer) :
+ outputType >= gluShaderUtil.DataType.INT && outputType <= gluShaderUtil.DataType.INT_VEC4 ? new Int32Array(outputValues[outNdx].buffer) :
+ outputType >= gluShaderUtil.DataType.UINT && outputType <= gluShaderUtil.DataType.UINT_VEC4 ? new Uint32Array(outputValues[outNdx].buffer) :
+ outputType >= gluShaderUtil.DataType.BOOL && outputType <= gluShaderUtil.DataType.BOOL_VEC4 ? new Int32Array(outputValues[outNdx].buffer) :
+ null;
+ outputData.push(data);
+ }
+
+ // TODO: verify proper TypedArray for BOOL types; defaulting to Int32Array in the mean time (outputValues returns 400 bytes, we need 100 elements)
+ // Compare results.
+ /** @type {Array<number>} */ var inScalarSizes = es3fShaderCommonFunctionTests.getScalarSizes(this.m_spec.inputs);
+ /** @type {Array<number>} */ var outScalarSizes = es3fShaderCommonFunctionTests.getScalarSizes(this.m_spec.outputs);
+ /** @type {Array<*>} */ var curInputPtr = [];
+ /** @type {Array<*>} */ var curOutputPtr = [];
+ /** @type {number} */ var numFailed = 0;
+
+ for (var inNdx = 0; inNdx < inputData.length; inNdx++) {
+ curInputPtr[inNdx] = [];
+ for (var valNdx = 0; valNdx < inputData[inNdx].length; valNdx += inScalarSizes[inNdx])
+ curInputPtr[inNdx].push(inputData[inNdx].slice(valNdx, valNdx + inScalarSizes[inNdx]));
+ }
+
+ for (var outNdx = 0; outNdx < outputData.length; outNdx++) {
+ curOutputPtr[outNdx] = [];
+ for (var valNdx = 0; valNdx < outputData[outNdx].length; valNdx += outScalarSizes[outNdx])
+ curOutputPtr[outNdx].push(outputData[outNdx].slice(valNdx, valNdx + outScalarSizes[outNdx]));
+ }
+
+ this.m_failMsg = '';
+ for (var valNdx = 0; valNdx < this.m_numValues; valNdx++) {
+ var curInputValues = [];
+ var curOutputValues = [];
+ for (var inNdx = 0; inNdx < inputData.length; inNdx++) {
+ curInputValues.push(curInputPtr[inNdx][valNdx]);
+ }
+ for (var outNdx = 0; outNdx < outputData.length; outNdx++) {
+ curOutputValues.push(curOutputPtr[outNdx][valNdx]);
+ }
+ if (!this.compare(curInputValues, curOutputValues)) {
+ // \todo [2013-08-08 pyry] We probably want to log reference value as well?
+
+ bufferedLogToConsole('ERROR: comparison failed for value ' + valNdx + ':\n ' + this.m_failMsg);
+ bufferedLogToConsole(' inputs:');
+ for (var inNdx = 0; inNdx < inputData.length; ++inNdx) {
+ var varValue = es3fShaderCommonFunctionTests.VarValue(this.m_spec.inputs[0].varType, curInputValues[inNdx]);
+ bufferedLogToConsole(' ' + this.m_spec.inputs[inNdx].name + ' = ' + varValue);
+ }
+
+ bufferedLogToConsole(' outputs:');
+ for (var outNdx = 0; outNdx < outputData.length; ++outNdx) {
+ var varValue = es3fShaderCommonFunctionTests.VarValue(this.m_spec.inputs[0].varType, curOutputValues[outNdx]);
+ bufferedLogToConsole(' ' + this.m_spec.outputs[outNdx].name + ' = ' + varValue);
+ }
+
+ this.m_failMsg = '';
+ numFailed += 1;
+ }
+ }
+
+ bufferedLogToConsole((this.m_numValues - numFailed) + ' / ' + this.m_numValues + ' values passed');
+
+ /** @type {boolean} */ var isOk = numFailed === 0;
+
+ if (!isOk)
+ testFailedOptions('Result comparison failed', false);
+ else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @param {gluShaderUtil.precision} precision
+ * @return {string}
+ */
+ es3fShaderCommonFunctionTests.getPrecisionPostfix = function(precision) {
+ /** @type {Array<string>} */ var s_postfix = [
+ '_lowp',
+ '_mediump',
+ '_highp'
+ ];
+ assertMsgOptions(0 <= precision && precision < s_postfix.length, 'Error: Out of range', false, true);
+ return s_postfix[precision];
+ };
+
+ /**
+ * @param {gluShaderProgram.shaderType} shaderType
+ * @return {string}
+ */
+ es3fShaderCommonFunctionTests.getShaderTypePostfix = function(shaderType) {
+ /** @type {Array<string>} */ var s_postfix = [
+ '_vertex',
+ '_fragment'
+ ];
+ assertMsgOptions(0 <= shaderType && shaderType < s_postfix.length, 'Error Out of range', false, true);
+ return s_postfix[shaderType];
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderUtil.precision} precision
+ * @param {gluShaderProgram.shaderType} shaderType
+ * @return {string}
+ */
+ es3fShaderCommonFunctionTests.getCommonFuncCaseName = function(baseType, precision, shaderType) {
+ return gluShaderUtil.getDataTypeName(baseType) +
+ es3fShaderCommonFunctionTests.getPrecisionPostfix(precision) +
+ es3fShaderCommonFunctionTests.getShaderTypePostfix(shaderType);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase}
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderUtil.precision} precision
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderCommonFunctionTests.AbsCase = function(baseType, precision, shaderType) {
+ es3fShaderCommonFunctionTests.CommonFunctionCase.call(this,
+ es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType),
+ 'abs', shaderType);
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.source = 'out0 = abs(in0);';
+ };
+
+ es3fShaderCommonFunctionTests.AbsCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype);
+ es3fShaderCommonFunctionTests.AbsCase.prototype.constructor = es3fShaderCommonFunctionTests.AbsCase;
+
+ /**
+ * @param {number} numValues
+ * @return {*}
+ */
+ es3fShaderCommonFunctionTests.AbsCase.prototype.getInputValues = function(numValues) {
+ /** @type {Array<Array<number>>} */ var floatRanges = [
+ [-2.0, 2.0], // lowp
+ [-1e3, 1e3], // mediump
+ [-1e7, 1e7] // highp
+ ];
+
+ /** @type {Array<Array<number>>} */ var intRanges = [
+ [-(1 << 7) + 1, (1 << 7) - 1],
+ [-(1 << 15) + 1, (1 << 15) - 1],
+ [-0x80000000 + 1, 0x7fffffff]
+ ];
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0x235fac);
+
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {Array<Array<number>>} */ var values = [];
+ values[0] = [];
+
+ if (gluShaderUtil.isDataTypeFloatOrVec(type))
+ values[0] = es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, floatRanges[precision][0], floatRanges[precision][1], numValues * scalarSize);
+ else
+ values[0] = es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.INT, rnd, intRanges[precision][0], intRanges[precision][1], numValues * scalarSize);
+
+ return values;
+ };
+
+ /**
+ * @param {*} inputs
+ * @param {*} outputs
+ * @return {boolean}
+ */
+ es3fShaderCommonFunctionTests.AbsCase.prototype.compare = function(inputs, outputs) {
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+
+ /** @type {number} */ var in0;
+ /** @type {number} */ var out0;
+ /** @type {number} */ var ref0;
+
+ if (gluShaderUtil.isDataTypeFloatOrVec(type)) {
+ /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision);
+ /** @type {number} */ var maxUlpDiff = (1 << (23 - mantissaBits)) - 1;
+
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ ref0 = Math.abs(in0);
+ /** @type {number} */ var ulpDiff0 = es3fShaderCommonFunctionTests.getUlpDiff(out0, ref0);
+
+ if (ulpDiff0 > maxUlpDiff) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref0 /*HexFloat(ref0)*/ + ' with ULP threshold ' + maxUlpDiff + ', got ULP diff ' + ulpDiff0;
+ return false;
+ }
+ }
+ } else
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ ref0 = Math.abs(in0);
+
+ if (out0 != ref0) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref0;
+ return false;
+ }
+ }
+
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase}
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderUtil.precision} precision
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderCommonFunctionTests.SignCase = function(baseType, precision, shaderType) {
+ es3fShaderCommonFunctionTests.CommonFunctionCase.call(this,
+ es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType),
+ 'sign', shaderType);
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.source = 'out0 = sign(in0);';
+ };
+
+ es3fShaderCommonFunctionTests.SignCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype);
+ es3fShaderCommonFunctionTests.SignCase.prototype.constructor = es3fShaderCommonFunctionTests.SignCase;
+
+ /**
+ * @param {number} numValues
+ * @return {*}
+ */
+ es3fShaderCommonFunctionTests.SignCase.prototype.getInputValues = function(numValues) {
+ /** @type {Array<Array<number>>} */ var floatRanges = [
+ [-2.0, 2.0], // lowp
+ [-1e4, 1e4], // mediump
+ [-1e8, 1e8] // highp
+ ];
+
+ /** @type {Array<Array<number>>} */ var intRanges = [
+ [-(1 << 7), (1 << 7) - 1],
+ [-(1 << 15), (1 << 15) - 1],
+ [0x80000000, 0x7fffffff]
+ ];
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0x324);
+
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {Array<Array<number>>} */ var values = [];
+ values[0] = [];
+
+ if (gluShaderUtil.isDataTypeFloatOrVec(type)) {
+ // Special cases.
+ // [dag] The special cases are 1, -1, and 0
+ var specialCases = [1.0, -1.0, 0.0];
+ for (var caseNdx = 0; caseNdx < specialCases.length; caseNdx++)
+ for (var scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) {
+ values[0].push(specialCases[caseNdx]);
+ }
+ values[0] = values[0].concat(es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, floatRanges[precision][0], floatRanges[precision][1], (numValues - 3) * scalarSize));
+ } else {
+ var specialCases = [1, -1, 0];
+ for (var caseNdx = 0; caseNdx < specialCases.length; caseNdx++)
+ for (var scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) {
+ values[0].push(specialCases[caseNdx]);
+ }
+ values[0] = values[0].concat(es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.INT, rnd, intRanges[precision][0], intRanges[precision][1], (numValues - 3) * scalarSize));
+ }
+
+ return values;
+ };
+
+ /**
+ * @param {*} inputs
+ * @param {*} outputs
+ * @return {boolean}
+ */
+ es3fShaderCommonFunctionTests.SignCase.prototype.compare = function(inputs, outputs) {
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+
+ /** @type {number} */ var in0;
+ /** @type {number} */ var out0;
+ /** @type {number} */ var ref0;
+
+ if (gluShaderUtil.isDataTypeFloatOrVec(type)) {
+ // Both highp and mediump should be able to represent -1, 0, and +1 exactly
+ /** @type {number} */ var maxUlpDiff = precision === gluShaderUtil.precision.PRECISION_LOWP ?
+ es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(es3fShaderCommonFunctionTests.getMinMantissaBits(precision)) :
+ 0;
+
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ ref0 = in0 < 0.0 ? -1.0 :
+ in0 > 0.0 ? 1.0 : 0.0;
+ /** @type {number} */ var ulpDiff0 = es3fShaderCommonFunctionTests.getUlpDiff(out0, ref0);
+
+ if (ulpDiff0 > maxUlpDiff) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref0 /*HexFloat(ref0)*/ + ' with ULP threshold ' + maxUlpDiff + ', got ULP diff ' + ulpDiff0;
+ return false;
+ }
+ }
+ } else {
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ ref0 = in0 < 0 ? -1 :
+ in0 > 0 ? 1 : 0;
+
+ if (out0 != ref0) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref0;
+ return false;
+ }
+ }
+ }
+
+ return true;
+ };
+
+ /**
+ * @param {number} v
+ * @return {number}
+ */
+ es3fShaderCommonFunctionTests.roundEven = function(v) {
+ /** @type {number} */ var q = deMath.deFloatFrac(v);
+ /** @type {number} */ var truncated = Math.trunc(v - q);
+ /** @type {number} */ var rounded = (q > 0.5) ? (truncated + 1) : // Rounded up
+ (q == 0.5 && (truncated % 2 != 0)) ? (truncated + 1) : // Round to nearest even at 0.5
+ truncated; // Rounded down
+ return rounded;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase}
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderUtil.precision} precision
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderCommonFunctionTests.RoundEvenCase = function(baseType, precision, shaderType) {
+ es3fShaderCommonFunctionTests.CommonFunctionCase.call(this,
+ es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType),
+ 'roundEven', shaderType);
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.source = 'out0 = roundEven(in0);';
+ };
+
+ es3fShaderCommonFunctionTests.RoundEvenCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype);
+ es3fShaderCommonFunctionTests.RoundEvenCase.prototype.constructor = es3fShaderCommonFunctionTests.RoundEvenCase;
+
+ /**
+ * @param {number} numValues
+ * @return {*}
+ */
+ es3fShaderCommonFunctionTests.RoundEvenCase.prototype.getInputValues = function(numValues) {
+ /** @type {Array<Array<number>>} */ var ranges = [
+ [-2.0, 2.0], // lowp
+ [-1e3, 1e3], // mediump
+ [-1e7, 1e7] // highp
+ ];
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xac23f);
+
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {number} */ var numSpecialCases = 0;
+ /** @type {Array<Array<number>>} */ var values = [];
+ values[0] = [];
+ // Special cases.
+ if (precision !== gluShaderUtil.precision.PRECISION_LOWP) {
+ assertMsgOptions(numValues >= 20, 'numValues should be greater or equal than 20', false, true);
+ for (var ndx = 0; ndx < 20; ndx++) {
+ /** @type {number} */ var v = deMath.clamp(ndx - 10.5, ranges[precision][0], ranges[precision][1]);
+ for (var scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) {
+ values[0].push(v);
+ }
+ numSpecialCases += 1;
+ }
+ }
+
+ // Random cases.
+ values[0] = values[0].concat(es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], (numValues - numSpecialCases) * scalarSize));
+
+ // If precision is mediump, make sure values can be represented in fp16 exactly
+ if (precision === gluShaderUtil.precision.PRECISION_MEDIUMP)
+ es3fShaderCommonFunctionTests.vecToFloat16(values[0]);
+
+ return values;
+ };
+
+ /**
+ * @param {*} inputs
+ * @param {*} outputs
+ * @return {boolean}
+ */
+ es3fShaderCommonFunctionTests.RoundEvenCase.prototype.compare = function(inputs, outputs) {
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {number} */ var in0;
+ /** @type {number} */ var out0;
+
+ if (precision == gluShaderUtil.precision.PRECISION_HIGHP || precision == gluShaderUtil.precision.PRECISION_MEDIUMP) {
+ // Require exact rounding result.
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ /** @type {number} */ var ref = es3fShaderCommonFunctionTests.roundEven(in0);
+
+ /** @type {number} */ var ulpDiff = es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref);
+
+ if (ulpDiff > 0) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref + ', got ULP diff ' + ulpDiff;
+ return false;
+ }
+ }
+ } else {
+ /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision);
+ /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits); // ULP diff for rounded integer value.
+ /** @type {number} */ var eps = es3fShaderCommonFunctionTests.getEpsFromBits(1.0, mantissaBits); // epsilon for rounding bounds
+
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ /** @type {number} */ var minRes = Math.floor(es3fShaderCommonFunctionTests.roundEven(in0 - eps));
+ /** @type {number} */ var maxRes = Math.floor(es3fShaderCommonFunctionTests.roundEven(in0 + eps));
+ /** @type {boolean} */ var anyOk = false;
+
+ for (var roundedVal = minRes; roundedVal <= maxRes; roundedVal++) {
+ ulpDiff = es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, roundedVal);
+
+ if (ulpDiff <= maxUlpDiff) {
+ anyOk = true;
+ break;
+ }
+ }
+
+ if (!anyOk) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = [' + minRes + ', ' + maxRes + '] with ULP threshold ' + maxUlpDiff;
+ return false;
+ }
+ }
+ }
+
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase}
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderUtil.precision} precision
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderCommonFunctionTests.ModfCase = function(baseType, precision, shaderType) {
+ es3fShaderCommonFunctionTests.CommonFunctionCase.call(this,
+ es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType),
+ 'modf', shaderType);
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out1', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.source = 'out0 = modf(in0, out1);';
+ };
+
+ es3fShaderCommonFunctionTests.ModfCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype);
+ es3fShaderCommonFunctionTests.ModfCase.prototype.constructor = es3fShaderCommonFunctionTests.ModfCase;
+
+ /**
+ * @param {number} numValues
+ * @return {*}
+ */
+ es3fShaderCommonFunctionTests.ModfCase.prototype.getInputValues = function(numValues) {
+ /** @type {Array<Array<number>>} */ var ranges = [
+ [-2.0, 2.0], // lowp
+ [-1e3, 1e3], // mediump
+ [-1e7, 1e7] // highp
+ ];
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xac23f);
+
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {Array<Array<number>>} */ var values = [];
+ values[0] = es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], numValues * scalarSize);
+
+ return values;
+ };
+
+ /**
+ * @param {*} inputs
+ * @param {*} outputs
+ * @return {boolean}
+ */
+ es3fShaderCommonFunctionTests.ModfCase.prototype.compare = function(inputs, outputs) {
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {boolean} */ var hasZeroSign = es3fShaderCommonFunctionTests.supportsSignedZero(precision);
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision);
+ /** @type {number} */ var in0;
+ /** @type {number} */ var out0;
+ /** @type {number} */ var out1;
+
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ out1 = outputs[1][compNdx];
+
+ /** @type {number} */ var refOut1 = Math.floor(in0);
+ /** @type {number} */ var refOut0 = in0 - refOut1;
+
+ /** @type {number} */ var bitsLost = precision != gluShaderUtil.precision.PRECISION_HIGHP ? es3fShaderCommonFunctionTests.numBitsLostInOp(in0, refOut0) : 0;
+ /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(Math.max(mantissaBits - bitsLost, 0));
+
+ /** @type {number} */ var resSum = out0 + out1;
+
+ /** @type {number} */ var ulpDiff = hasZeroSign ? es3fShaderCommonFunctionTests.getUlpDiff(resSum, in0) : es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(resSum, in0);
+
+ if (ulpDiff > maxUlpDiff) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = (' + refOut0 + ') + (' + refOut1 + ') = ' + in0 + ' with ULP threshold ' +
+ maxUlpDiff + ', got ULP diff ' + ulpDiff;
+ return false;
+ }
+ }
+
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase}
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderUtil.precision} precision
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderCommonFunctionTests.IsnanCase = function(baseType, precision, shaderType) {
+ es3fShaderCommonFunctionTests.CommonFunctionCase.call(this,
+ es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType),
+ 'isnan', shaderType);
+ assertMsgOptions(gluShaderUtil.isDataTypeFloatOrVec(baseType), 'Assert error.', false, true);
+
+ /** @type {number} */ var vecSize = gluShaderUtil.getDataTypeScalarSize(baseType);
+ /** @type {gluShaderUtil.DataType} */ var boolType = vecSize > 1 ?
+ gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.BOOL, vecSize) :
+ gluShaderUtil.DataType.BOOL;
+
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(boolType)));
+ this.m_spec.source = 'out0 = isnan(in0);';
+ };
+
+ es3fShaderCommonFunctionTests.IsnanCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype);
+ es3fShaderCommonFunctionTests.IsnanCase.prototype.constructor = es3fShaderCommonFunctionTests.IsnanCase;
+
+ /**
+ * @param {number} numValues
+ * @return {*}
+ */
+ es3fShaderCommonFunctionTests.IsnanCase.prototype.getInputValues = function(numValues) {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xc2a39f);
+
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision);
+ /** @type {number} */ var mantissaMask = (~es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits)) & ((1 << 23) - 1);
+ /** @type {Array<Array<number>>} */ var values = [];
+ values[0] = [];
+
+ for (var valNdx = 0; valNdx < numValues * scalarSize; valNdx++) {
+ /** @type {boolean} */ var isNan = rnd.getFloat() > 0.3;
+ /** @type {boolean} */ var isInf = !isNan && rnd.getFloat() > 0.4;
+ /** @type {number} */ var mantissa = !isInf ? ((1 << 22) | (Math.abs(rnd.getInt()) & mantissaMask)) : 0;
+ /** @type {number} */ var exp = !isNan && !isInf ? (Math.abs(rnd.getInt()) & 0x7f) : 0xff;
+ /** @type {number} */ var sign = Math.abs(rnd.getInt()) & 0x1;
+ /** @type {number} */ var value = (sign << 31) | (exp << 23) | mantissa;
+
+ // Convert int to float.
+ var view = new DataView(new ArrayBuffer(4));
+ view.setInt32(0, value, true);
+ value = view.getFloat32(0, true);
+
+ assertMsgOptions(tcuFloat.newFloat32(value).isInf() === isInf && tcuFloat.newFloat32(value).isNaN() === isNan, 'Assert error.', false, true);
+
+ values[0].push(value);
+ }
+
+ return values;
+ };
+
+ /**
+ * @param {*} inputs
+ * @param {*} outputs
+ * @return {boolean}
+ */
+ es3fShaderCommonFunctionTests.IsnanCase.prototype.compare = function(inputs, outputs) {
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+
+ /** @type {number} */ var in0;
+ /** @type {number} */ var out0;
+ /** @type {number} */ var ref;
+
+ if (precision === gluShaderUtil.precision.PRECISION_HIGHP) {
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ ref = tcuFloat.newFloat32(in0).isNaN() ? 1 : 0;
+
+ if (out0 !== ref) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref;
+ return false;
+ }
+ }
+ } else {
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ out0 = outputs[0][compNdx];
+
+ if (out0 !== 0 && out0 !== 1) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = 0 / 1';
+ return false;
+ }
+ }
+ }
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase}
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderUtil.precision} precision
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderCommonFunctionTests.IsinfCase = function(baseType, precision, shaderType) {
+ es3fShaderCommonFunctionTests.CommonFunctionCase.call(this,
+ es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType),
+ 'isinf', shaderType);
+ assertMsgOptions(gluShaderUtil.isDataTypeFloatOrVec(baseType), 'Assert error.', false, true);
+
+ /** @type {number} */ var vecSize = gluShaderUtil.getDataTypeScalarSize(baseType);
+ /** @type {gluShaderUtil.DataType} */ var boolType = vecSize > 1 ?
+ gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.BOOL, vecSize) :
+ gluShaderUtil.DataType.BOOL;
+
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(boolType)));
+ this.m_spec.source = 'out0 = isinf(in0);';
+ };
+
+ es3fShaderCommonFunctionTests.IsinfCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype);
+ es3fShaderCommonFunctionTests.IsinfCase.prototype.constructor = es3fShaderCommonFunctionTests.IsinfCase;
+
+ /**
+ * @param {number} numValues
+ * @return {*}
+ */
+ es3fShaderCommonFunctionTests.IsinfCase.prototype.getInputValues = function(numValues) {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xc2a39f);
+
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision);
+ /** @type {number} */ var mantissaMask = (~es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits)) & ((1 << 23) - 1);
+ /** @type {Array<Array<number>>} */ var values = [];
+ values[0] = [];
+
+ for (var valNdx = 0; valNdx < numValues * scalarSize; valNdx++) {
+ /** @type {boolean} */ var isInf = rnd.getFloat() > 0.3;
+ /** @type {boolean} */ var isNan = !isInf && rnd.getFloat() > 0.4;
+ /** @type {number} */ var mantissa = !isInf ? ((1 << 22) | (Math.abs(rnd.getInt()) & mantissaMask)) : 0;
+ /** @type {number} */ var exp = !isNan && !isInf ? (Math.abs(rnd.getInt()) & 0x7f) : 0xff;
+ /** @type {number} */ var sign = Math.abs(rnd.getInt()) & 0x1;
+ /** @type {number} */ var value = (sign << 31) | (exp << 23) | mantissa;
+
+ // Convert int to float.
+ var view = new DataView(new ArrayBuffer(4));
+ view.setInt32(0, value, true);
+ value = view.getFloat32(0, true);
+
+ assertMsgOptions(tcuFloat.newFloat32(value).isInf() === isInf && tcuFloat.newFloat32(value).isNaN() === isNan, 'Assert error.', false, true);
+
+ values[0].push(value);
+ }
+
+ return values;
+ };
+
+ /**
+ * @param {*} inputs
+ * @param {*} outputs
+ * @return {boolean}
+ */
+ es3fShaderCommonFunctionTests.IsinfCase.prototype.compare = function(inputs, outputs) {
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+
+ /** @type {number} */ var in0;
+ /** @type {number} */ var out0;
+ /** @type {number} */ var ref;
+
+ if (precision === gluShaderUtil.precision.PRECISION_HIGHP) {
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ ref = tcuFloat.newFloat32(in0).isInf() ? 1 : 0;
+
+ if (out0 !== ref) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref;
+ return false;
+ }
+ }
+ } else {
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ out0 = outputs[0][compNdx];
+
+ if (out0 !== 0 && out0 !== 1) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = 0 / 1';
+ return false;
+ }
+ }
+ }
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase}
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderUtil.precision} precision
+ * @param {gluShaderProgram.shaderType} shaderType
+ * @param {boolean} outIsSigned
+ */
+ es3fShaderCommonFunctionTests.FloatBitsToUintIntCase = function(baseType, precision, shaderType, outIsSigned) {
+ es3fShaderCommonFunctionTests.CommonFunctionCase.call(this,
+ es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType),
+ outIsSigned ? 'floatBitsToInt' : 'floatBitsToUint', shaderType);
+
+ /** @type {number} */ var vecSize = gluShaderUtil.getDataTypeScalarSize(baseType);
+ /** @type {gluShaderUtil.DataType} */ var intType = outIsSigned ?
+ (vecSize > 1 ? gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.INT, vecSize) : gluShaderUtil.DataType.INT) :
+ (vecSize > 1 ? gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.UINT, vecSize) : gluShaderUtil.DataType.UINT);
+
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(intType, gluShaderUtil.precision.PRECISION_HIGHP)));
+ this.m_spec.source = outIsSigned ? 'out0 = floatBitsToInt(in0);' : 'out0 = floatBitsToUint(in0);';
+ };
+
+ es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype);
+ es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.prototype.constructor = es3fShaderCommonFunctionTests.FloatBitsToUintIntCase;
+
+ /**
+ * @param {number} numValues
+ * @return {*}
+ */
+ es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.prototype.getInputValues = function(numValues) {
+
+ /** @type {Array<number>} */ var ranges = [
+ [-2.0, 2.0], // lowp
+ [-1e3, 1e3], // mediump
+ [-1e7, 1e7] // highp
+ ];
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0x2790a);
+
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {Array<Array<number>>} */ var values = [];
+
+ values[0] = es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], numValues * scalarSize);
+ return values;
+ };
+
+ /**
+ * @param {*} inputs
+ * @param {*} outputs
+ * @return {boolean}
+ */
+ es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.prototype.compare = function(inputs, outputs) {
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision);
+ /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits);
+
+ /** @type {number} */ var in0;
+ /** @type {number} */ var out0;
+ /** @type {number} */ var refOut0;
+ /** @type {number} */ var ulpDiff;
+
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+
+ // Convert int to uint because ref out is in uint format.
+ var view = new DataView(new ArrayBuffer(4));
+ view.setInt32(0, out0, true);
+ out0 = view.getUint32(0, true);
+
+ refOut0 = tcuFloat.newFloat32(in0).bits();
+ ulpDiff = Math.abs(out0 - refOut0);
+ if (ulpDiff > maxUlpDiff) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + refOut0 + ' with threshold ' +
+ maxUlpDiff + ', got diff ' + ulpDiff;
+ return false;
+ }
+ }
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderCommonFunctionTests.FloatBitsToUintIntCase}
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderUtil.precision} precision
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderCommonFunctionTests.FloatBitsToIntCase = function(baseType, precision, shaderType) {
+ es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.call(this, baseType, precision, shaderType, true);
+ };
+
+ es3fShaderCommonFunctionTests.FloatBitsToIntCase.prototype = Object.create(es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.prototype);
+ es3fShaderCommonFunctionTests.FloatBitsToIntCase.prototype.constructor = es3fShaderCommonFunctionTests.FloatBitsToIntCase;
+
+ /**
+ * @constructor
+ * @extends {es3fShaderCommonFunctionTests.FloatBitsToUintIntCase}
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderUtil.precision} precision
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderCommonFunctionTests.FloatBitsToUintCase = function(baseType, precision, shaderType) {
+ es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.call(this, baseType, precision, shaderType, false);
+ };
+
+ es3fShaderCommonFunctionTests.FloatBitsToUintCase.prototype = Object.create(es3fShaderCommonFunctionTests.FloatBitsToUintIntCase.prototype);
+ es3fShaderCommonFunctionTests.FloatBitsToUintCase.prototype.constructor = es3fShaderCommonFunctionTests.FloatBitsToUintCase;
+
+ /**
+ * @constructor
+ * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase}
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderCommonFunctionTests.BitsToFloatCase = function(baseType, shaderType) {
+ es3fShaderCommonFunctionTests.CommonFunctionCase.call(this,
+ es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, gluShaderUtil.precision.PRECISION_HIGHP, shaderType),
+ gluShaderUtil.isDataTypeIntOrIVec(baseType) ? 'intBitsToFloat' : 'uintBitsToFloat', shaderType);
+ /** @type {boolean} */ var inIsSigned = gluShaderUtil.isDataTypeIntOrIVec(baseType);
+ /** @type {number} */ var vecSize = gluShaderUtil.getDataTypeScalarSize(baseType);
+ /** @type {gluShaderUtil.DataType} */ var floatType = vecSize > 1 ? gluShaderUtil.getDataTypeFloatVec(vecSize) : gluShaderUtil.DataType.FLOAT;
+
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, gluShaderUtil.precision.PRECISION_HIGHP)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(floatType, gluShaderUtil.precision.PRECISION_HIGHP)));
+ this.m_spec.source = inIsSigned ? 'out0 = intBitsToFloat(in0);' : 'out0 = uintBitsToFloat(in0);';
+ };
+
+ es3fShaderCommonFunctionTests.BitsToFloatCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype);
+ es3fShaderCommonFunctionTests.BitsToFloatCase.prototype.constructor = es3fShaderCommonFunctionTests.BitsToFloatCase;
+
+ /**
+ * @param {number} numValues
+ * @return {*}
+ */
+ es3fShaderCommonFunctionTests.BitsToFloatCase.prototype.getInputValues = function(numValues) {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xbbb225);
+
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {Array<number>} */ var range = [-1e8, 1e8];
+ /** @type {Array<Array<number>>} */ var values = [];
+
+ values[0] = es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, range[0], range[1], numValues * scalarSize);
+ return values;
+ };
+
+ /**
+ * @param {*} inputs
+ * @param {*} outputs
+ * @return {boolean}
+ */
+ es3fShaderCommonFunctionTests.BitsToFloatCase.prototype.compare = function(inputs, outputs) {
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {number} */ var maxUlpDiff = 0;
+
+ /** @type {number} */ var in0;
+ /** @type {number} */ var out0;
+ /** @type {number} */ var ulpDiff;
+ /** @type {number} */ var refOut0;
+
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+
+ // Convert int to float
+ var view = new DataView(new ArrayBuffer(4));
+ view.setInt32(0, in0, true);
+ in0 = view.getFloat32(0, true);
+
+ ulpDiff = es3fShaderCommonFunctionTests.getUlpDiff(in0, out0);
+ if (ulpDiff > maxUlpDiff) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + in0 + ' with ULP threshold ' +
+ maxUlpDiff + ', got ULP diff ' + ulpDiff;
+ return false;
+ }
+ }
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase}
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderUtil.precision} precision
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderCommonFunctionTests.FloorCase = function(baseType, precision, shaderType) {
+ es3fShaderCommonFunctionTests.CommonFunctionCase.call(this,
+ es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType),
+ 'floor', shaderType);
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.source = 'out0 = floor(in0);';
+ };
+
+ es3fShaderCommonFunctionTests.FloorCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype);
+ es3fShaderCommonFunctionTests.FloorCase.prototype.constructor = es3fShaderCommonFunctionTests.FloorCase;
+
+ /**
+ * @param {number} numValues
+ * @return {*}
+ */
+ es3fShaderCommonFunctionTests.FloorCase.prototype.getInputValues = function(numValues) {
+ /** @type {Array<Array<number>>} */ var ranges = [
+ [-2.0, 2.0], // lowp
+ [-1e3, 1e3], // mediump
+ [-1e7, 1e7] // highp
+ ];
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xac23f);
+
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {Array<Array<number>>} */ var values = [];
+ // Random cases.
+ values[0] = es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], numValues * scalarSize);
+
+ // If precision is mediump, make sure values can be represented in fp16 exactly
+ if (precision === gluShaderUtil.precision.PRECISION_MEDIUMP)
+ es3fShaderCommonFunctionTests.vecToFloat16(values[0]);
+
+ return values;
+ };
+
+ /**
+ * @param {*} inputs
+ * @param {*} outputs
+ * @return {boolean}
+ */
+ es3fShaderCommonFunctionTests.FloorCase.prototype.compare = function(inputs, outputs) {
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+
+ /** @type {number} */ var in0;
+ /** @type {number} */ var out0;
+ /** @type {number} */ var ref;
+ /** @type {number} */ var ulpDiff;
+
+ if (precision === gluShaderUtil.precision.PRECISION_HIGHP || precision === gluShaderUtil.precision.PRECISION_MEDIUMP) {
+ // Require exact result.
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ ref = Math.floor(in0);
+
+ ulpDiff = es3fShaderCommonFunctionTests.getUlpDiff(out0, ref);
+
+ if (ulpDiff > 0) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref + ', got ULP diff ' + ulpDiff;
+ return false;
+ }
+ }
+ } else {
+ /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision);
+ /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits); // ULP diff for rounded integer value.
+ /** @type {number} */ var eps = es3fShaderCommonFunctionTests.getEpsFromBits(1.0, mantissaBits); // epsilon for rounding bounds
+
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ /** @type {number} */ var minRes = Math.floor(in0 - eps);
+ /** @type {number} */ var maxRes = Math.floor(in0 + eps);
+ /** @type {boolean} */ var anyOk = false;
+
+ for (var roundedVal = minRes; roundedVal <= maxRes; roundedVal++) {
+ ulpDiff = es3fShaderCommonFunctionTests.getUlpDiff(out0, roundedVal);
+
+ if (ulpDiff <= maxUlpDiff) {
+ anyOk = true;
+ break;
+ }
+ }
+
+ if (!anyOk) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = [' + minRes + ', ' + maxRes + '] with ULP threshold ' + maxUlpDiff;
+ return false;
+ }
+ }
+ }
+
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase}
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderUtil.precision} precision
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderCommonFunctionTests.TruncCase = function(baseType, precision, shaderType) {
+ es3fShaderCommonFunctionTests.CommonFunctionCase.call(this,
+ es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType),
+ 'trunc', shaderType);
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.source = 'out0 = trunc(in0);';
+ };
+
+ es3fShaderCommonFunctionTests.TruncCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype);
+ es3fShaderCommonFunctionTests.TruncCase.prototype.constructor = es3fShaderCommonFunctionTests.TruncCase;
+
+ /**
+ * @param {number} numValues
+ * @return {*}
+ */
+ es3fShaderCommonFunctionTests.TruncCase.prototype.getInputValues = function(numValues) {
+ /** @type {Array<Array<number>>} */ var ranges = [
+ [-2.0, 2.0], // lowp
+ [-1e3, 1e3], // mediump
+ [-1e7, 1e7] // highp
+ ];
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xac23f);
+
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+
+ /** @type {Array<number>} */ var specialCases = [0.0, -0.0, -0.9, 0.9, 1.0, -1.0];
+ /** @type {Array<Array<number>>} */ var values = [];
+ values[0] = [];
+
+ // Special cases
+ for (var caseNdx = 0; caseNdx < specialCases.length; caseNdx++)
+ for (var scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++)
+ values[0].push(specialCases[caseNdx]);
+
+ // Random cases.
+ values[0] = values[0].concat(es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], (numValues - specialCases.length) * scalarSize));
+
+ // If precision is mediump, make sure values can be represented in fp16 exactly
+ if (precision === gluShaderUtil.precision.PRECISION_MEDIUMP)
+ es3fShaderCommonFunctionTests.vecToFloat16(values[0]);
+
+ return values;
+ };
+
+ /**
+ * @param {*} inputs
+ * @param {*} outputs
+ * @return {boolean}
+ */
+ es3fShaderCommonFunctionTests.TruncCase.prototype.compare = function(inputs, outputs) {
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+
+ /** @type {number} */ var in0;
+ /** @type {number} */ var out0;
+ /** @type {number} */ var ref;
+ /** @type {number} */ var ulpDiff;
+
+ if (precision === gluShaderUtil.precision.PRECISION_HIGHP || precision === gluShaderUtil.precision.PRECISION_MEDIUMP) {
+ // Require exact result.
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ /** @type {boolean} */ var isNeg = tcuFloat.newFloat32(in0).sign() < 0;
+ ref = isNeg ? (-Math.floor(-in0)) : Math.floor(in0);
+
+ // \note: trunc() function definition is a bit broad on negative zeros. Ignore result sign if zero.
+ ulpDiff = es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref);
+
+ if (ulpDiff > 0) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref + ', got ULP diff ' + ulpDiff;
+ return false;
+ }
+ }
+ } else {
+ /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision);
+ /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits); // ULP diff for rounded integer value.
+ /** @type {number} */ var eps = es3fShaderCommonFunctionTests.getEpsFromBits(1.0, mantissaBits); // epsilon for rounding bounds
+
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ /** @type {number} */ var minRes = Math.trunc(in0 - eps);
+ /** @type {number} */ var maxRes = Math.trunc(in0 + eps);
+ /** @type {boolean} */ var anyOk = false;
+
+ for (var roundedVal = minRes; roundedVal <= maxRes; roundedVal++) {
+ ulpDiff = es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, roundedVal);
+
+ if (ulpDiff <= maxUlpDiff) {
+ anyOk = true;
+ break;
+ }
+ }
+
+ if (!anyOk) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = [' + minRes + ', ' + maxRes + '] with ULP threshold ' + maxUlpDiff;
+ return false;
+ }
+ }
+ }
+
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase}
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderUtil.precision} precision
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderCommonFunctionTests.RoundCase = function(baseType, precision, shaderType) {
+ es3fShaderCommonFunctionTests.CommonFunctionCase.call(this,
+ es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType),
+ 'round', shaderType);
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.source = 'out0 = round(in0);';
+ };
+
+ es3fShaderCommonFunctionTests.RoundCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype);
+ es3fShaderCommonFunctionTests.RoundCase.prototype.constructor = es3fShaderCommonFunctionTests.RoundCase;
+
+ /**
+ * @param {number} numValues
+ * @return {*}
+ */
+ es3fShaderCommonFunctionTests.RoundCase.prototype.getInputValues = function(numValues) {
+ /** @type {Array<Array<number>>} */ var ranges = [
+ [-2.0, 2.0], // lowp
+ [-1e3, 1e3], // mediump
+ [-1e7, 1e7] // highp
+ ];
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xac23f);
+
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {number} */ var numSpecialCases = 0;
+
+ /** @type {Array<Array<number>>} */ var values = [];
+ values[0] = []
+
+ // Special cases.
+ if (precision === gluShaderUtil.precision.PRECISION_LOWP) {
+ assertMsgOptions(numValues >= 10, 'Sample too small.', false, true);
+ for (var ndx = 0; ndx < 10; ndx++) {
+ /** @type {number} */ var v = deMath.clamp(ndx - 5.5, ranges[precision][0], ranges[precision][1]);
+ for (var iter = 1; iter <= scalarSize; iter++)
+ values[0].push(v);
+ numSpecialCases += 1;
+ }
+ }
+
+ // Random cases.
+ values[0] = values[0].concat(es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], (numValues - numSpecialCases) * scalarSize));
+
+ // If precision is mediump, make sure values can be represented in fp16 exactly
+ if (precision === gluShaderUtil.precision.PRECISION_MEDIUMP)
+ es3fShaderCommonFunctionTests.vecToFloat16(values[0]);
+
+ return values;
+ };
+
+ /**
+ * @param {*} inputs
+ * @param {*} outputs
+ * @return {boolean}
+ */
+ es3fShaderCommonFunctionTests.RoundCase.prototype.compare = function(inputs, outputs) {
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {boolean} */ var hasZeroSign = es3fShaderCommonFunctionTests.supportsSignedZero(precision);
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+
+ /** @type {number} */ var in0;
+ /** @type {number} */ var out0;
+ /** @type {number} */ var ulpDiff;
+
+ if (precision === gluShaderUtil.precision.PRECISION_HIGHP || precision === gluShaderUtil.precision.PRECISION_MEDIUMP) {
+ // Require exact result.
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+
+ if ((in0 - Math.floor(in0)) === 0.5) {
+ /** @type {number} */ var ref0 = Math.floor(in0);
+ /** @type {number} */ var ref1 = Math.ceil(in0);
+ /** @type {number} */ var ulpDiff0 = hasZeroSign ? es3fShaderCommonFunctionTests.getUlpDiff(out0, ref0) : es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref0);
+ /** @type {number} */ var ulpDiff1 = hasZeroSign ? es3fShaderCommonFunctionTests.getUlpDiff(out0, ref1) : es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref1);
+ if (ulpDiff0 > 0 && ulpDiff1 > 0) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref0 + ' or ' + ref1 + ', got ULP diff ' + Math.min(ulpDiff0, ulpDiff1);
+ return false;
+ }
+ } else {
+ // Require exact result
+ /** @type {number} */ var ref = es3fShaderCommonFunctionTests.roundEven(in0);
+ ulpDiff = hasZeroSign ? es3fShaderCommonFunctionTests.getUlpDiff(out0, ref) : es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref);
+
+ if (ulpDiff > 0) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref + ', got ULP diff ' + ulpDiff;
+ return false;
+ }
+ }
+ }
+ } else {
+ /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision);
+ /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits); // ULP diff for rounded integer value.
+ /** @type {number} */ var eps = es3fShaderCommonFunctionTests.getEpsFromBits(1.0, mantissaBits); // epsilon for rounding bounds
+
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ /** @type {number} */ var minRes = Math.floor(es3fShaderCommonFunctionTests.roundEven(in0 - eps));
+ /** @type {number} */ var maxRes = Math.floor(es3fShaderCommonFunctionTests.roundEven(in0 + eps));
+ /** @type {boolean} */ var anyOk = false;
+
+ for (var roundedVal = minRes; roundedVal <= maxRes; roundedVal++) {
+ ulpDiff = es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, roundedVal);
+
+ if (ulpDiff <= maxUlpDiff) {
+ anyOk = true;
+ break;
+ }
+ }
+
+ if (!anyOk) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = [' + minRes + ', ' + maxRes + '] with ULP threshold ' + maxUlpDiff;
+ return false;
+ }
+ }
+ }
+
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase}
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderUtil.precision} precision
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderCommonFunctionTests.CeilCase = function(baseType, precision, shaderType) {
+ es3fShaderCommonFunctionTests.CommonFunctionCase.call(this,
+ es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType),
+ 'ceil', shaderType);
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.source = 'out0 = ceil(in0);';
+ };
+
+ es3fShaderCommonFunctionTests.CeilCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype);
+ es3fShaderCommonFunctionTests.CeilCase.prototype.constructor = es3fShaderCommonFunctionTests.CeilCase;
+
+ /**
+ * @param {number} numValues
+ * @return {*}
+ */
+ es3fShaderCommonFunctionTests.CeilCase.prototype.getInputValues = function(numValues) {
+ /** @type {Array<Array<number>>} */ var ranges = [
+ [-2.0, 2.0], // lowp
+ [-1e3, 1e3], // mediump
+ [-1e7, 1e7] // highp
+ ];
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xac23f);
+
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+
+ /** @type {Array<Array<number>>} */ var values = [];
+
+ // Random cases.
+ values[0] = es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], numValues * scalarSize);
+
+ // If precision is mediump, make sure values can be represented in fp16 exactly
+ if (precision === gluShaderUtil.precision.PRECISION_MEDIUMP)
+ es3fShaderCommonFunctionTests.vecToFloat16(values[0]);
+
+ return values;
+ };
+
+ /**
+ * @param {*} inputs
+ * @param {*} outputs
+ * @return {boolean}
+ */
+ es3fShaderCommonFunctionTests.CeilCase.prototype.compare = function(inputs, outputs) {
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {boolean} */ var hasZeroSign = es3fShaderCommonFunctionTests.supportsSignedZero(precision);
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+
+ /** @type {number} */ var in0;
+ /** @type {number} */ var out0;
+ /** @type {number} */ var ref;
+ /** @type {number} */ var ulpDiff;
+
+ if (precision === gluShaderUtil.precision.PRECISION_HIGHP || precision === gluShaderUtil.precision.PRECISION_MEDIUMP) {
+ // Require exact result.
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ ref = Math.ceil(in0);
+ ulpDiff = hasZeroSign ? es3fShaderCommonFunctionTests.getUlpDiff(out0, ref) : es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref);
+
+ if (ulpDiff > 0) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref + ', got ULP diff ' + ulpDiff;
+ return false;
+ }
+ }
+ } else {
+ /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision);
+ /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(mantissaBits); // ULP diff for rounded integer value.
+ /** @type {number} */ var eps = es3fShaderCommonFunctionTests.getEpsFromBits(1.0, mantissaBits); // epsilon for rounding bounds
+
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ /** @type {number} */ var minRes = Math.ceil(in0 - eps);
+ /** @type {number} */ var maxRes = Math.ceil(in0 + eps);
+ /** @type {boolean} */ var anyOk = false;
+
+ for (var roundedVal = minRes; roundedVal <= maxRes; roundedVal++) {
+ ulpDiff = es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, roundedVal);
+
+ if (ulpDiff <= maxUlpDiff) {
+ anyOk = true;
+ break;
+ }
+ }
+
+ if (!anyOk & deMath.deInRange32(0, minRes, maxRes)) {
+ ulpDiff = Math.abs(Math.floor(tcuFloat.newFloat32(out0).bits()) - 0x80000000);
+ anyOk = ulpDiff <= maxUlpDiff;
+ }
+
+ if (!anyOk) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = [' + minRes + ', ' + maxRes + '] with ULP threshold ' + maxUlpDiff;
+ return false;
+ }
+ }
+ }
+
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderCommonFunctionTests.CommonFunctionCase}
+ * @param {gluShaderUtil.DataType} baseType
+ * @param {gluShaderUtil.precision} precision
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderCommonFunctionTests.FractCase = function(baseType, precision, shaderType) {
+ es3fShaderCommonFunctionTests.CommonFunctionCase.call(this,
+ es3fShaderCommonFunctionTests.getCommonFuncCaseName(baseType, precision, shaderType),
+ 'fract', shaderType);
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(baseType, precision)));
+ this.m_spec.source = 'out0 = fract(in0);';
+ };
+
+ es3fShaderCommonFunctionTests.FractCase.prototype = Object.create(es3fShaderCommonFunctionTests.CommonFunctionCase.prototype);
+ es3fShaderCommonFunctionTests.FractCase.prototype.constructor = es3fShaderCommonFunctionTests.FractCase;
+
+ /**
+ * @param {number} numValues
+ * @return {*}
+ */
+ es3fShaderCommonFunctionTests.FractCase.prototype.getInputValues = function(numValues) {
+ /** @type {Array<Array<number>>} */ var ranges = [
+ [-2.0, 2.0], // lowp
+ [-1e3, 1e3], // mediump
+ [-1e7, 1e7] // highp
+ ];
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xac23f);
+
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {number} */ var numSpecialCases = 0;
+
+ /** @type {Array<Array<number>>} */ var values = [];
+ values[0] = [];
+
+ // Special cases.
+ if (precision !== gluShaderUtil.precision.PRECISION_LOWP) {
+ assertMsgOptions(numValues >= 10, 'Sample too small.', false, true);
+ for (var ndx = 0; ndx < 10; ndx++) {
+ /** @type {number} */ var v = deMath.clamp(ndx - 5.5, ranges[precision][0], ranges[precision][1]);
+ for (var scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++) {
+ values[0].push(v);
+ }
+ numSpecialCases += 1;
+ }
+ }
+
+ // Random cases.
+ values[0] = values[0].concat(es3fShaderCommonFunctionTests.fillRandomScalars(es3fShaderCommonFunctionTests.Types.FLOAT, rnd, ranges[precision][0], ranges[precision][1], (numValues - numSpecialCases) * scalarSize));
+
+ // If precision is mediump, make sure values can be represented in fp16 exactly
+ if (precision === gluShaderUtil.precision.PRECISION_MEDIUMP)
+ es3fShaderCommonFunctionTests.vecToFloat16(values[0])
+
+ return values;
+ };
+
+ /**
+ * @param {*} inputs
+ * @param {*} outputs
+ * @return {boolean}
+ */
+ es3fShaderCommonFunctionTests.FractCase.prototype.compare = function(inputs, outputs) {
+ /** @type {gluShaderUtil.DataType} */ var type = this.m_spec.inputs[0].varType.getBasicType();
+ /** @type {gluShaderUtil.precision} */ var precision = this.m_spec.inputs[0].varType.getPrecision();
+ /** @type {boolean} */ var hasZeroSign = es3fShaderCommonFunctionTests.supportsSignedZero(precision);
+ /** @type {number} */ var scalarSize = gluShaderUtil.getDataTypeScalarSize(type);
+
+ /** @type {number} */ var in0;
+ /** @type {number} */ var out0;
+ /** @type {number} */ var ref;
+ /** @type {number} */ var ulpDiff;
+
+ if (precision === gluShaderUtil.precision.PRECISION_HIGHP || precision === gluShaderUtil.precision.PRECISION_MEDIUMP) {
+ // Require exact result.
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+ ref = in0 - Math.floor(in0);
+ ulpDiff = hasZeroSign ? es3fShaderCommonFunctionTests.getUlpDiff(out0, ref) : es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref);
+
+ if (ulpDiff > 0) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref + ', got ULP diff ' + ulpDiff;
+ return false;
+ }
+ }
+ } else {
+ /** @type {number} */ var mantissaBits = es3fShaderCommonFunctionTests.getMinMantissaBits(precision);
+ /** @type {number} */ var eps = es3fShaderCommonFunctionTests.getEpsFromBits(1.0, mantissaBits); // epsilon for rounding bounds
+
+ for (var compNdx = 0; compNdx < scalarSize; compNdx++) {
+ in0 = inputs[0][compNdx];
+ out0 = outputs[0][compNdx];
+
+ if (Math.floor(in0 - eps) == Math.floor(in0 + eps)) {
+ ref = in0 - Math.floor(in0);
+ /** @type {number} */ var bitsLost = es3fShaderCommonFunctionTests.numBitsLostInOp(in0, ref);
+ /** @type {number} */ var maxUlpDiff = es3fShaderCommonFunctionTests.getMaxUlpDiffFromBits(Math.max(0, mantissaBits - bitsLost)); // ULP diff for rounded integer value.
+ ulpDiff = es3fShaderCommonFunctionTests.getUlpDiffIgnoreZeroSign(out0, ref);
+ if (ulpDiff > maxUlpDiff) {
+ this.m_failMsg += 'Expected [' + compNdx + '] = ' + ref + ' with ULP threshold ' + maxUlpDiff + ', got diff ' + ulpDiff;
+ return false;
+ }
+ } else {
+ if (out0 >= 1.0) {
+ this.m_failMsg += 'Expected [' + compNdx + '] < 1.0';
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderCommonFunctionTests.ShaderCommonFunctionTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'common', 'Common function tests');
+ };
+
+ es3fShaderCommonFunctionTests.ShaderCommonFunctionTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderCommonFunctionTests.ShaderCommonFunctionTests.prototype.constructor = es3fShaderCommonFunctionTests.ShaderCommonFunctionTests;
+
+ /**
+ * @param {tcuTestCase.DeqpTest} parent
+ * @param {es3fShaderCommonFunctionTests.TestClass} testClass
+ * @param {string} functionName
+ * @param {boolean} floatTypes
+ * @param {boolean} intTypes
+ * @param {boolean} uintTypes
+ */
+ es3fShaderCommonFunctionTests.addFunctionCases = function(parent, testClass, functionName, floatTypes, intTypes, uintTypes) {
+ /** @type {tcuTestCase.DeqpTest} */ var group = tcuTestCase.newTest(functionName, functionName);
+ parent.addChild(group);
+
+ /** @type {Array<gluShaderUtil.DataType>} */ var scalarTypes = [
+ gluShaderUtil.DataType.FLOAT,
+ gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.UINT
+ ];
+
+ for (var scalarTypeNdx = 0; scalarTypeNdx < scalarTypes.length; scalarTypeNdx++) {
+ /** @type {gluShaderUtil.DataType} */ var scalarType = scalarTypes[scalarTypeNdx];
+
+ if ((!floatTypes && scalarType == gluShaderUtil.DataType.FLOAT) ||
+ (!intTypes && scalarType == gluShaderUtil.DataType.INT) ||
+ (!uintTypes && scalarType == gluShaderUtil.DataType.UINT))
+ continue;
+
+ for (var vecSize = 1; vecSize <= 4; vecSize++)
+ for (var prec = gluShaderUtil.precision.PRECISION_LOWP; prec <= gluShaderUtil.precision.PRECISION_HIGHP; prec++)
+ for (var shaderType = gluShaderProgram.shaderType.VERTEX; shaderType <= gluShaderProgram.shaderType.FRAGMENT; shaderType++)
+ group.addChild(new testClass(/** @type {gluShaderUtil.DataType} */ (scalarType + vecSize - 1), prec, shaderType));
+ }
+ };
+
+ es3fShaderCommonFunctionTests.ShaderCommonFunctionTests.prototype.init = function() {
+ var testGroup = tcuTestCase.runner.testCases;
+
+ es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.AbsCase, 'abs', true, true, false);
+ es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.SignCase, 'sign', true, true, false);
+ es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.FloorCase, 'floor', true, false, false);
+ es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.TruncCase, 'trunc', true, false, false);
+ es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.RoundCase, 'round', true, false, false);
+ es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.RoundEvenCase, 'roundeven', true, false, false);
+ es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.CeilCase, 'ceil', true, false, false);
+ es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.FractCase, 'fract', true, false, false);
+ // mod
+ es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.ModfCase, 'modf', true, false, false);
+ // min, max, clamp, mix, step, smoothstep
+ es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.IsnanCase, 'isnan', true, false, false);
+ es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.IsinfCase, 'isinf', true, false, false);
+ es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.FloatBitsToIntCase, 'floatbitstoint', true, false, false);
+ es3fShaderCommonFunctionTests.addFunctionCases(testGroup, es3fShaderCommonFunctionTests.FloatBitsToUintCase, 'floatbitstouint', true, false, false);
+
+ // (u)intBitsToFloat()
+ /** @type {tcuTestCase.DeqpTest} */ var intGroup = tcuTestCase.newTest('intbitstofloat', 'intBitsToFloat() Tests');
+ /** @type {tcuTestCase.DeqpTest} */ var uintGroup = tcuTestCase.newTest('uintbitstofloat', 'uintBitsToFloat() Tests');
+
+ testGroup.addChild(intGroup);
+ testGroup.addChild(uintGroup);
+
+ /** @type {Array<gluShaderProgram.shaderType>} */ var shaderTypes = [
+ gluShaderProgram.shaderType.VERTEX,
+ gluShaderProgram.shaderType.FRAGMENT
+ ];
+
+ for (var vecSize = 1; vecSize < 4; vecSize++) {
+ /** @type {gluShaderUtil.DataType} */ var intType = vecSize > 1 ?
+ gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.INT, vecSize) :
+ gluShaderUtil.DataType.INT;
+
+ /** @type {gluShaderUtil.DataType} */ var uintType = vecSize > 1 ?
+ gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.UINT, vecSize) :
+ gluShaderUtil.DataType.UINT;
+
+ for (var shaderType in shaderTypes) {
+ intGroup.addChild(new es3fShaderCommonFunctionTests.BitsToFloatCase(intType, shaderTypes[shaderType]));
+ uintGroup.addChild(new es3fShaderCommonFunctionTests.BitsToFloatCase(uintType, shaderTypes[shaderType]));
+ }
+ }
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fShaderCommonFunctionTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fShaderCommonFunctionTests.ShaderCommonFunctionTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fShaderCommonFunctionTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderDerivateTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderDerivateTests.js
new file mode 100644
index 0000000000..9c859c296f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderDerivateTests.js
@@ -0,0 +1,1696 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fShaderDerivateTests');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluDrawUtil');
+goog.require('framework.opengl.gluPixelTransfer');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTexture');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('framework.common.tcuInterval');
+goog.require('framework.common.tcuFloat');
+goog.require('framework.common.tcuLogImage');
+goog.require('framework.common.tcuMatrix');
+goog.require('framework.common.tcuPixelFormat');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuStringTemplate');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.common.tcuTestCase');
+goog.require('modules.shared.glsShaderRenderCase');
+
+goog.scope(function() {
+ var es3fShaderDerivateTests = functional.gles3.es3fShaderDerivateTests;
+ var deMath = framework.delibs.debase.deMath;
+ var deRandom = framework.delibs.debase.deRandom;
+ var deString = framework.delibs.debase.deString;
+ var gluDrawUtil = framework.opengl.gluDrawUtil;
+ var gluPixelTransfer = framework.opengl.gluPixelTransfer;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluTexture = framework.opengl.gluTexture;
+ var gluTextureUtil = framework.opengl.gluTextureUtil;
+ var tcuInterval = framework.common.tcuInterval;
+ var tcuFloat = framework.common.tcuFloat;
+ var tcuLogImage = framework.common.tcuLogImage;
+ var tcuMatrix = framework.common.tcuMatrix;
+ var tcuPixelFormat = framework.common.tcuPixelFormat;
+ var tcuRGBA = framework.common.tcuRGBA;
+ var tcuStringTemplate = framework.common.tcuStringTemplate;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuTexture = framework.common.tcuTexture;
+ var tcuTextureUtil = framework.common.tcuTextureUtil;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
+
+ /** @const {number} */ es3fShaderDerivateTests.VIEWPORT_WIDTH = 167;
+ /** @const {number} */ es3fShaderDerivateTests.VIEWPORT_HEIGHT = 103;
+ /** @const {number} */ es3fShaderDerivateTests.FBO_WIDTH = 99;
+ /** @const {number} */ es3fShaderDerivateTests.FBO_HEIGHT = 133;
+ /** @const {number} */ es3fShaderDerivateTests.MAX_FAILED_MESSAGES = 10;
+ /** @const {number} */ es3fShaderDerivateTests.INTERPOLATION_LOST_BITS = 3; // number mantissa of bits allowed to be lost in varying interpolation
+ /**
+ * @enum {number}
+ */
+ es3fShaderDerivateTests.DerivateFunc = {
+ DFDX: 0,
+ DFDY: 1,
+ FWIDTH: 2
+ };
+
+ /**
+ * @enum {number}
+ */
+ es3fShaderDerivateTests.SurfaceType = {
+ DEFAULT_FRAMEBUFFER: 0,
+ UNORM_FBO: 1,
+ FLOAT_FBO: 2 // \note Uses RGBA32UI fbo actually, since FP rendertargets are not in core spec.
+ };
+
+ /**
+ * @enum {number}
+ */
+ es3fShaderDerivateTests.VerificationLogging = {
+ LOG_ALL: 0,
+ LOG_NOTHING: 1
+ };
+
+ /**
+ * @param {es3fShaderDerivateTests.DerivateFunc} func
+ * @return {string}
+ */
+ es3fShaderDerivateTests.getDerivateFuncName = function(func) {
+ switch (func) {
+ case es3fShaderDerivateTests.DerivateFunc.DFDX: return 'dFdx';
+ case es3fShaderDerivateTests.DerivateFunc.DFDY: return 'dFdy';
+ case es3fShaderDerivateTests.DerivateFunc.FWIDTH: return 'fwidth';
+ default: throw new Error('Derivate Func not supported.');
+ }
+ };
+
+ /**
+ * @param {es3fShaderDerivateTests.DerivateFunc} func
+ * @return {string}
+ */
+ es3fShaderDerivateTests.getDerivateFuncCaseName = function(func) {
+ switch (func) {
+ case es3fShaderDerivateTests.DerivateFunc.DFDX: return 'dfdx';
+ case es3fShaderDerivateTests.DerivateFunc.DFDY: return 'dfdy';
+ case es3fShaderDerivateTests.DerivateFunc.FWIDTH: return 'fwidth';
+ default: throw new Error('Derivate Func not supported.');
+ }
+ };
+
+ /**
+ * @param {?gluShaderUtil.DataType} type
+ * @return {Array<boolean>}
+ */
+ es3fShaderDerivateTests.getDerivateMask = function(type) {
+ switch (type) {
+ case gluShaderUtil.DataType.FLOAT: return [true, false, false, false];
+ case gluShaderUtil.DataType.FLOAT_VEC2: return [true, true, false, false];
+ case gluShaderUtil.DataType.FLOAT_VEC3: return [true, true, true, false];
+ case gluShaderUtil.DataType.FLOAT_VEC4: return [true, true, true, true];
+ default: throw new Error('Data Type not supported.');
+ }
+ };
+
+ /**
+ * @param {tcuTexture.ConstPixelBufferAccess} surface
+ * @param {Array<number>} derivScale
+ * @param {Array<number>} derivBias
+ * @param {number} x
+ * @param {number} y
+ * @return {Array<number>}
+ */
+ es3fShaderDerivateTests.readDerivate = function(surface, derivScale, derivBias, x, y) {
+ return deMath.divide(deMath.subtract(surface.getPixel(x, y), derivBias), derivScale);
+ };
+
+ /**
+ * @param {Array<number>} v
+ * @return {Array<number>}
+ */
+ es3fShaderDerivateTests.getCompExpBits = function(v) {
+ return [tcuFloat.newFloat32(v[0]).exponentBits(),
+ tcuFloat.newFloat32(v[1]).exponentBits(),
+ tcuFloat.newFloat32(v[2]).exponentBits(),
+ tcuFloat.newFloat32(v[3]).exponentBits()];
+ };
+
+ /**
+ * @param {number} value
+ * @param {number} numAccurateBits
+ * @return {number}
+ */
+ es3fShaderDerivateTests.computeFloatingPointError = function(value, numAccurateBits) {
+ /** @type {number} */ var numGarbageBits = 23 - numAccurateBits;
+ /** @type {number} */ var mask = (1 << numGarbageBits) - 1 ;
+ /** @type {number} */ var exp = tcuFloat.newFloat32(value).exponent();
+
+ return (new tcuFloat.deFloat()).construct(1, exp, (1 << 23) | mask).getValue() - (new tcuFloat.deFloat()).construct(1, exp, 1 << 23).getValue();
+ };
+
+ /**
+ * @param {?gluShaderUtil.precision} precision
+ * @return {number}
+ */
+ es3fShaderDerivateTests.getNumMantissaBits = function(precision) {
+ switch (precision) {
+ case gluShaderUtil.precision.PRECISION_HIGHP: return 23;
+ case gluShaderUtil.precision.PRECISION_MEDIUMP: return 10;
+ case gluShaderUtil.precision.PRECISION_LOWP: return 6;
+ default:
+ throw new Error('Precision not supported: ' + precision);
+ }
+ };
+
+ /**
+ * @param {?gluShaderUtil.precision} precision
+ * @return {number}
+ */
+ es3fShaderDerivateTests.getMinExponent = function(precision) {
+ switch (precision) {
+ case gluShaderUtil.precision.PRECISION_HIGHP: return -126;
+ case gluShaderUtil.precision.PRECISION_MEDIUMP: return -14;
+ case gluShaderUtil.precision.PRECISION_LOWP: return -8;
+ default:
+ throw new Error('Precision not supported: ' + precision);
+ }
+ };
+
+ /**
+ * @param {number} exp
+ * @param {number} numMantissaBits
+ * @return {number}
+ */
+ es3fShaderDerivateTests.getSingleULPForExponent = function(exp, numMantissaBits) {
+ if (numMantissaBits > 0) {
+ assertMsgOptions(numMantissaBits <= 23, 'numMantissaBits must be less or equal than 23.', false, true);
+
+ /** @type {number} */ var ulpBitNdx = 23 - numMantissaBits;
+
+ return (new tcuFloat.deFloat()).construct(1, exp, (1 << 23) | (1 << ulpBitNdx)).getValue() - (new tcuFloat.deFloat()).construct(1, exp, 1 << 23).getValue();
+ } else {
+ assertMsgOptions(numMantissaBits === 0, 'numMantissaBits must equal to 0.', false, true);
+ return (new tcuFloat.deFloat()).construct(1, exp, (1 << 23)).getValue()
+ }
+ };
+
+ /**
+ * @param {number} value
+ * @param {number} numMantissaBits
+ * @return {number}
+ */
+ es3fShaderDerivateTests.getSingleULPForValue = function(value, numMantissaBits) {
+ /** @type {number} */ var exp = (new tcuFloat.deFloat().deFloatNumber(value)).exponent();
+ return es3fShaderDerivateTests.getSingleULPForExponent(exp, numMantissaBits);
+ };
+
+ /**
+ * @param {number} value
+ * @param {number} minExponent
+ * @param {number} numAccurateBits
+ * @return {number}
+ */
+ es3fShaderDerivateTests.convertFloorFlushToZero = function(value, minExponent, numAccurateBits) {
+ if (value === 0.0) {
+ return 0.0;
+ } else {
+ /** @type {tcuFloat.deFloat} */ var inputFloat = new tcuFloat.deFloat().deFloatNumber(value);
+ /** @type {number} */ var numTruncatedBits = 23 - numAccurateBits;
+ /** @type {number} */ var truncMask = (1 << numTruncatedBits) - 1;
+
+ if (value > 0.0) {
+ if (value > 0.0 && (new tcuFloat.deFloat().deFloatNumber(value)).exponent() < minExponent) {
+ // flush to zero if possible
+ return 0.0;
+ } else {
+ // just mask away non-representable bits
+ return (new tcuFloat.deFloat()).construct(1, inputFloat.exponent(), inputFloat.mantissa() & ~truncMask).getValue();
+ }
+ } else {
+ if (inputFloat.mantissa() & truncMask) {
+ // decrement one ulp if truncated bits are non-zero (i.e. if value is not representable)
+ return (new tcuFloat.deFloat()).construct(-1, inputFloat.exponent(), inputFloat.mantissa() & ~truncMask).getValue() - es3fShaderDerivateTests.getSingleULPForExponent(inputFloat.exponent(), numAccurateBits);
+ } else {
+ // value is representable, no need to do anything
+ return value;
+ }
+ }
+ }
+ };
+
+ /**
+ * @param {number} value
+ * @param {number} minExponent
+ * @param {number} numAccurateBits
+ * @return {number}
+ */
+ es3fShaderDerivateTests.convertCeilFlushToZero = function(value, minExponent, numAccurateBits) {
+ return -es3fShaderDerivateTests.convertFloorFlushToZero(-value, minExponent, numAccurateBits);
+ };
+
+ /**
+ * @param {number} value
+ * @param {number} numUlps
+ * @param {number} numMantissaBits
+ * @return {number}
+ */
+ es3fShaderDerivateTests.addErrorUlp = function(value, numUlps, numMantissaBits) {
+ return value + numUlps * es3fShaderDerivateTests.getSingleULPForValue(value, numMantissaBits);
+ };
+
+ /**
+ * @param {?gluShaderUtil.precision} precision
+ * @param {Array<number>} valueMin
+ * @param {Array<number>} valueMax
+ * @param {Array<number>} expectedDerivate
+ * @return {Array<number>}
+ */
+ es3fShaderDerivateTests.getDerivateThreshold = function(precision, valueMin, valueMax, expectedDerivate) {
+ /** @type {number} */ var baseBits = es3fShaderDerivateTests.getNumMantissaBits(precision);
+ /** @type {Array<number>} */ var derivExp = es3fShaderDerivateTests.getCompExpBits(expectedDerivate);
+ /** @type {Array<number>} */ var maxValueExp = deMath.max(es3fShaderDerivateTests.getCompExpBits(valueMin), es3fShaderDerivateTests.getCompExpBits(valueMax));
+ /** @type {Array<number>} */ var numBitsLost = deMath.subtract(maxValueExp, deMath.min(maxValueExp, derivExp));
+ /** @type {Array<number>} */
+ var numAccurateBits = deMath.max(
+ deMath.addScalar(
+ deMath.subtract(
+ [baseBits, baseBits, baseBits, baseBits],
+ numBitsLost),
+ -es3fShaderDerivateTests.INTERPOLATION_LOST_BITS),
+ [0, 0, 0, 0]);
+
+ return [es3fShaderDerivateTests.computeFloatingPointError(expectedDerivate[0], numAccurateBits[0]),
+ es3fShaderDerivateTests.computeFloatingPointError(expectedDerivate[1], numAccurateBits[1]),
+ es3fShaderDerivateTests.computeFloatingPointError(expectedDerivate[2], numAccurateBits[2]),
+ es3fShaderDerivateTests.computeFloatingPointError(expectedDerivate[3], numAccurateBits[3])];
+ };
+
+ /**
+ * @param {tcuTexture.ConstPixelBufferAccess} result
+ * @param {tcuTexture.PixelBufferAccess} errorMask
+ * @param {?gluShaderUtil.DataType} dataType
+ * @param {Array<number>} reference
+ * @param {Array<number>} threshold
+ * @param {Array<number>} scale
+ * @param {Array<number>} bias
+ * @param {es3fShaderDerivateTests.VerificationLogging=} logPolicy
+ * @return {boolean}
+ */
+ es3fShaderDerivateTests.verifyConstantDerivate = function(result, errorMask, dataType, reference, threshold, scale, bias, logPolicy) {
+ logPolicy = logPolicy === undefined ? es3fShaderDerivateTests.VerificationLogging.LOG_ALL : logPolicy;
+ /** @type {Array<boolean>} */ var mask = deMath.logicalNotBool(es3fShaderDerivateTests.getDerivateMask(dataType));
+ /** @type {number} */ var numFailedPixels = 0;
+
+ if (logPolicy === es3fShaderDerivateTests.VerificationLogging.LOG_ALL)
+ bufferedLogToConsole('Expecting ' + reference + ' with threshold ' + threshold);
+
+ for (var y = 0; y < result.getHeight(); y++) {
+ for (var x = 0; x < result.getWidth(); x++) {
+ /** @type {Array<number>} */ var resDerivate = es3fShaderDerivateTests.readDerivate(result, scale, bias, x, y);
+ /** @type {boolean} */
+ var isOk = deMath.boolAll(
+ deMath.logicalOrBool(
+ deMath.lessThanEqual(
+ deMath.abs(deMath.subtract(reference, resDerivate)),
+ threshold),
+ mask));
+
+ if (!isOk) {
+ if (numFailedPixels < es3fShaderDerivateTests.MAX_FAILED_MESSAGES && logPolicy === es3fShaderDerivateTests.VerificationLogging.LOG_ALL)
+ bufferedLogToConsole('FAIL: got ' + resDerivate + ', diff = ' + deMath.abs(deMath.subtract(reference, resDerivate)) + ', at x = ' + x + ', y = ' + y);
+ numFailedPixels += 1;
+ errorMask.setPixel(tcuRGBA.RGBA.red.toVec(), x, y);
+ }
+ }
+ }
+
+ if (numFailedPixels >= es3fShaderDerivateTests.MAX_FAILED_MESSAGES && logPolicy === es3fShaderDerivateTests.VerificationLogging.LOG_ALL)
+ bufferedLogToConsole('...');
+
+ if (numFailedPixels > 0 && logPolicy === es3fShaderDerivateTests.VerificationLogging.LOG_ALL)
+ bufferedLogToConsole('FAIL: found ' + numFailedPixels + ' failed pixels');
+
+ return numFailedPixels === 0;
+ };
+
+ /**
+ * .-----.
+ * | s_x |
+ * M x | s_y |
+ * | 1.0 |
+ * '-----'
+ * @struct
+ * @constructor
+ */
+ es3fShaderDerivateTests.Linear2DFunctionEvaluator = function() {
+ /** @type {tcuMatrix.Matrix} */ this.matrix = new tcuMatrix.Matrix(4, 3);
+ };
+
+ es3fShaderDerivateTests.Linear2DFunctionEvaluator.prototype.evaluateAt = function(screenX, screenY) {
+ /** @type {Array<number>} */ var position = [screenX, screenY, 1.0];
+ return tcuMatrix.multiplyMatVec(this.matrix, position);
+ };
+
+ /**
+ * @param {tcuTexture.ConstPixelBufferAccess} result
+ * @param {tcuTexture.PixelBufferAccess} errorMask
+ * @param {?gluShaderUtil.DataType} dataType
+ * @param {?gluShaderUtil.precision} precision
+ * @param {Array<number>} derivScale
+ * @param {Array<number>} derivBias
+ * @param {Array<number>} surfaceThreshold
+ * @param {es3fShaderDerivateTests.DerivateFunc} derivateFunc
+ * @param {es3fShaderDerivateTests.Linear2DFunctionEvaluator} func
+ * @return {boolean}
+ */
+ es3fShaderDerivateTests.reverifyConstantDerivateWithFlushRelaxations = function(result, errorMask, dataType, precision, derivScale, derivBias, surfaceThreshold, derivateFunc, func) {
+ assertMsgOptions(result.getWidth() === errorMask.getWidth(), 'Dimensions of result and errorMask inconsistent.', false, true);
+ assertMsgOptions(result.getHeight() === errorMask.getHeight(), 'Dimensions of result and errorMask inconsistent.', false, true);
+ assertMsgOptions(derivateFunc === es3fShaderDerivateTests.DerivateFunc.DFDX || derivateFunc === es3fShaderDerivateTests.DerivateFunc.DFDY, 'Derivate Function should be DFDX or DFDY.', false, true);
+
+ /** @type {Array<number>} */ var red = [255, 0, 0, 255];
+ /** @type {Array<number>} */ var green = [0, 255, 0, 255];
+ /** @type {number} */ var divisionErrorUlps = 2.5;
+
+ /** @type {number} */ var numComponents = gluShaderUtil.getDataTypeScalarTypeAsDataType(dataType);
+ /** @type {number} */ var numBits = es3fShaderDerivateTests.getNumMantissaBits(precision);
+ /** @type {number} */ var minExponent = es3fShaderDerivateTests.getMinExponent(precision);
+
+ /** @type {number} */ var numVaryingSampleBits = numBits - es3fShaderDerivateTests.INTERPOLATION_LOST_BITS;
+ /** @type {number} */ var numFailedPixels = 0;
+
+ errorMask.clear(green);
+
+ // search for failed pixels
+ for (var y = 0; y < result.getHeight(); ++y)
+ for (var x = 0; x < result.getWidth(); ++x) {
+ // flushToZero?(f2z?(functionValueCurrent) - f2z?(functionValueBefore))
+ // flushToZero? ( ------------------------------------------------------------------------ +- 2.5 ULP )
+ // dx
+
+ /** @type {Array<number>} */ var resultDerivative = es3fShaderDerivateTests.readDerivate(result, derivScale, derivBias, x, y);
+
+ // sample at the front of the back pixel and the back of the front pixel to cover the whole area of
+ // legal sample positions. In general case this is NOT OK, but we know that the target funtion is
+ // (mostly*) linear which allows us to take the sample points at arbitrary points. This gets us the
+ // maximum difference possible in exponents which are used in error bound calculations.
+ // * non-linearity may happen around zero or with very high function values due to subnorms not
+ // behaving well.
+ /** @type {Array<number>} */ var functionValueForward = (derivateFunc === es3fShaderDerivateTests.DerivateFunc.DFDX) ?
+ (func.evaluateAt(x + 2.0, y + 0.5)) :
+ (func.evaluateAt(x + 0.5, y + 2.0));
+ /** @type {Array<number>} */ var functionValueBackward = (derivateFunc === es3fShaderDerivateTests.DerivateFunc.DFDX) ?
+ (func.evaluateAt(x - 1.0, y + 0.5)) :
+ (func.evaluateAt(x + 0.5, y - 1.0));
+
+ /** @type {boolean} */ var anyComponentFailed = false;
+
+ // check components separately
+ for (var c = 0; c < numComponents; ++c) {
+ // interpolation value range
+ /** @type {tcuInterval.Interval} */ var forwardComponent = tcuInterval.withIntervals(
+ new tcuInterval.Interval(es3fShaderDerivateTests.convertFloorFlushToZero(
+ es3fShaderDerivateTests.addErrorUlp(functionValueForward[c], -0.5, numVaryingSampleBits), minExponent, numBits)),
+ new tcuInterval.Interval(es3fShaderDerivateTests.convertCeilFlushToZero(
+ es3fShaderDerivateTests.addErrorUlp(functionValueForward[c], +0.5, numVaryingSampleBits), minExponent, numBits))
+ );
+
+ /** @type {tcuInterval.Interval} */ var backwardComponent = tcuInterval.withIntervals(
+ new tcuInterval.Interval(es3fShaderDerivateTests.convertFloorFlushToZero(
+ es3fShaderDerivateTests.addErrorUlp(functionValueBackward[c], -0.5, numVaryingSampleBits), minExponent, numBits)),
+ new tcuInterval.Interval(es3fShaderDerivateTests.convertCeilFlushToZero(
+ es3fShaderDerivateTests.addErrorUlp(functionValueBackward[c], +0.5, numVaryingSampleBits), minExponent, numBits))
+ );
+
+ /** @type {number} */
+ var maxValueExp = Math.max(
+ (new tcuFloat.deFloat().deFloatNumber(forwardComponent.lo())).exponent(),
+ (new tcuFloat.deFloat().deFloatNumber(forwardComponent.hi())).exponent(),
+ (new tcuFloat.deFloat().deFloatNumber(backwardComponent.lo())).exponent(),
+ (new tcuFloat.deFloat().deFloatNumber(backwardComponent.hi())).exponent());
+
+ // subtraction in nominator will likely cause a cancellation of the most
+ // significant bits. Apply error bounds.
+ /** @type {tcuInterval.Interval} */ var nominator = tcuInterval.Interval.operatorSub(forwardComponent, backwardComponent);
+ /** @type {number} */ var nominatorLoExp = (new tcuFloat.deFloat().deFloatNumber(nominator.lo())).exponent();
+ /** @type {number} */ var nominatorHiExp = (new tcuFloat.deFloat().deFloatNumber(nominator.hi())).exponent();
+ /** @type {number} */ var nominatorLoBitsLost = maxValueExp - nominatorLoExp;
+ /** @type {number} */ var nominatorHiBitsLost = maxValueExp - nominatorHiExp;
+ /** @type {number} */ var nominatorLoBits = Math.max(0, numBits - nominatorLoBitsLost);
+ /** @type {number} */ var nominatorHiBits = Math.max(0, numBits - nominatorHiBitsLost);
+
+ /** @type {tcuInterval.Interval} */ var nominatorRange = tcuInterval.withIntervals(
+ new tcuInterval.Interval(es3fShaderDerivateTests.convertFloorFlushToZero(nominator.lo(), minExponent, nominatorLoBits)),
+ new tcuInterval.Interval(es3fShaderDerivateTests.convertCeilFlushToZero(nominator.hi(), minExponent, nominatorHiBits)));
+ //
+ /** @type {tcuInterval.Interval} */ var divisionRange = tcuInterval.Interval.operatorDiv(nominatorRange, new tcuInterval.Interval(3.0)); // legal sample area is anywhere within this and neighboring pixels (i.e. size = 3)
+ /** @type {tcuInterval.Interval} */ var divisionResultRange = tcuInterval.withIntervals(
+ new tcuInterval.Interval(es3fShaderDerivateTests.convertFloorFlushToZero(es3fShaderDerivateTests.addErrorUlp(divisionRange.lo(), -divisionErrorUlps, numBits), minExponent, numBits)),
+ new tcuInterval.Interval(es3fShaderDerivateTests.convertCeilFlushToZero(es3fShaderDerivateTests.addErrorUlp(divisionRange.hi(), divisionErrorUlps, numBits), minExponent, numBits)));
+ /** @type {tcuInterval.Interval} */ var finalResultRange = tcuInterval.withIntervals(
+ new tcuInterval.Interval(divisionResultRange.lo() - surfaceThreshold[c]),
+ new tcuInterval.Interval(divisionResultRange.hi() + surfaceThreshold[c]));
+
+ if (resultDerivative[c] >= finalResultRange.lo() && resultDerivative[c] <= finalResultRange.hi()) {
+ // value ok
+ } else {
+ if (numFailedPixels < es3fShaderDerivateTests.MAX_FAILED_MESSAGES)
+ bufferedLogToConsole('Error in pixel at ' + x + ', ' + y + ' with component ' + c + ' (channel ' + ('rgba'[c]) + ')\n' +
+ '\tGot pixel value ' + result.getPixelInt(x, y) + '\n' +
+ '\t\tdFd' + ((derivateFunc === es3fShaderDerivateTests.DerivateFunc.DFDX) ? 'x' : 'y') + ' ~= ' + resultDerivative[c] + '\n' +
+ '\t\tdifference to a valid range: ' +
+ ((resultDerivative[c] < finalResultRange.lo()) ? '-' : '+') +
+ ((resultDerivative[c] < finalResultRange.lo()) ? (finalResultRange.lo() - resultDerivative[c]) : (resultDerivative[c] - finalResultRange.hi())) +
+ '\n' +
+ '\tDerivative value range:\n' +
+ '\t\tMin: ' + finalResultRange.lo() + '\n' +
+ '\t\tMax: ' + finalResultRange.hi() + '\n');
+
+ ++numFailedPixels;
+ anyComponentFailed = true;
+ }
+ }
+
+ if (anyComponentFailed)
+ errorMask.setPixel(red, x, y);
+ }
+
+ if (numFailedPixels >= es3fShaderDerivateTests.MAX_FAILED_MESSAGES)
+ bufferedLogToConsole('...');
+
+ if (numFailedPixels > 0)
+ bufferedLogToConsole('FAIL: found ' + numFailedPixels + ' failed pixels');
+
+ return numFailedPixels === 0;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ */
+ es3fShaderDerivateTests.TriangleDerivateCase = function(name, description) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ /** @type {?gluShaderUtil.DataType} */ this.m_dataType = null;
+ /** @type {?gluShaderUtil.precision} */ this.m_precision = null;
+
+ /** @type {?gluShaderUtil.DataType} */ this.m_coordDataType = null;
+ /** @type {?gluShaderUtil.precision} */ this.m_coordPrecision = null;
+
+ /** @type {string} */ this.m_fragmentSrc;
+
+ /** @type {Array<number>} */ this.m_coordMin = [];
+ /** @type {Array<number>} */ this.m_coordMax = [];
+ /** @type {Array<number>} */ this.m_derivScale = [];
+ /** @type {Array<number>} */ this.m_derivBias = [];
+
+ /** @type {es3fShaderDerivateTests.SurfaceType} */ this.m_surfaceType = es3fShaderDerivateTests.SurfaceType.DEFAULT_FRAMEBUFFER;
+ /** @type {number} */ this.m_numSamples = 0;
+ /** @type {number} */ this.m_hint = gl.DONT_CARE;
+
+ assertMsgOptions(this.m_surfaceType !== es3fShaderDerivateTests.SurfaceType.DEFAULT_FRAMEBUFFER || this.m_numSamples === 0, 'Did not expect surfaceType = DEFAULT_FRAMEBUFFER or numSamples = 0', false, true);
+ };
+
+ es3fShaderDerivateTests.TriangleDerivateCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderDerivateTests.TriangleDerivateCase.prototype.constructor = es3fShaderDerivateTests.TriangleDerivateCase;
+
+ es3fShaderDerivateTests.TriangleDerivateCase.prototype.deinit = function() {};
+
+ /** @param {WebGLProgram} program */
+ es3fShaderDerivateTests.TriangleDerivateCase.prototype.setupRenderState = function(program) {};
+
+ /**
+ * @param {?gluShaderUtil.DataType} coordType
+ * @param {?gluShaderUtil.precision} precision
+ * @return {string}
+ */
+ es3fShaderDerivateTests.genVertexSource = function(coordType, precision) {
+ assertMsgOptions(gluShaderUtil.isDataTypeFloatOrVec(coordType), 'Coord Type not supported', false, true);
+
+ /** @type {string} */ var vertexTmpl = '' +
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in ${PRECISION} ${DATATYPE} a_coord;\n' +
+ 'out ${PRECISION} ${DATATYPE} v_coord;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ ' v_coord = a_coord;\n' +
+ '}\n';
+
+ /** @type {Object} */ var vertexParams = {};
+
+ vertexParams['PRECISION'] = gluShaderUtil.getPrecisionName(precision);
+ vertexParams['DATATYPE'] = gluShaderUtil.getDataTypeName(coordType);
+
+ return tcuStringTemplate.specialize(vertexTmpl, vertexParams);
+ };
+
+ /**
+ * @return {Array<number>}
+ */
+ es3fShaderDerivateTests.TriangleDerivateCase.prototype.getViewportSize = function() {
+ if (this.m_surfaceType === es3fShaderDerivateTests.SurfaceType.DEFAULT_FRAMEBUFFER) {
+ /** @type {number} */ var width = Math.min(gl.drawingBufferWidth, es3fShaderDerivateTests.VIEWPORT_WIDTH);
+ /** @type {number} */ var height = Math.min(gl.drawingBufferHeight, es3fShaderDerivateTests.VIEWPORT_HEIGHT);
+ return [width, height];
+ } else
+ return [es3fShaderDerivateTests.FBO_WIDTH, es3fShaderDerivateTests.FBO_HEIGHT];
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderDerivateTests.TriangleDerivateCase.prototype.iterate = function() {
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(es3fShaderDerivateTests.genVertexSource(this.m_coordDataType, this.m_coordPrecision), this.m_fragmentSrc));
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0xbbc24);
+ /** @type {boolean} */ var useFbo = this.m_surfaceType != es3fShaderDerivateTests.SurfaceType.DEFAULT_FRAMEBUFFER;
+ /** @type {number} */ var fboFormat = this.m_surfaceType === es3fShaderDerivateTests.SurfaceType.FLOAT_FBO ? gl.RGBA32UI : gl.RGBA8;
+ /** @type {Array<number>} */ var viewportSize = this.getViewportSize();
+ /** @type {number} */ var viewportX = useFbo ? 0 : rnd.getInt(0, gl.drawingBufferWidth - viewportSize[0]);
+ /** @type {number} */ var viewportY = useFbo ? 0 : rnd.getInt(0, gl.drawingBufferHeight - viewportSize[1]);
+ /** @type {?WebGLFramebuffer} */ var fbo = null;
+ /** @type {?WebGLRenderbuffer} */ var rbo = null;
+ /** @type {tcuTexture.TextureLevel} */ var result = null;
+
+ bufferedLogToConsole(program.getProgramInfo().infoLog);
+
+ if (!program.isOk())
+ assertMsgOptions(false, 'Compile failed', false, true);
+
+ if (useFbo) {
+ bufferedLogToConsole('Rendering to FBO, format = ' + wtu.glEnumToString(gl, fboFormat) + ', samples = ' + this.m_numSamples);
+
+ fbo = gl.createFramebuffer();
+ rbo = gl.createRenderbuffer();
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, this.m_numSamples, fboFormat, viewportSize[0], viewportSize[1]);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
+ } else {
+ /** @type {tcuPixelFormat.PixelFormat} */ var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
+
+ bufferedLogToConsole('Rendering to default framebuffer\n' +
+ '\tColor depth: R=' + pixelFormat.redBits + ', G=' + pixelFormat.greenBits + ', B=' + pixelFormat.blueBits + ', A=' + pixelFormat.alphaBits);
+ }
+
+ bufferedLogToConsole('in: ' + this.m_coordMin + ' ' + this.m_coordMax + '\n' +
+ 'v_coord.x = in.x * x\n' +
+ 'v_coord.y = in.y * y\n' +
+ 'v_coord.z = in.z * (x+y)/2\n' +
+ 'v_coord.w = in.w * (1 - (x+y)/2)\n' +
+ '\n' +
+ 'u_scale: ' + this.m_derivScale + ', u_bias: ' + this.m_derivBias + ' (displayed values have scale/bias removed)' +
+ 'Viewport: ' + viewportSize[0] + 'x' + viewportSize[1] +
+ 'gl.FRAGMENT_SHADER_DERIVATE_HINT: ' + wtu.glEnumToString(gl, this.m_hint));
+ // Draw
+ /** @type {Array<number>} */ var positions = [
+ -1.0, -1.0, 0.0, 1.0,
+ -1.0, 1.0, 0.0, 1.0,
+ 1.0, -1.0, 0.0, 1.0,
+ 1.0, 1.0, 0.0, 1.0
+ ];
+
+ /** @type {Array<number>} */ var coords =[
+ this.m_coordMin[0], this.m_coordMin[1], this.m_coordMin[2], this.m_coordMax[3],
+ this.m_coordMin[0], this.m_coordMax[1], (this.m_coordMin[2] + this.m_coordMax[2]) * 0.5, (this.m_coordMin[3]+this.m_coordMax[3]) * 0.5,
+ this.m_coordMax[0], this.m_coordMin[1], (this.m_coordMin[2] + this.m_coordMax[2]) * 0.5, (this.m_coordMin[3]+this.m_coordMax[3]) * 0.5,
+ this.m_coordMax[0], this.m_coordMax[1], this.m_coordMax[2], this.m_coordMin[3]
+ ];
+
+ /** @type {Array<gluDrawUtil.VertexArrayBinding>} */ var vertexArrays = [
+ gluDrawUtil.newFloatVertexArrayBinding('a_position', 4, 4, 0, positions),
+ gluDrawUtil.newFloatVertexArrayBinding('a_coord', 4, 4, 0, coords)
+ ];
+
+ /** @type {Array<number>} */ var indices = [0, 2, 1, 2, 3, 1];
+
+ gl.clearColor(0.125, 0.25, 0.5, 1.0);
+ // We can't really call clear() on gl.COLOR_BUFFER_BIT here as in c++ deqp.
+ // The fbo format might be of integer type and WebGL2 requires an INVALID_OPERATION to be generated.
+ var formatObj = gluTextureUtil.mapGLInternalFormat(fboFormat);
+ var fmtClass = tcuTexture.getTextureChannelClass(formatObj.type);
+ switch (fmtClass) {
+ case tcuTexture.TextureChannelClass.FLOATING_POINT:
+ case tcuTexture.TextureChannelClass.SIGNED_FIXED_POINT:
+ case tcuTexture.TextureChannelClass.UNSIGNED_FIXED_POINT:
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ break;
+ case tcuTexture.TextureChannelClass.UNSIGNED_INTEGER:
+ gl.clearBufferuiv(gl.COLOR, 0, new Uint32Array([31, 63, 127, 255]));
+ gl.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ break;
+ case tcuTexture.TextureChannelClass.SIGNED_INTEGER:
+ gl.clearBufferiv(gl.COLOR, 0, new Int32Array([31, 63, 127, 255]));
+ gl.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
+ break;
+ default:
+ throw new Error('Invalid channelclass ' + fmtClass);
+ }
+ gl.disable(gl.DITHER);
+
+ gl.useProgram(program.getProgram());
+
+ /** @type {WebGLUniformLocation} */ var scaleLoc = gl.getUniformLocation(program.getProgram(), 'u_scale');
+ /** @type {WebGLUniformLocation} */ var biasLoc = gl.getUniformLocation(program.getProgram(), 'u_bias');
+
+ switch (this.m_dataType) {
+ case gluShaderUtil.DataType.FLOAT:
+ gl.uniform1f(scaleLoc, this.m_derivScale[0]);
+ gl.uniform1f(biasLoc, this.m_derivBias[0]);
+ break;
+
+ case gluShaderUtil.DataType.FLOAT_VEC2:
+ gl.uniform2fv(scaleLoc, this.m_derivScale.slice(0,2));
+ gl.uniform2fv(biasLoc, this.m_derivBias.slice(0,2));
+ break;
+
+ case gluShaderUtil.DataType.FLOAT_VEC3:
+ gl.uniform3fv(scaleLoc, this.m_derivScale.slice(0,3));
+ gl.uniform3fv(biasLoc, this.m_derivBias.slice(0,3));
+ break;
+
+ case gluShaderUtil.DataType.FLOAT_VEC4:
+ gl.uniform4fv(scaleLoc, this.m_derivScale);
+ gl.uniform4fv(biasLoc, this.m_derivBias);
+ break;
+
+ default:
+ throw new Error('Data Type not supported: ' + this.m_dataType);
+ }
+
+ glsShaderRenderCase.setupDefaultUniforms(program.getProgram());
+ this.setupRenderState(program.getProgram());
+
+ gl.hint(gl.FRAGMENT_SHADER_DERIVATIVE_HINT, this.m_hint);
+
+ gl.viewport(viewportX, viewportY, viewportSize[0], viewportSize[1]);
+ gluDrawUtil.draw(gl, program.getProgram(), vertexArrays, gluDrawUtil.triangles(indices));
+
+ // Read back results
+
+ /** @type {boolean} */ var isMSAA = useFbo && this.m_numSamples > 0;
+ /** @type {?WebGLFramebuffer} */ var resFbo = null;
+ /** @type {?WebGLRenderbuffer} */ var resRbo = null;
+
+ // Resolve if necessary
+ if (isMSAA) {
+ resFbo = gl.createFramebuffer();
+ resRbo = gl.createRenderbuffer();
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, resRbo);
+ gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 0, fboFormat, viewportSize[0], viewportSize[1]);
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, resFbo);
+ gl.framebufferRenderbuffer(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, resRbo);
+
+ gl.blitFramebuffer(0, 0, viewportSize[0], viewportSize[1], 0, 0, viewportSize[0], viewportSize[1], gl.COLOR_BUFFER_BIT, gl.NEAREST);
+
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, resFbo);
+ }
+ switch (this.m_surfaceType) {
+ case es3fShaderDerivateTests.SurfaceType.DEFAULT_FRAMEBUFFER:
+ case es3fShaderDerivateTests.SurfaceType.UNORM_FBO:
+ var dataFormat = new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNORM_INT8);
+ result = new tcuTexture.TextureLevel(dataFormat, viewportSize[0], viewportSize[1]);
+ gluPixelTransfer.readPixels(gl, viewportX, viewportY, dataFormat, result);
+ break;
+
+ case es3fShaderDerivateTests.SurfaceType.FLOAT_FBO:
+ var dataFormat = new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.FLOAT);
+ var transferFormat = new tcuTexture.TextureFormat(tcuTexture.ChannelOrder.RGBA, tcuTexture.ChannelType.UNSIGNED_INT32);
+ result = new tcuTexture.TextureLevel(dataFormat, viewportSize[0], viewportSize[1]);
+ gluPixelTransfer.readPixels(gl, viewportX, viewportY, transferFormat, result);
+ break;
+
+ default:
+ throw new Error('Surface Type not supported: ' + this.m_surfaceType);
+ }
+
+ // Verify
+ /** @type {tcuSurface.Surface} */
+ var errorMask = new tcuSurface.Surface(result.getWidth(), result.getHeight());
+
+ errorMask.getAccess().clear(tcuRGBA.RGBA.green.toVec());
+
+ /** @type {boolean} */ var isOk = this.verify(result.getAccess(), errorMask.getAccess());
+
+ if (!isOk) {
+ tcuLogImage.logImage('Rendered', 'Rendered image', result.getAccess());
+ tcuLogImage.logImage('ErrorMask', 'Error mask', errorMask.getAccess());
+ testFailedOptions('Fail', false);
+ } else
+ testPassedOptions('Pass', true);
+
+ // Cleaning up buffers
+ gl.deleteFramebuffer(fbo);
+ gl.deleteRenderbuffer(rbo);
+ gl.deleteFramebuffer(resFbo);
+ gl.deleteRenderbuffer(resRbo);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @return {Array<number>}
+ */
+ es3fShaderDerivateTests.TriangleDerivateCase.prototype.getSurfaceThreshold = function() {
+ switch (this.m_surfaceType) {
+ case es3fShaderDerivateTests.SurfaceType.DEFAULT_FRAMEBUFFER:
+ /** @type {tcuPixelFormat.PixelFormat} */ var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
+ /** @type {Array<number>} */ var channelBits = [pixelFormat.redBits, pixelFormat.greenBits, pixelFormat.blueBits, pixelFormat.alphaBits];
+ /** @type {Array<number>} */ var intThreshold = deMath.arrayShiftLeft([1, 1, 1, 1], deMath.subtract([8, 8, 8, 8], channelBits));
+ /** @type {Array<number>} */ var normThreshold = deMath.scale(intThreshold, 1.0/255.0);
+
+ return normThreshold;
+
+ case es3fShaderDerivateTests.SurfaceType.UNORM_FBO: return deMath.scale([1, 1, 1, 1], 1.0/255.0);
+ case es3fShaderDerivateTests.SurfaceType.FLOAT_FBO: return [0.0, 0.0, 0.0, 0.0];
+ default:
+ assertMsgOptions(false, 'Surface Type not supported. Falling back to default retun value [0.0, 0.0, 0.0, 0.0]', false, false);
+ return [0.0, 0.0, 0.0, 0.0];
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderDerivateTests.TriangleDerivateCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {es3fShaderDerivateTests.DerivateFunc} func
+ * @param {gluShaderUtil.DataType} type
+ */
+ es3fShaderDerivateTests.ConstantDerivateCase = function(name, description, func, type) {
+ es3fShaderDerivateTests.TriangleDerivateCase.call(this, name, description);
+ /** @type {es3fShaderDerivateTests.DerivateFunc} */ this.m_func = func;
+ this.m_dataType = type;
+ this.m_precision = gluShaderUtil.precision.PRECISION_HIGHP;
+ this.m_coordDataType = this.m_dataType;
+ this.m_coordPrecision = this.m_precision;
+ };
+
+ es3fShaderDerivateTests.ConstantDerivateCase.prototype = Object.create(es3fShaderDerivateTests.TriangleDerivateCase.prototype);
+ es3fShaderDerivateTests.ConstantDerivateCase.prototype.constructor = es3fShaderDerivateTests.ConstantDerivateCase;
+
+ es3fShaderDerivateTests.ConstantDerivateCase.prototype.init = function() {
+ /** @type {string} */ var fragmentTmpl = '' +
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_scale;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_bias;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${PRECISION} ${DATATYPE} res = ${FUNC}(${VALUE}) * u_scale + u_bias;\n' +
+ ' o_color = ${CAST_TO_OUTPUT};\n' +
+ '}\n';
+
+ /** @type {Object} */ var fragmentParams = {};
+ fragmentParams['PRECISION'] = gluShaderUtil.getPrecisionName(this.m_precision);
+ fragmentParams['DATATYPE'] = gluShaderUtil.getDataTypeName(this.m_dataType);
+ fragmentParams['FUNC'] = es3fShaderDerivateTests.getDerivateFuncName(this.m_func);
+ fragmentParams['VALUE'] = this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC4 ? 'vec4(1.0, 7.2, -1e5, 0.0)' :
+ this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC3 ? 'vec3(1e2, 8.0, 0.01)' :
+ this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC2 ? 'vec2(-0.0, 2.7)' :
+ '7.7';
+ fragmentParams['CAST_TO_OUTPUT'] = this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC4 ? 'res' :
+ this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC3 ? 'vec4(res, 1.0)' :
+ this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC2 ? 'vec4(res, 0.0, 1.0)' :
+ 'vec4(res, 0.0, 0.0, 1.0)';
+
+ this.m_fragmentSrc = tcuStringTemplate.specialize(fragmentTmpl, fragmentParams);
+
+ this.m_derivScale = [1e3, 1e3, 1e3, 1e3];
+ this.m_derivBias = [0.5, 0.5, 0.5, 0.5];
+ };
+
+ /**
+ * @param {tcuTexture.ConstPixelBufferAccess} result
+ * @param {tcuTexture.PixelBufferAccess} errorMask
+ * @return {boolean}
+ */
+ es3fShaderDerivateTests.ConstantDerivateCase.prototype.verify = function(result, errorMask) {
+ /** @type {Array<number>} */ var reference = [0.0, 0.0, 0.0, 0.0]; // Derivate of constant argument should always be 0
+ /** @type {Array<number>} */ var threshold = deMath.divide(this.getSurfaceThreshold(), deMath.abs(this.m_derivScale));
+ return es3fShaderDerivateTests.verifyConstantDerivate(result, errorMask, this.m_dataType,
+ reference, threshold, this.m_derivScale, this.m_derivBias);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderDerivateTests.TriangleDerivateCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {es3fShaderDerivateTests.DerivateFunc} func
+ * @param {gluShaderUtil.DataType} type
+ * @param {gluShaderUtil.precision} precision
+ * @param {number} hint
+ * @param {es3fShaderDerivateTests.SurfaceType} surfaceType
+ * @param {number} numSamples
+ * @param {string} fragmentSrcTmpl
+ */
+ es3fShaderDerivateTests.LinearDerivateCase = function(name, description, func, type, precision, hint, surfaceType, numSamples, fragmentSrcTmpl) {
+ es3fShaderDerivateTests.TriangleDerivateCase.call(this, name, description);
+ /** @type {es3fShaderDerivateTests.DerivateFunc} */ this.m_func = func;
+ /** @type {string} */ this.m_fragmentTmpl = fragmentSrcTmpl;
+ this.m_dataType = type;
+ this.m_precision = precision;
+ this.m_coordDataType = this.m_dataType;
+ this.m_coordPrecision = this.m_precision;
+ this.m_hint = hint;
+ this.m_surfaceType = surfaceType;
+ this.m_numSamples = numSamples;
+ };
+
+ es3fShaderDerivateTests.LinearDerivateCase.prototype = Object.create(es3fShaderDerivateTests.TriangleDerivateCase.prototype);
+ es3fShaderDerivateTests.LinearDerivateCase.prototype.constructor = es3fShaderDerivateTests.LinearDerivateCase;
+
+ es3fShaderDerivateTests.LinearDerivateCase.prototype.init = function() {
+ /** @type {Array<number>} */ var viewportSize = this.getViewportSize();
+ /** @type {number} */ var w = viewportSize[0];
+ /** @type {number} */ var h = viewportSize[1];
+ /** @type {boolean} */ var packToInt = this.m_surfaceType === es3fShaderDerivateTests.SurfaceType.FLOAT_FBO;
+
+ /** @type {Object} */ var fragmentParams = {};
+ fragmentParams['OUTPUT_TYPE'] = gluShaderUtil.getDataTypeName(packToInt ? gluShaderUtil.DataType.UINT_VEC4 : gluShaderUtil.DataType.FLOAT_VEC4);
+ fragmentParams['OUTPUT_PREC'] = gluShaderUtil.getPrecisionName(packToInt ? gluShaderUtil.precision.PRECISION_HIGHP : this.m_precision);
+ fragmentParams['PRECISION'] = gluShaderUtil.getPrecisionName(this.m_precision);
+ fragmentParams['DATATYPE'] = gluShaderUtil.getDataTypeName(this.m_dataType);
+ fragmentParams['FUNC'] = es3fShaderDerivateTests.getDerivateFuncName(this.m_func);
+
+ if (packToInt) {
+ fragmentParams['CAST_TO_OUTPUT'] = this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC4 ? 'floatBitsToUint(res)' :
+ this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC3 ? 'floatBitsToUint(vec4(res, 1.0))' :
+ this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC2 ? 'floatBitsToUint(vec4(res, 0.0, 1.0))' :
+ 'floatBitsToUint(vec4(res, 0.0, 0.0, 1.0))';
+ } else {
+ fragmentParams['CAST_TO_OUTPUT'] = this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC4 ? 'res' :
+ this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC3 ? 'vec4(res, 1.0)' :
+ this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC2 ? 'vec4(res, 0.0, 1.0)' :
+ 'vec4(res, 0.0, 0.0, 1.0)';
+ }
+
+ this.m_fragmentSrc = tcuStringTemplate.specialize(this.m_fragmentTmpl, fragmentParams);
+
+ switch (this.m_precision) {
+ case gluShaderUtil.precision.PRECISION_HIGHP:
+ this.m_coordMin = [-97., 0.2, 71., 74.];
+ this.m_coordMax = [-13.2, -77., 44., 76.];
+ break;
+
+ case gluShaderUtil.precision.PRECISION_MEDIUMP:
+ this.m_coordMin = [-37.0, 47., -7., 0.0];
+ this.m_coordMax = [-1.0, 12., 7., 19.];
+ break;
+
+ case gluShaderUtil.precision.PRECISION_LOWP:
+ this.m_coordMin = [0.0, -1.0, 0.0, 1.0];
+ this.m_coordMax = [1.0, 1.0, -1.0, -1.0];
+ break;
+
+ default:
+ throw new Error('Precision not supported: ' + this.m_precision);
+ }
+
+ if (this.m_surfaceType === es3fShaderDerivateTests.SurfaceType.FLOAT_FBO) {
+ // No scale or bias used for accuracy.
+ this.m_derivScale = [1.0, 1.0, 1.0, 1.0];
+ this.m_derivBias = [0.0, 0.0, 0.0, 0.0];
+ } else {
+ // Compute scale - bias that normalizes to 0..1 range.
+ /** @type {Array<number>} */ var dx = deMath.divide(deMath.subtract(this.m_coordMax, this.m_coordMin), [w, w, w * 0.5, -w * 0.5]);
+ /** @type {Array<number>} */ var dy = deMath.divide(deMath.subtract(this.m_coordMax, this.m_coordMin), [h, h, h * 0.5, -h * 0.5]);
+
+ switch (this.m_func) {
+ case es3fShaderDerivateTests.DerivateFunc.DFDX:
+ this.m_derivScale = deMath.divide([0.5, 0.5, 0.5, 0.5], dx);
+ break;
+
+ case es3fShaderDerivateTests.DerivateFunc.DFDY:
+ this.m_derivScale = deMath.divide([0.5, 0.5, 0.5, 0.5], dy);
+ break;
+
+ case es3fShaderDerivateTests.DerivateFunc.FWIDTH:
+ this.m_derivScale = deMath.divide([0.5, 0.5, 0.5, 0.5], deMath.add(deMath.abs(dx), deMath.abs(dy)));
+ break;
+
+ default:
+ throw new Error('Derivate Function not supported: ' + this.m_func);
+ }
+
+ this.m_derivBias = [0.0, 0.0, 0.0, 0.0];
+ }
+ };
+
+ /**
+ * @param {tcuTexture.ConstPixelBufferAccess} result
+ * @param {tcuTexture.PixelBufferAccess} errorMask
+ * @return {boolean}
+ */
+ es3fShaderDerivateTests.LinearDerivateCase.prototype.verify = function(result, errorMask) {
+ /** @type {Array<number>} */ var xScale = [1.0, 0.0, 0.5, -0.5];
+ /** @type {Array<number>} */ var yScale = [0.0, 1.0, 0.5, -0.5];
+ /** @type {Array<number>} */ var surfaceThreshold = deMath.divide(this.getSurfaceThreshold(), deMath.abs(this.m_derivScale));
+
+ /** @type {number} */ var w;
+ /** @type {number} */ var h;
+ /** @type {Array<number>} */ var reference;
+ /** @type {Array<number>} */ var threshold;
+
+ if (this.m_func === es3fShaderDerivateTests.DerivateFunc.DFDX || this.m_func === es3fShaderDerivateTests.DerivateFunc.DFDY) {
+ /** @type {boolean} */ var isX = this.m_func === es3fShaderDerivateTests.DerivateFunc.DFDX;
+ /** @type {number} */ var div = isX ? result.getWidth() : result.getHeight();
+ /** @type {Array<number>} */ var scale = isX ? xScale : yScale;
+ reference = deMath.multiply(deMath.scale(deMath.subtract(this.m_coordMax, this.m_coordMin), 1/div), scale);
+ /** @type {Array<number>} */ var opThreshold = es3fShaderDerivateTests.getDerivateThreshold(this.m_precision, deMath.multiply(this.m_coordMin, scale), deMath.multiply(this.m_coordMax, scale), reference);
+ threshold = deMath.max(surfaceThreshold, opThreshold);
+ bufferedLogToConsole('Verifying result image.\n' +
+ '\tValid derivative is ' + reference + ' with threshold ' + threshold);
+
+ // short circuit if result is strictly within the normal value error bounds.
+ // This improves performance significantly.
+ if (es3fShaderDerivateTests.verifyConstantDerivate(result, errorMask,
+ this.m_dataType, reference, threshold, this.m_derivScale,
+ this.m_derivBias, es3fShaderDerivateTests.VerificationLogging.LOG_NOTHING)) {
+ bufferedLogToConsole('No incorrect derivatives found, result valid.');
+ return true;
+ }
+
+ // some pixels exceed error bounds calculated for normal values. Verify that these
+ // potentially invalid pixels are in fact valid due to (for example) subnorm flushing.
+
+ bufferedLogToConsole('Initial verification failed, verifying image by calculating accurate error bounds for each result pixel.\n' +
+ '\tVerifying each result derivative is within its range of legal result values.');
+
+ /** @type {Array<number>} */ var viewportSize = this.getViewportSize();
+ /** @type {Array<number>} */ var valueRamp = deMath.subtract(this.m_coordMax, this.m_coordMin);
+ /** @type {es3fShaderDerivateTests.Linear2DFunctionEvaluator} */ var function_ = new es3fShaderDerivateTests.Linear2DFunctionEvaluator();
+ w = viewportSize[0];
+ h = viewportSize[1];
+
+ function_.matrix.setRow(0, [valueRamp[0] / w, 0.0, this.m_coordMin[0]]);
+ function_.matrix.setRow(1, [0.0, valueRamp[1] / h, this.m_coordMin[1]]);
+ function_.matrix.setRow(2, deMath.scale([valueRamp[2] / w, valueRamp[2] / h, this.m_coordMin[2] + this.m_coordMin[2]], 1 / 2.0));
+ function_.matrix.setRow(3, deMath.scale([-valueRamp[3] / w, -valueRamp[3] / h, this.m_coordMax[3] + this.m_coordMax[3]], 1 / 2.0));
+
+ return es3fShaderDerivateTests.reverifyConstantDerivateWithFlushRelaxations(
+ result, errorMask, this.m_dataType, this.m_precision, this.m_derivScale,
+ this.m_derivBias, surfaceThreshold, this.m_func, function_);
+ } else {
+ assertMsgOptions(this.m_func === es3fShaderDerivateTests.DerivateFunc.FWIDTH, 'Expected DerivateFunc.FWIDTH', false, true);
+ w = result.getWidth();
+ h = result.getHeight();
+
+ /** @type {Array<number>} */ var dx = deMath.multiply(deMath.scale(deMath.subtract(this.m_coordMax, this.m_coordMin), 1 / w), xScale);
+ /** @type {Array<number>} */ var dy = deMath.multiply(deMath.scale(deMath.subtract(this.m_coordMax, this.m_coordMin), 1 / h), yScale);
+ reference = deMath.add(deMath.abs(dx), deMath.abs(dy));
+ /** @type {Array<number>} */ var dxThreshold = es3fShaderDerivateTests.getDerivateThreshold(this.m_precision, deMath.multiply(this.m_coordMin, xScale), deMath.multiply(this.m_coordMax, xScale), dx);
+ /** @type {Array<number>} */ var dyThreshold = es3fShaderDerivateTests.getDerivateThreshold(this.m_precision, deMath.multiply(this.m_coordMin, yScale), deMath.multiply(this.m_coordMax, yScale), dy);
+ threshold = deMath.max(surfaceThreshold, deMath.max(dxThreshold, dyThreshold));
+
+ return es3fShaderDerivateTests.verifyConstantDerivate(result, errorMask, this.m_dataType,
+ reference, threshold, this.m_derivScale, this.m_derivBias);
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderDerivateTests.TriangleDerivateCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {es3fShaderDerivateTests.DerivateFunc} func
+ * @param {gluShaderUtil.DataType} type
+ * @param {gluShaderUtil.precision} precision
+ * @param {number} hint
+ * @param {es3fShaderDerivateTests.SurfaceType} surfaceType
+ * @param {number} numSamples
+ */
+ es3fShaderDerivateTests.TextureDerivateCase = function(name, description, func, type, precision, hint, surfaceType, numSamples) {
+ es3fShaderDerivateTests.TriangleDerivateCase.call(this, name, description);
+ /** @type {es3fShaderDerivateTests.DerivateFunc} */ this.m_func = func;
+ /** @type {gluTexture.Texture2D} */ this.m_texture = null;
+ /** @type {Array<number>} */ this.m_texValueMin = [];
+ /** @type {Array<number>} */ this.m_texValueMax = [];
+ this.m_dataType = type;
+ this.m_precision = precision;
+ this.m_coordDataType = gluShaderUtil.DataType.FLOAT_VEC2;
+ this.m_coordPrecision = gluShaderUtil.precision.PRECISION_HIGHP;
+ this.m_hint = hint;
+ this.m_surfaceType = surfaceType;
+ this.m_numSamples = numSamples;
+ };
+
+ es3fShaderDerivateTests.TextureDerivateCase.prototype = Object.create(es3fShaderDerivateTests.TriangleDerivateCase.prototype);
+ es3fShaderDerivateTests.TextureDerivateCase.prototype.constructor = es3fShaderDerivateTests.TextureDerivateCase;
+
+ es3fShaderDerivateTests.TextureDerivateCase.prototype.deinit = function() {
+ this.m_texture = null;
+ };
+
+ es3fShaderDerivateTests.TextureDerivateCase.prototype.init = function() {
+ // Generate shader
+ /** @type {string} */ var fragmentTmpl = '' +
+ '#version 300 es\n' +
+ 'in highp vec2 v_coord;\n' +
+ 'layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n' +
+ 'uniform ${PRECISION} sampler2D u_sampler;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_scale;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_bias;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${PRECISION} vec4 tex = texture(u_sampler, v_coord);\n' +
+ ' ${PRECISION} ${DATATYPE} res = ${FUNC}(tex${SWIZZLE}) * u_scale + u_bias;\n' +
+ ' o_color = ${CAST_TO_OUTPUT};\n' +
+ '}\n';
+
+ /** @type {boolean} */ var packToInt = this.m_surfaceType === es3fShaderDerivateTests.SurfaceType.FLOAT_FBO;
+ /** @type {Object} */ var fragmentParams = {};
+ /** @type {Array<number>} */ var viewportSize;
+ fragmentParams['OUTPUT_TYPE'] = gluShaderUtil.getDataTypeName(packToInt ? gluShaderUtil.DataType.UINT_VEC4 : gluShaderUtil.DataType.FLOAT_VEC4);
+ fragmentParams['OUTPUT_PREC'] = gluShaderUtil.getPrecisionName(packToInt ? gluShaderUtil.precision.PRECISION_HIGHP : this.m_precision);
+ fragmentParams['PRECISION'] = gluShaderUtil.getPrecisionName(this.m_precision);
+ fragmentParams['DATATYPE'] = gluShaderUtil.getDataTypeName(this.m_dataType);
+ fragmentParams['FUNC'] = es3fShaderDerivateTests.getDerivateFuncName(this.m_func);
+ fragmentParams['SWIZZLE'] = this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC4 ? '' :
+ this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC3 ? '.xyz' :
+ this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC2 ? '.xy' :
+ '.x';
+
+ if (packToInt) {
+ fragmentParams['CAST_TO_OUTPUT'] = this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC4 ? 'floatBitsToUint(res)' :
+ this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC3 ? 'floatBitsToUint(vec4(res, 1.0))' :
+ this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC2 ? 'floatBitsToUint(vec4(res, 0.0, 1.0))' :
+ 'floatBitsToUint(vec4(res, 0.0, 0.0, 1.0))';
+ } else {
+ fragmentParams['CAST_TO_OUTPUT'] = this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC4 ? 'res' :
+ this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC3 ? 'vec4(res, 1.0)' :
+ this.m_dataType === gluShaderUtil.DataType.FLOAT_VEC2 ? 'vec4(res, 0.0, 1.0)' :
+ 'vec4(res, 0.0, 0.0, 1.0)';
+ }
+
+ this.m_fragmentSrc = tcuStringTemplate.specialize(fragmentTmpl, fragmentParams);
+
+ // Texture size matches viewport and nearest sampling is used. Thus texture sampling
+ // is equal to just interpolating the texture value range.
+
+ // Determine value range for texture.
+
+ switch (this.m_precision) {
+ case gluShaderUtil.precision.PRECISION_HIGHP:
+ this.m_texValueMin = [-97., 0.2, 71., 74.];
+ this.m_texValueMax = [-13.2, -77., 44., 76.];
+ break;
+
+ case gluShaderUtil.precision.PRECISION_MEDIUMP:
+ this.m_texValueMin = [-37.0, 47., -7., 0.0];
+ this.m_texValueMax = [-1.0, 12., 7., 19.];
+ break;
+
+ case gluShaderUtil.precision.PRECISION_LOWP:
+ this.m_texValueMin = [0.0, -1.0, 0.0, 1.0];
+ this.m_texValueMax = [1.0, 1.0, -1.0, -1.0];
+ break;
+
+ default:
+ throw new Error(false, 'Precision not supported:' + this.m_precision);
+ }
+
+ // Lowp and mediump cases use RGBA16F format, while highp uses RGBA32F.
+ viewportSize = this.getViewportSize();
+ assertMsgOptions(!this.m_texture, 'Texture not null', false, true);
+ this.m_texture = gluTexture.texture2DFromInternalFormat(gl, this.m_precision === gluShaderUtil.precision.PRECISION_HIGHP ? gl.RGBA32F : gl.RGBA16F, viewportSize[0], viewportSize[1]);
+ this.m_texture.getRefTexture().allocLevel(0);
+
+ // Texture coordinates
+ this.m_coordMin = [0.0, 0.0, 0.0, 0.0];
+ this.m_coordMax = [1.0, 1.0, 1.0, 1.0];
+
+ // Fill with gradients.
+ /** @type {tcuTexture.PixelBufferAccess} */ var level0 = this.m_texture.getRefTexture().getLevel(0);
+ for (var y = 0; y < level0.getHeight(); y++) {
+ for (var x = 0; x < level0.getWidth(); x++) {
+ /** @type {number} */ var xf = (x + 0.5) / level0.getWidth();
+ /** @type {number} */ var yf = (y + 0.5) / level0.getHeight();
+ /** @type {Array<number>} */ var s = [xf, yf, (xf + yf) / 2.0, 1.0 - (xf + yf) / 2.0];
+
+ level0.setPixel(deMath.add(this.m_texValueMin, deMath.multiply(deMath.subtract(this.m_texValueMax, this.m_texValueMin), s)), x, y);
+ }
+ }
+
+ this.m_texture.upload();
+
+ if (this.m_surfaceType === es3fShaderDerivateTests.SurfaceType.FLOAT_FBO) {
+ // No scale or bias used for accuracy.
+ this.m_derivScale = [1.0, 1.0, 1.0, 1.0];
+ this.m_derivBias = [0.0, 0.0, 0.0, 0.0];
+ } else {
+ // Compute scale - bias that normalizes to 0..1 range.
+ viewportSize = this.getViewportSize();
+ /** @type {number} */ var w = viewportSize[0];
+ /** @type {number} */ var h = viewportSize[1];
+ /** @type {Array<number>} */ var dx = deMath.divide(deMath.subtract(this.m_texValueMax, this.m_texValueMin), [w, w, w * 0.5, -w * 0.5]);
+ /** @type {Array<number>} */ var dy = deMath.divide(deMath.subtract(this.m_texValueMax, this.m_texValueMin), [h, h, h * 0.5, -h * 0.5]);
+
+ switch (this.m_func) {
+ case es3fShaderDerivateTests.DerivateFunc.DFDX:
+ this.m_derivScale = deMath.divide([0.5, 0.5, 0.5, 0.5], dx);
+ break;
+
+ case es3fShaderDerivateTests.DerivateFunc.DFDY:
+ this.m_derivScale = deMath.divide([0.5, 0.5, 0.5, 0.5], dy);
+ break;
+
+ case es3fShaderDerivateTests.DerivateFunc.FWIDTH:
+ this.m_derivScale = deMath.divide([0.5, 0.5, 0.5, 0.5], deMath.add(deMath.abs(dx), deMath.abs(dy)));
+ break;
+
+ default:
+ throw new Error('Derivate Function not supported: ' + this.m_func);
+ }
+
+ this.m_derivBias = [0.0, 0.0, 0.0, 0.0];
+ }
+ };
+
+ /**
+ * @param {WebGLProgram} program
+ */
+ es3fShaderDerivateTests.TextureDerivateCase.prototype.setupRenderState = function(program) {
+ /** @type {number} */ var texUnit = 1;
+
+ gl.activeTexture(gl.TEXTURE0 + texUnit);
+ gl.bindTexture(gl.TEXTURE_2D, this.m_texture.getGLTexture());
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+
+ gl.uniform1i(gl.getUniformLocation(program, 'u_sampler'), texUnit);
+ };
+
+ /**
+ * @param {tcuTexture.PixelBufferAccess} result
+ * @param {tcuTexture.PixelBufferAccess} errorMask
+ * @return {boolean}
+ */
+ es3fShaderDerivateTests.TextureDerivateCase.prototype.verify = function(result, errorMask) {
+ // \note Edges are ignored in comparison
+ if (result.getWidth() < 2 || result.getHeight() < 2)
+ throw new Error('Too small viewport');
+
+ /** @type {tcuTexture.PixelBufferAccess} */ var compareArea = tcuTextureUtil.getSubregion(result, 1, 1, 0, result.getWidth() - 2, result.getHeight() - 2, 1);
+ /** @type {tcuTexture.PixelBufferAccess} */ var maskArea = tcuTextureUtil.getSubregion(errorMask, 1, 1, 0, errorMask.getWidth() - 2, errorMask.getHeight() - 2, 1);
+ /** @type {Array<number>} */ var xScale = [1.0, 0.0, 0.5, -0.5];
+ /** @type {Array<number>} */ var yScale = [0.0, 1.0, 0.5, -0.5];
+ /** @type {number} */ var w = result.getWidth();
+ /** @type {number} */ var h = result.getHeight();
+
+ /** @type {Array<number>} */ var surfaceThreshold = deMath.divide(this.getSurfaceThreshold(), deMath.abs(this.m_derivScale));
+ /** @type {Array<number>} */ var reference;
+ /** @type {Array<number>} */ var threshold;
+ if (this.m_func == es3fShaderDerivateTests.DerivateFunc.DFDX || this.m_func == es3fShaderDerivateTests.DerivateFunc.DFDY) {
+ /** @type {boolean} */ var isX = this.m_func == es3fShaderDerivateTests.DerivateFunc.DFDX;
+ /** @type {number} */ var div = isX ? w : h;
+ /** @type {Array<number>} */ var scale = isX ? xScale : yScale;
+ reference = deMath.multiply(deMath.scale(deMath.subtract(this.m_texValueMax, this.m_texValueMin), 1 / div), scale);
+ /** @type {Array<number>} */ var opThreshold = es3fShaderDerivateTests.getDerivateThreshold(this.m_precision, deMath.multiply(this.m_texValueMin, scale), deMath.multiply(this.m_texValueMax, scale), reference);
+ threshold = deMath.max(surfaceThreshold, opThreshold);
+
+ bufferedLogToConsole('Verifying result image.\n'+
+ '\tValid derivative is ' + reference + ' with threshold ' + threshold);
+
+ // short circuit if result is strictly within the normal value error bounds.
+ // This improves performance significantly.
+ if (es3fShaderDerivateTests.verifyConstantDerivate(compareArea, maskArea, this.m_dataType,
+ reference, threshold, this.m_derivScale, this.m_derivBias,
+ es3fShaderDerivateTests.VerificationLogging.LOG_NOTHING)) {
+ bufferedLogToConsole('No incorrect derivatives found, result valid.');
+ return true;
+ }
+ // some pixels exceed error bounds calculated for normal values. Verify that these
+ // potentially invalid pixels are in fact valid due to (for example) subnorm flushing.
+
+ bufferedLogToConsole('Initial verification failed, verifying image by calculating accurate error bounds for each result pixel.\n' +
+ '\tVerifying each result derivative is within its range of legal result values.');
+
+ /** @type {Array<number>} */ var valueRamp = deMath.subtract(this.m_texValueMax, this.m_texValueMin);
+ /** @type {es3fShaderDerivateTests.Linear2DFunctionEvaluator} */ var function_ = new es3fShaderDerivateTests.Linear2DFunctionEvaluator();
+
+ function_.matrix.setRow(0, [valueRamp[0] / w, 0.0, this.m_texValueMin[0]]);
+ function_.matrix.setRow(1, [0.0, valueRamp[1] / h, this.m_texValueMin[1]]);
+ function_.matrix.setRow(2, deMath.scale([valueRamp[2] / w, valueRamp[2] / h, this.m_texValueMin[2] + this.m_texValueMin[2]], 1 / 2.0));
+ function_.matrix.setRow(3, deMath.scale([-valueRamp[3] / w, -valueRamp[3] / h, this.m_texValueMax[3] + this.m_texValueMax[3]], 1 / 2.0));
+
+ return es3fShaderDerivateTests.reverifyConstantDerivateWithFlushRelaxations(compareArea, maskArea, this.m_dataType, this.m_precision,
+ this.m_derivScale, this.m_derivBias, surfaceThreshold, this.m_func, function_);
+ } else {
+ assertMsgOptions(this.m_func == es3fShaderDerivateTests.DerivateFunc.FWIDTH, 'Expected Derivate Function FWIDTH', false, true);
+ /** @type {Array<number>} */ var dx = deMath.multiply(deMath.scale(deMath.subtract(this.m_texValueMax, this.m_texValueMin), 1 / w), xScale);
+ /** @type {Array<number>} */ var dy = deMath.multiply(deMath.scale(deMath.subtract(this.m_texValueMax, this.m_texValueMin), 1 / h), yScale);
+ reference = deMath.add(deMath.abs(dx), deMath.abs(dy));
+ /** @type {Array<number>} */ var dxThreshold = es3fShaderDerivateTests.getDerivateThreshold(this.m_precision, deMath.multiply(this.m_texValueMin, xScale), deMath.multiply(this.m_texValueMax, xScale), dx);
+ /** @type {Array<number>} */ var dyThreshold = es3fShaderDerivateTests.getDerivateThreshold(this.m_precision, deMath.multiply(this.m_texValueMin, yScale), deMath.multiply(this.m_texValueMax, yScale), dy);
+ threshold = deMath.max(surfaceThreshold, deMath.max(dxThreshold, dyThreshold));
+
+ return es3fShaderDerivateTests.verifyConstantDerivate(compareArea, maskArea, this.m_dataType,
+ reference, threshold, this.m_derivScale, this.m_derivBias);
+ };
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderDerivateTests.ShaderDerivateTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'derivate', 'Derivate Function Tests');
+ };
+
+ es3fShaderDerivateTests.ShaderDerivateTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderDerivateTests.ShaderDerivateTests.prototype.constructor = es3fShaderDerivateTests.ShaderDerivateTests
+
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {es3fShaderDerivateTests.DerivateFunc} func
+ * @param {gluShaderUtil.DataType} dataType_
+ * @param {gluShaderUtil.precision} precision_
+ */
+ es3fShaderDerivateTests.FunctionSpec = function(name, func, dataType_, precision_) {
+ this.name = name;
+ this.function_ = func;
+ this.dataType = dataType_;
+ this.precision = precision_;
+ };
+
+ es3fShaderDerivateTests.ShaderDerivateTests.prototype.init = function() {
+ var testGroup = tcuTestCase.runner.testCases;
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {string} description
+ * @param {string} source
+ */
+ var LinearDerivateCase = function(name, description, source) {
+ /** @type {string} */ this.name = name;
+ /** @type {string} */ this.description = description;
+ /** @type {string} */ this.source = source;
+ };
+
+ /** @type {Array<LinearDerivateCase>} */
+ var s_linearDerivateCases = [
+ new LinearDerivateCase(
+ 'linear',
+ 'Basic derivate of linearly interpolated argument',
+ '#version 300 es\n' +
+ 'in ${PRECISION} ${DATATYPE} v_coord;\n' +
+ 'layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_scale;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_bias;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${PRECISION} ${DATATYPE} res = ${FUNC}(v_coord) * u_scale + u_bias;\n' +
+ ' o_color = ${CAST_TO_OUTPUT};\n' +
+ '}\n'),
+ new LinearDerivateCase(
+ 'in_function',
+ 'Derivate of linear function argument',
+ '#version 300 es\n' +
+ 'in ${PRECISION} ${DATATYPE} v_coord;\n' +
+ 'layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_scale;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_bias;\n' +
+ '\n' +
+ '${PRECISION} ${DATATYPE} computeRes (${PRECISION} ${DATATYPE} value)\n' +
+ '{\n' +
+ ' return ${FUNC}(v_coord) * u_scale + u_bias;\n' +
+ '}\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${PRECISION} ${DATATYPE} res = computeRes(v_coord);\n' +
+ ' o_color = ${CAST_TO_OUTPUT};\n' +
+ '}\n'),
+ new LinearDerivateCase(
+ 'static_if',
+ 'Derivate of linearly interpolated value in static if',
+ '#version 300 es\n' +
+ 'in ${PRECISION} ${DATATYPE} v_coord;\n' +
+ 'layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_scale;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_bias;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${PRECISION} ${DATATYPE} res;\n' +
+ ' if (false)\n' +
+ ' res = ${FUNC}(-v_coord) * u_scale + u_bias;\n' +
+ ' else\n' +
+ ' res = ${FUNC}(v_coord) * u_scale + u_bias;\n' +
+ ' o_color = ${CAST_TO_OUTPUT};\n' +
+ '}\n'),
+ new LinearDerivateCase(
+ 'static_loop',
+ 'Derivate of linearly interpolated value in static loop',
+ '#version 300 es\n' +
+ 'in ${PRECISION} ${DATATYPE} v_coord;\n' +
+ 'layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_scale;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_bias;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${PRECISION} ${DATATYPE} res = ${DATATYPE}(0.0);\n' +
+ ' for (int i = 0; i < 2; i++)\n' +
+ ' res += ${FUNC}(v_coord * float(i));\n' +
+ ' res = res * u_scale + u_bias;\n' +
+ ' o_color = ${CAST_TO_OUTPUT};\n' +
+ '}\n'),
+ new LinearDerivateCase(
+ 'static_switch',
+ 'Derivate of linearly interpolated value in static switch',
+ '#version 300 es\n' +
+ 'in ${PRECISION} ${DATATYPE} v_coord;\n' +
+ 'layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_scale;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_bias;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${PRECISION} ${DATATYPE} res;\n' +
+ ' switch (1)\n' +
+ ' {\n' +
+ ' case 0: res = ${FUNC}(-v_coord) * u_scale + u_bias; break;\n' +
+ ' case 1: res = ${FUNC}(v_coord) * u_scale + u_bias; break;\n' +
+ ' }\n' +
+ ' o_color = ${CAST_TO_OUTPUT};\n' +
+ '}\n'),
+ new LinearDerivateCase(
+ 'uniform_if',
+ 'Derivate of linearly interpolated value in uniform if',
+ '#version 300 es\n' +
+ 'in ${PRECISION} ${DATATYPE} v_coord;\n' +
+ 'layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_scale;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_bias;\n' +
+ 'uniform bool ub_true;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${PRECISION} ${DATATYPE} res;\n' +
+ ' if (ub_true)\n' +
+ ' res = ${FUNC}(v_coord) * u_scale + u_bias;\n' +
+ ' else\n' +
+ ' res = ${FUNC}(-v_coord) * u_scale + u_bias;\n' +
+ ' o_color = ${CAST_TO_OUTPUT};\n' +
+ '}\n'),
+ new LinearDerivateCase(
+ 'uniform_loop',
+ 'Derivate of linearly interpolated value in uniform loop',
+ '#version 300 es\n' +
+ 'in ${PRECISION} ${DATATYPE} v_coord;\n' +
+ 'layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_scale;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_bias;\n' +
+ 'uniform int ui_two;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${PRECISION} ${DATATYPE} res = ${DATATYPE}(0.0);\n' +
+ ' for (int i = 0; i < ui_two; i++)\n' +
+ ' res += ${FUNC}(v_coord * float(i));\n' +
+ ' res = res * u_scale + u_bias;\n' +
+ ' o_color = ${CAST_TO_OUTPUT};\n' +
+ '}\n'),
+ new LinearDerivateCase(
+ 'uniform_switch',
+ 'Derivate of linearly interpolated value in uniform switch',
+ '#version 300 es\n' +
+ 'in ${PRECISION} ${DATATYPE} v_coord;\n' +
+ 'layout(location = 0) out ${OUTPUT_PREC} ${OUTPUT_TYPE} o_color;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_scale;\n' +
+ 'uniform ${PRECISION} ${DATATYPE} u_bias;\n' +
+ 'uniform int ui_one;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${PRECISION} ${DATATYPE} res;\n' +
+ ' switch (ui_one)\n' +
+ ' {\n' +
+ ' case 0: res = ${FUNC}(-v_coord) * u_scale + u_bias; break;\n' +
+ ' case 1: res = ${FUNC}(v_coord) * u_scale + u_bias; break;\n' +
+ ' }\n' +
+ ' o_color = ${CAST_TO_OUTPUT};\n' +
+ '}\n')
+ ];
+
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {es3fShaderDerivateTests.SurfaceType} surfaceType
+ * @param {number} numSamples
+ */
+ var FboConfig = function(name, surfaceType, numSamples) {
+ /** @type {string} */ this.name = name;
+ /** @type {es3fShaderDerivateTests.SurfaceType} */ this.surfaceType = surfaceType;
+ /** @type {number} */ this.numSamples = numSamples;
+ };
+
+ /** @type {Array<FboConfig>} */ var s_fboConfigs = [
+ new FboConfig('fbo', es3fShaderDerivateTests.SurfaceType.DEFAULT_FRAMEBUFFER, 0),
+ new FboConfig('fbo_msaa2', es3fShaderDerivateTests.SurfaceType.UNORM_FBO, 2),
+ new FboConfig('fbo_msaa4', es3fShaderDerivateTests.SurfaceType.UNORM_FBO, 4),
+ new FboConfig('fbo_float', es3fShaderDerivateTests.SurfaceType.FLOAT_FBO, 0)
+ ];
+
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {number} hint
+ */
+ var Hint = function(name, hint) {
+ /** @type {string} */ this.name = name;
+ /** @type {number} */ this.hint = hint;
+ };
+
+ /** @type {Array<Hint>} */ var s_hints = [
+ new Hint('fastest', gl.FASTEST),
+ new Hint('nicest', gl.NICEST)
+ ];
+
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {es3fShaderDerivateTests.SurfaceType} surfaceType
+ * @param {number} numSamples
+ */
+ var HintFboConfig = function(name, surfaceType, numSamples) {
+ /** @type {string} */ this.name = name;
+ /** @type {es3fShaderDerivateTests.SurfaceType} */ this.surfaceType = surfaceType;
+ /** @type {number} */ this.numSamples = numSamples;
+ };
+
+ /** @type {Array<HintFboConfig>} */ var s_hintFboConfigs = [
+ new HintFboConfig('default', es3fShaderDerivateTests.SurfaceType.DEFAULT_FRAMEBUFFER, 0),
+ new HintFboConfig('fbo_msaa4', es3fShaderDerivateTests.SurfaceType.UNORM_FBO, 4),
+ new HintFboConfig('fbo_float', es3fShaderDerivateTests.SurfaceType.FLOAT_FBO, 0)
+ ];
+
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {es3fShaderDerivateTests.SurfaceType} surfaceType
+ * @param {number} numSamples
+ * @param {number} hint
+ */
+ var TextureConfig = function(name, surfaceType, numSamples, hint) {
+ /** @type {string} */ this.name = name;
+ /** @type {es3fShaderDerivateTests.SurfaceType} */ this.surfaceType = surfaceType;
+ /** @type {number} */ this.numSamples = numSamples;
+ /** @type {number} */ this.hint = hint;
+ };
+
+ /** @type {Array<TextureConfig>} */ var s_textureConfigs = [
+ new TextureConfig('basic', es3fShaderDerivateTests.SurfaceType.DEFAULT_FRAMEBUFFER, 0, gl.DONT_CARE),
+ new TextureConfig('msaa4', es3fShaderDerivateTests.SurfaceType.UNORM_FBO, 4, gl.DONT_CARE),
+ new TextureConfig('float_fastest', es3fShaderDerivateTests.SurfaceType.FLOAT_FBO, 0, gl.FASTEST),
+ new TextureConfig('float_nicest', es3fShaderDerivateTests.SurfaceType.FLOAT_FBO, 0, gl.NICEST)
+ ];
+
+ /** @type {gluShaderUtil.DataType} */ var dataType;
+ /** @type {string} */ var source;
+ /** @type {gluShaderUtil.precision} */ var precision;
+ /** @type {es3fShaderDerivateTests.SurfaceType} */ var surfaceType;
+ /** @type {number} */ var numSamples;
+ /** @type {number} */ var hint;
+ /** @type {string} */ var caseName;
+ /** @type {tcuTestCase.DeqpTest} */ var fboGroup;
+
+ // .dfdx, .dfdy, .fwidth
+ for (var funcNdx in es3fShaderDerivateTests.DerivateFunc) {
+ /** @type {es3fShaderDerivateTests.DerivateFunc} */ var function_ = es3fShaderDerivateTests.DerivateFunc[funcNdx];
+ /** @type {tcuTestCase.DeqpTest} */ var functionGroup = tcuTestCase.newTest(es3fShaderDerivateTests.getDerivateFuncCaseName(function_), es3fShaderDerivateTests.getDerivateFuncName(function_));
+ testGroup.addChild(functionGroup);
+
+ // .constant - no precision variants, checks that derivate of constant arguments is 0
+ /** @type {tcuTestCase.DeqpTest} */ var constantGroup = tcuTestCase.newTest('constant', 'Derivate of constant argument');
+ functionGroup.addChild(constantGroup);
+
+ for (var vecSize = 1; vecSize <= 4; vecSize++) {
+ dataType = vecSize > 1 ? gluShaderUtil.getDataTypeFloatVec(vecSize) : gluShaderUtil.DataType.FLOAT;
+ constantGroup.addChild(new es3fShaderDerivateTests.ConstantDerivateCase(gluShaderUtil.getDataTypeName(dataType), '', function_, dataType));
+ }
+
+ // Cases based on LinearDerivateCase
+ for (var caseNdx = 0; caseNdx < s_linearDerivateCases.length; caseNdx++) {
+ /** @type {tcuTestCase.DeqpTest} */ var linearCaseGroup = tcuTestCase.newTest(s_linearDerivateCases[caseNdx].name, s_linearDerivateCases[caseNdx].description);
+ source = s_linearDerivateCases[caseNdx].source;
+ functionGroup.addChild(linearCaseGroup);
+
+ for (var vecSize = 1; vecSize <= 4; vecSize++)
+ for (var precNdx in gluShaderUtil.precision) {
+ dataType = vecSize > 1 ? gluShaderUtil.getDataTypeFloatVec(vecSize) : gluShaderUtil.DataType.FLOAT;
+ precision = gluShaderUtil.precision[precNdx];
+ surfaceType = es3fShaderDerivateTests.SurfaceType.DEFAULT_FRAMEBUFFER;
+ numSamples = 0;
+ hint = gl.DONT_CARE;
+
+ if (caseNdx !== 0 && precision === gluShaderUtil.precision.PRECISION_LOWP)
+ continue; // Skip as lowp doesn't actually produce any bits when rendered to default FB.
+
+ caseName = gluShaderUtil.getDataTypeName(dataType) + '_' + gluShaderUtil.getPrecisionName(precision);
+
+ linearCaseGroup.addChild(new es3fShaderDerivateTests.LinearDerivateCase(caseName, '', function_, dataType, precision, hint, surfaceType, numSamples, source));
+ }
+ }
+
+ // Fbo cases
+ for (var caseNdx = 0; caseNdx < s_fboConfigs.length; caseNdx++) {
+ fboGroup = tcuTestCase.newTest(s_fboConfigs[caseNdx].name, 'Derivate usage when rendering into FBO');
+ source = s_linearDerivateCases[0].source; // use source from .linear group
+ surfaceType = s_fboConfigs[caseNdx].surfaceType;
+ numSamples = s_fboConfigs[caseNdx].numSamples;
+ functionGroup.addChild(fboGroup);
+
+ for (var vecSize = 1; vecSize <= 4; vecSize++)
+ for (var precNdx in gluShaderUtil.precision) {
+ dataType = vecSize > 1 ? gluShaderUtil.getDataTypeFloatVec(vecSize) : gluShaderUtil.DataType.FLOAT;
+ precision = gluShaderUtil.precision[precNdx];
+ hint = gl.DONT_CARE;
+
+ if (surfaceType !== es3fShaderDerivateTests.SurfaceType.FLOAT_FBO && precision === gluShaderUtil.precision.PRECISION_LOWP)
+ continue; // Skip as lowp doesn't actually produce any bits when rendered to U8 RT.
+
+ caseName = gluShaderUtil.getDataTypeName(dataType) + '_' + gluShaderUtil.getPrecisionName(precision);
+
+ fboGroup.addChild(new es3fShaderDerivateTests.LinearDerivateCase(caseName, '', function_, dataType, precision, hint, surfaceType, numSamples, source));
+ }
+ }
+
+ // .fastest, .nicest
+ for (var hintCaseNdx = 0; hintCaseNdx < s_hints.length; hintCaseNdx++) {
+ /** @type {tcuTestCase.DeqpTest} */ var hintGroup = tcuTestCase.newTest(s_hints[hintCaseNdx].name, 'Shader derivate hints');
+ source = s_linearDerivateCases[0].source; // use source from .linear group
+ hint = s_hints[hintCaseNdx].hint;
+ functionGroup.addChild(hintGroup);
+
+ for (var fboCaseNdx = 0; fboCaseNdx < s_hintFboConfigs.length; fboCaseNdx++) {
+ fboGroup = tcuTestCase.newTest(s_hintFboConfigs[fboCaseNdx].name, '');
+ surfaceType = s_hintFboConfigs[fboCaseNdx].surfaceType;
+ numSamples = s_hintFboConfigs[fboCaseNdx].numSamples;
+ hintGroup.addChild(fboGroup);
+
+ for (var vecSize = 1; vecSize <= 4; vecSize++)
+ for (var precNdx in gluShaderUtil.precision) {
+ dataType = vecSize > 1 ? gluShaderUtil.getDataTypeFloatVec(vecSize) : gluShaderUtil.DataType.FLOAT;
+ precision = gluShaderUtil.precision[precNdx];
+
+ if (surfaceType !== es3fShaderDerivateTests.SurfaceType.FLOAT_FBO && precision === gluShaderUtil.precision.PRECISION_LOWP)
+ continue; // Skip as lowp doesn't actually produce any bits when rendered to U8 RT.
+
+ caseName = gluShaderUtil.getDataTypeName(dataType) + '_' + gluShaderUtil.getPrecisionName(precision);
+
+ fboGroup.addChild(new es3fShaderDerivateTests.LinearDerivateCase(caseName, '', function_, dataType, precision, hint, surfaceType, numSamples, source));
+ }
+ }
+ }
+
+ // .texture
+ /** @type {tcuTestCase.DeqpTest} */ var textureGroup = tcuTestCase.newTest('texture', 'Derivate of texture lookup result');
+ functionGroup.addChild(textureGroup);
+
+ for (var texCaseNdx = 0; texCaseNdx < s_textureConfigs.length; texCaseNdx++) {
+ /** @type {tcuTestCase.DeqpTest} */ var caseGroup = tcuTestCase.newTest(s_textureConfigs[texCaseNdx].name, '');
+ surfaceType = s_textureConfigs[texCaseNdx].surfaceType;
+ numSamples = s_textureConfigs[texCaseNdx].numSamples;
+ hint = s_textureConfigs[texCaseNdx].hint;
+ textureGroup.addChild(caseGroup);
+
+ for (var vecSize = 1; vecSize <= 4; vecSize++)
+ for (var precNdx in gluShaderUtil.precision) {
+ dataType = vecSize > 1 ? gluShaderUtil.getDataTypeFloatVec(vecSize) : gluShaderUtil.DataType.FLOAT;
+ precision = gluShaderUtil.precision[precNdx];
+
+ if (surfaceType !== es3fShaderDerivateTests.SurfaceType.FLOAT_FBO && precision === gluShaderUtil.precision.PRECISION_LOWP)
+ continue; // Skip as lowp doesn't actually produce any bits when rendered to U8 RT.
+
+ caseName = gluShaderUtil.getDataTypeName(dataType) + '_' + gluShaderUtil.getPrecisionName(precision);
+
+ caseGroup.addChild(new es3fShaderDerivateTests.TextureDerivateCase(caseName, '', function_, dataType, precision, hint, surfaceType, numSamples));
+ }
+ }
+ }
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fShaderDerivateTests.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fShaderDerivateTests.ShaderDerivateTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fShaderDerivateTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderIndexingTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderIndexingTests.js
new file mode 100644
index 0000000000..c08db90758
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderIndexingTests.js
@@ -0,0 +1,1278 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fShaderIndexingTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuStringTemplate');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluTexture');
+goog.require('modules.shared.glsShaderRenderCase');
+
+goog.scope(function() {
+ /** @type {?WebGL2RenderingContext} */ var gl;
+ var es3fShaderIndexingTests = functional.gles3.es3fShaderIndexingTests;
+ var deMath = framework.delibs.debase.deMath;
+ var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluTexture = framework.opengl.gluTexture;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuStringTemplate = framework.common.tcuStringTemplate;
+ /**
+ * @enum {number}
+ */
+ es3fShaderIndexingTests.IndexAccessType = {
+ STATIC: 0,
+ DYNAMIC: 1,
+ STATIC_LOOP: 2,
+ DYNAMIC_LOOP: 3
+ };
+
+ /**
+ * @param {es3fShaderIndexingTests.IndexAccessType} accessType
+ * @return {string}
+ */
+ es3fShaderIndexingTests.getIndexAccessTypeName = function(accessType) {
+ /** @type {Array<string>} */ var s_names = [
+ 'static',
+ 'dynamic',
+ 'static_loop',
+ 'dynamic_loop'
+ ];
+ return s_names[accessType];
+ };
+
+ /**
+ * @enum {number}
+ */
+ es3fShaderIndexingTests.VectorAccessType = {
+ DIRECT: 0,
+ COMPONENT: 1,
+ SUBSCRIPT_STATIC: 2,
+ SUBSCRIPT_DYNAMIC: 3,
+ SUBSCRIPT_STATIC_LOOP: 4,
+ SUBSCRIPT_DYNAMIC_LOOP: 5
+ };
+
+ /**
+ * @param {es3fShaderIndexingTests.VectorAccessType} accessType
+ * @return {string}
+ */
+ es3fShaderIndexingTests.getVectorAccessTypeName = function(accessType) {
+ /** @type {Array<string>} */ var s_names = [
+ 'direct',
+ 'component',
+ 'static_subscript',
+ 'dynamic_subscript',
+ 'static_loop_subscript',
+ 'dynamic_loop_subscript'
+ ];
+ assertMsgOptions(deMath.deInBounds32(accessType, 0, s_names.length), 'Index out of bounds', false, true);
+ return s_names[accessType];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayCoordsFloat = function(c) {
+ c.color[0] = 1.875 * c.coords[0];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayCoordsVec2 = function(c) {
+ var swizzled = deMath.swizzle(c.coords, [0, 1]);
+ c.color[0] = 1.875 * swizzled[0];
+ c.color[1] = 1.875 * swizzled[1];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayCoordsVec3 = function(c) {
+ var swizzled = deMath.swizzle(c.coords, [0, 1, 2]);
+ c.color[0] = 1.875 * swizzled[0];
+ c.color[1] = 1.875 * swizzled[1];
+ c.color[2] = 1.875 * swizzled[2];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayCoordsVec4 = function(c) {
+ c.color = deMath.scale(c.coords, 1.875);
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} dataType
+ * @return {function(glsShaderRenderCase.ShaderEvalContext)}
+ */
+ es3fShaderIndexingTests.getArrayCoordsEvalFunc = function(dataType) {
+ if (dataType === gluShaderUtil.DataType.FLOAT) return es3fShaderIndexingTests.evalArrayCoordsFloat;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC2) return es3fShaderIndexingTests.evalArrayCoordsVec2;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC3) return es3fShaderIndexingTests.evalArrayCoordsVec3;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC4) return es3fShaderIndexingTests.evalArrayCoordsVec4;
+ else throw new Error('Invalid data type.');
+ };
+
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayUniformFloat = function(c) {
+ c.color[0] = 1.875 * c.constCoords[0];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayUniformVec2 = function(c) {
+ var swizzled = deMath.swizzle(c.constCoords, [0, 1]);
+ c.color[0] = 1.875 * swizzled[0];
+ c.color[1] = 1.875 * swizzled[1];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayUniformVec3 = function(c) {
+ var swizzled = deMath.swizzle(c.constCoords, [0, 1, 2]);
+ c.color[0] = 1.875 * swizzled[0];
+ c.color[1] = 1.875 * swizzled[1];
+ c.color[2] = 1.875 * swizzled[2];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalArrayUniformVec4 = function(c) {
+ c.color = deMath.scale(c.constCoords, 1.875);
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} dataType
+ * @return {function(glsShaderRenderCase.ShaderEvalContext)}
+ */
+ es3fShaderIndexingTests.getArrayUniformEvalFunc = function(dataType) {
+ if (dataType === gluShaderUtil.DataType.FLOAT) return es3fShaderIndexingTests.evalArrayUniformFloat;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC2) return es3fShaderIndexingTests.evalArrayUniformVec2;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC3) return es3fShaderIndexingTests.evalArrayUniformVec3;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC4) return es3fShaderIndexingTests.evalArrayUniformVec4;
+ else throw new Error('Invalid data type.');
+ };
+
+ /**
+ * @constructor
+ * @extends {glsShaderRenderCase.ShaderRenderCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {gluShaderUtil.DataType} varType
+ * @param {function(glsShaderRenderCase.ShaderEvalContext)} evalFunc
+ * @param {string} vertShaderSource
+ * @param {string} fragShaderSource
+ */
+ es3fShaderIndexingTests.ShaderIndexingCase = function(name, description, isVertexCase, varType, evalFunc, vertShaderSource, fragShaderSource) {
+ glsShaderRenderCase.ShaderRenderCase.call(this, name, description, isVertexCase, evalFunc);
+ /** @type {gluShaderUtil.DataType} */ this.m_varType = varType;
+ /** @type {string} */ this.m_vertShaderSource = vertShaderSource;
+ /** @type {string} */ this.m_fragShaderSource = fragShaderSource;
+ };
+
+ es3fShaderIndexingTests.ShaderIndexingCase.prototype = Object.create(glsShaderRenderCase.ShaderRenderCase.prototype);
+ es3fShaderIndexingTests.ShaderIndexingCase.prototype.constructor = es3fShaderIndexingTests.ShaderIndexingCase;
+
+ /**
+ * @param {?WebGLProgram} programID
+ * @param {Array<number>} constCoords
+ */
+ es3fShaderIndexingTests.ShaderIndexingCase.prototype.setupUniforms = function(programID, constCoords) {
+ /** @type {(Array<number>|Float32Array)} */ var arr = [];
+ /** @type {Array<number>} */ var array1d = [];
+ /** @type {?WebGLUniformLocation} */ var arrLoc = gl.getUniformLocation(programID, 'u_arr');
+ if (arrLoc != null) {
+ if (this.m_varType === gluShaderUtil.DataType.FLOAT) {
+ arr[0] = constCoords[0];
+ arr[1] = constCoords[0] * 0.5;
+ arr[2] = constCoords[0] * 0.25;
+ arr[3] = constCoords[0] * 0.125;
+ gl.uniform1fv(arrLoc, arr);
+ }
+ else if (this.m_varType === gluShaderUtil.DataType.FLOAT_VEC2) {
+ arr[0] = deMath.swizzle(constCoords, [0, 1]);
+ arr[1] = deMath.scale(deMath.swizzle(constCoords, [0, 1]), 0.5);
+ arr[2] = deMath.scale(deMath.swizzle(constCoords, [0, 1]), 0.25);
+ arr[3] = deMath.scale(deMath.swizzle(constCoords, [0, 1]), 0.125);
+ for (var i = 0; i < arr.length; i++)
+ array1d = array1d.concat(arr[i]);
+ gl.uniform2fv(arrLoc, array1d);
+ }
+ else if (this.m_varType === gluShaderUtil.DataType.FLOAT_VEC3) {
+ arr[0] = deMath.swizzle(constCoords, [0, 1, 2]);
+ arr[1] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2]), 0.5);
+ arr[2] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2]), 0.25);
+ arr[3] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2]), 0.125);
+ for (var i = 0; i < arr.length; i++)
+ array1d = array1d.concat(arr[i]);
+ gl.uniform3fv(arrLoc, array1d);
+ }
+ else if (this.m_varType === gluShaderUtil.DataType.FLOAT_VEC4) {
+ arr[0] = deMath.swizzle(constCoords, [0,1,2,3]);
+ arr[1] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2, 3]), 0.5);
+ arr[2] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2, 3]), 0.25);
+ arr[3] = deMath.scale(deMath.swizzle(constCoords, [0, 1, 2, 3]), 0.125);
+ for (var i = 0; i < arr.length; i++)
+ array1d = array1d.concat(arr[i]);
+ gl.uniform4fv(arrLoc, array1d);
+ }
+ else
+ throw new Error('u_arr should not have location assigned in this test case');
+ }
+ };
+
+ /**
+ * @param {string} caseName
+ * @param {string} description
+ * @param {gluShaderUtil.DataType} varType
+ * @param {es3fShaderIndexingTests.IndexAccessType} vertAccess
+ * @param {es3fShaderIndexingTests.IndexAccessType} fragAccess
+ * @return {es3fShaderIndexingTests.ShaderIndexingCase}
+ */
+ es3fShaderIndexingTests.createVaryingArrayCase = function(caseName, description, varType, vertAccess, fragAccess) {
+ /** @type {string} */ var vtx = '';
+ vtx += '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in highp vec4 a_coords;\n';
+
+ if (vertAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC)
+ vtx += 'uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n';
+ else if (vertAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP)
+ vtx += 'uniform mediump int ui_four;\n';
+
+ vtx += 'out ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n' +
+ '\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n';
+
+ if (vertAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
+ vtx += ' var[0] = ${VAR_TYPE}(a_coords);\n' +
+ ' var[1] = ${VAR_TYPE}(a_coords) * 0.5;\n' +
+ ' var[2] = ${VAR_TYPE}(a_coords) * 0.25;\n' +
+ ' var[3] = ${VAR_TYPE}(a_coords) * 0.125;\n';
+ }
+ else if (vertAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ vtx += ' var[ui_zero] = ${VAR_TYPE}(a_coords);\n' +
+ ' var[ui_one] = ${VAR_TYPE}(a_coords) * 0.5;\n' +
+ ' var[ui_two] = ${VAR_TYPE}(a_coords) * 0.25;\n' +
+ ' var[ui_three] = ${VAR_TYPE}(a_coords) * 0.125;\n';
+ }
+ else if (vertAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
+ vtx += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n' +
+ ' for (int i = 0; i < 4; i++)\n' +
+ ' {\n' +
+ ' var[i] = ${VAR_TYPE}(coords);\n' +
+ ' coords = coords * 0.5;\n' +
+ ' }\n';
+ }
+ else {
+ assertMsgOptions(vertAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'Not Dynamic_Loop', false, true);
+ vtx += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n' +
+ ' for (int i = 0; i < ui_four; i++)\n' +
+ ' {\n' +
+ ' var[i] = ${VAR_TYPE}(coords);\n' +
+ ' coords = coords * 0.5;\n' +
+ ' }\n';
+ }
+ vtx += '}\n';
+
+ /** @type {string} */ var frag = '';
+ frag += '#version 300 es\n' +
+ 'precision mediump int;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ if (fragAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC)
+ frag += 'uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n';
+ else if (fragAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP)
+ frag += 'uniform int ui_four;\n';
+
+ frag += 'in ${PRECISION} ${VAR_TYPE} var[${ARRAY_LEN}];\n' +
+ '\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n';
+
+ if (fragAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
+ frag += ' res += var[0];\n' +
+ ' res += var[1];\n' +
+ ' res += var[2];\n' +
+ ' res += var[3];\n';
+ }
+ else if (fragAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ frag += ' res += var[ui_zero];\n' +
+ ' res += var[ui_one];\n' +
+ ' res += var[ui_two];\n' +
+ ' res += var[ui_three];\n';
+ }
+ else if (fragAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
+ frag += ' for (int i = 0; i < 4; i++)\n' +
+ ' res += var[i];\n';
+ }
+ else {
+ assertMsgOptions(fragAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'Not Dynamic_Loop', false, true);
+ frag += ' for (int i = 0; i < ui_four; i++)\n' +
+ ' res += var[i];\n';
+ }
+ frag += ' o_color = vec4(res${PADDING});\n' +
+ '}\n';
+
+ // Fill in shader templates.
+ /** @type {Object} */ var params = {};
+ params['VAR_TYPE'] = gluShaderUtil.getDataTypeName(varType);
+ params['ARRAY_LEN'] = '4';
+ params['PRECISION'] = 'mediump';
+
+ if (varType === gluShaderUtil.DataType.FLOAT)
+ params['PADDING'] = ', 0.0, 0.0, 1.0';
+ else if (varType === gluShaderUtil.DataType.FLOAT_VEC2)
+ params['PADDING'] = ', 0.0, 1.0';
+ else if (varType === gluShaderUtil.DataType.FLOAT_VEC3)
+ params['PADDING'] = ', 1.0';
+ else
+ params['PADDING'] = '';
+
+ /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
+ /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
+
+ /** @type {function(glsShaderRenderCase.ShaderEvalContext)} */
+ var evalFunc = es3fShaderIndexingTests.getArrayCoordsEvalFunc(varType);
+ return new es3fShaderIndexingTests.ShaderIndexingCase(caseName, description, true, varType, evalFunc, vertexShaderSource, fragmentShaderSource);
+ };
+
+ /**
+ * @param {string} caseName
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {gluShaderUtil.DataType} varType
+ * @param {es3fShaderIndexingTests.IndexAccessType} readAccess
+ * @return {es3fShaderIndexingTests.ShaderIndexingCase}
+ */
+ es3fShaderIndexingTests.createUniformArrayCase = function(caseName, description, isVertexCase, varType, readAccess) {
+ /** @type {string} */ var vtx = '';
+ /** @type {string} */ var frag = '';
+ /** @type {string} */ var op = '';
+
+ vtx += '#version 300 es\n';
+ frag += '#version 300 es\n';
+
+ vtx += 'in highp vec4 a_position;\n';
+ vtx += 'in highp vec4 a_coords;\n';
+ frag += 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ if (isVertexCase) {
+ vtx += 'out mediump vec4 v_color;\n';
+ frag += 'in mediump vec4 v_color;\n';
+ }
+ else {
+ vtx += 'out mediump vec4 v_coords;\n';
+ frag += 'in mediump vec4 v_coords;\n';
+ }
+
+ if (readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC)
+ op += 'uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n';
+ else if (readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP)
+ op += 'uniform mediump int ui_four;\n';
+
+ op += 'uniform ${PRECISION} ${VAR_TYPE} u_arr[${ARRAY_LEN}];\n';
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ vtx += '\n';
+ vtx += 'void main()\n';
+ vtx += '{\n';
+ vtx += ' gl_Position = a_position;\n';
+
+ frag += '\n';
+ frag += 'void main()\n';
+ frag += '{\n';
+
+ // Read array.
+ op += ' ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n';
+ if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
+ op += ' res += u_arr[0];\n';
+ op += ' res += u_arr[1];\n';
+ op += ' res += u_arr[2];\n';
+ op += ' res += u_arr[3];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ op += ' res += u_arr[ui_zero];\n';
+ op += ' res += u_arr[ui_one];\n';
+ op += ' res += u_arr[ui_two];\n';
+ op += ' res += u_arr[ui_three];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
+ op += ' for (int i = 0; i < 4; i++)\n';
+ op += ' res += u_arr[i];\n';
+ }
+ else {
+ assertMsgOptions(readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'readAccess not supported.', false, true);
+ op += ' for (int i = 0; i < ui_four; i++)\n';
+ op += ' res += u_arr[i];\n';
+ }
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ if (isVertexCase) {
+ vtx += ' v_color = vec4(res${PADDING});\n';
+ frag += ' o_color = v_color;\n';
+ }
+ else {
+ vtx += ' v_coords = a_coords;\n';
+ frag += ' o_color = vec4(res${PADDING});\n';
+ }
+
+ vtx += '}\n';
+ frag += '}\n';
+
+ // Fill in shader templates.
+ /** @type {Object} */ var params = {};
+ params['VAR_TYPE'] = gluShaderUtil.getDataTypeName(varType);
+ params['ARRAY_LEN'] = '4';
+ params['PRECISION'] = 'mediump';
+
+ if (varType === gluShaderUtil.DataType.FLOAT)
+ params['PADDING'] = ', 0.0, 0.0, 1.0';
+ else if (varType === gluShaderUtil.DataType.FLOAT_VEC2)
+ params['PADDING'] = ', 0.0, 1.0';
+ else if (varType === gluShaderUtil.DataType.FLOAT_VEC3)
+ params['PADDING'] = ', 1.0';
+ else
+ params['PADDING'] = '';
+
+
+ /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
+ /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
+
+ /** @type {function(glsShaderRenderCase.ShaderEvalContext)} */
+ var evalFunc = es3fShaderIndexingTests.getArrayUniformEvalFunc(varType);
+ return new es3fShaderIndexingTests.ShaderIndexingCase(caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource, fragmentShaderSource);
+ };
+
+ /**
+ * @param {string} caseName
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {gluShaderUtil.DataType} varType
+ * @param {es3fShaderIndexingTests.IndexAccessType} writeAccess
+ * @param {es3fShaderIndexingTests.IndexAccessType} readAccess
+ * @return {es3fShaderIndexingTests.ShaderIndexingCase}
+ */
+ es3fShaderIndexingTests.createTmpArrayCase = function(caseName, description, isVertexCase, varType, writeAccess, readAccess) {
+ /** @type {string} */ var vtx = '';
+ /** @type {string} */ var frag = '';
+ /** @type {string} */ var op = '';
+
+ vtx += '#version 300 es\n';
+ frag += '#version 300 es\n';
+
+ vtx += 'in highp vec4 a_position;\n' +
+ 'in highp vec4 a_coords;\n';
+ frag += 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ if (isVertexCase) {
+ vtx += 'out mediump vec4 v_color;\n';
+ frag += 'in mediump vec4 v_color;\n';
+ }
+ else {
+ vtx += 'out mediump vec4 v_coords;\n';
+ frag += 'in mediump vec4 v_coords;\n';
+ }
+
+ if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC || readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC)
+ op += 'uniform mediump int ui_zero, ui_one, ui_two, ui_three;\n';
+
+ if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP || readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP)
+ op += 'uniform mediump int ui_four;\n';
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ vtx += '\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n';
+
+ frag += '\n' +
+ 'void main()\n' +
+ '{\n';
+
+ // Write array.
+ if (isVertexCase)
+ op += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n';
+ else
+ op += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n';
+
+ op += ' ${PRECISION} ${VAR_TYPE} arr[${ARRAY_LEN}];\n';
+ if (writeAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
+ op += ' arr[0] = ${VAR_TYPE}(coords);\n' +
+ ' arr[1] = ${VAR_TYPE}(coords) * 0.5;\n' +
+ ' arr[2] = ${VAR_TYPE}(coords) * 0.25;\n' +
+ ' arr[3] = ${VAR_TYPE}(coords) * 0.125;\n';
+ }
+ else if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ op += ' arr[ui_zero] = ${VAR_TYPE}(coords);\n' +
+ ' arr[ui_one] = ${VAR_TYPE}(coords) * 0.5;\n' +
+ ' arr[ui_two] = ${VAR_TYPE}(coords) * 0.25;\n' +
+ ' arr[ui_three] = ${VAR_TYPE}(coords) * 0.125;\n';
+ }
+ else if (writeAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
+ op += ' for (int i = 0; i < 4; i++)\n' +
+ ' {\n' +
+ ' arr[i] = ${VAR_TYPE}(coords);\n' +
+ ' coords = coords * 0.5;\n' +
+ ' }\n';
+ }
+ else {
+ assertMsgOptions(writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'writeAccess not supported', false, true);
+ op += ' for (int i = 0; i < ui_four; i++)\n' +
+ ' {\n' +
+ ' arr[i] = ${VAR_TYPE}(coords);\n' +
+ ' coords = coords * 0.5;\n' +
+ ' }\n';
+ }
+
+ // Read array.
+ op += ' ${PRECISION} ${VAR_TYPE} res = ${VAR_TYPE}(0.0);\n';
+ if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
+ op += ' res += arr[0];\n' +
+ ' res += arr[1];\n' +
+ ' res += arr[2];\n' +
+ ' res += arr[3];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ op += ' res += arr[ui_zero];\n' +
+ ' res += arr[ui_one];\n' +
+ ' res += arr[ui_two];\n' +
+ ' res += arr[ui_three];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
+ op += ' for (int i = 0; i < 4; i++)\n' +
+ ' res += arr[i];\n';
+ }
+ else {
+ assertMsgOptions(readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'readAccess not supported.', false, true);
+ op += ' for (int i = 0; i < ui_four; i++)\n' +
+ ' res += arr[i];\n';
+ }
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ if (isVertexCase) {
+ vtx += ' v_color = vec4(res${PADDING});\n';
+ frag += ' o_color = v_color;\n';
+ }
+ else {
+ vtx += ' v_coords = a_coords;\n';
+ frag += ' o_color = vec4(res${PADDING});\n';
+ }
+
+ vtx += '}\n';
+ frag += '}\n';
+
+ // Fill in shader templates.
+ /** @type {Object} */ var params = {};
+ params["VAR_TYPE"] = gluShaderUtil.getDataTypeName(varType);
+ params["ARRAY_LEN"] = "4";
+ params["PRECISION"] = "mediump";
+
+ if (varType === gluShaderUtil.DataType.FLOAT)
+ params['PADDING'] = ', 0.0, 0.0, 1.0';
+ else if (varType === gluShaderUtil.DataType.FLOAT_VEC2)
+ params['PADDING'] = ', 0.0, 1.0';
+ else if (varType === gluShaderUtil.DataType.FLOAT_VEC3)
+ params['PADDING'] = ', 1.0';
+ else
+ params['PADDING'] = '';
+
+ /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
+ /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
+
+ /** @type {function(glsShaderRenderCase.ShaderEvalContext)} */
+ var evalFunc = es3fShaderIndexingTests.getArrayCoordsEvalFunc(varType);
+ return new es3fShaderIndexingTests.ShaderIndexingCase(caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource, fragmentShaderSource);
+ };
+
+ // VECTOR SUBSCRIPT.
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptVec2 = function(c) {
+ c.color[0] = c.coords[0] + 0.5 * c.coords[1];
+ c.color[1] = c.coords[0] + 0.5 * c.coords[1];
+ c.color[2] = c.coords[0] + 0.5 * c.coords[1];
+ };
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptVec3 = function(c) {
+ c.color[0] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2];
+ c.color[1] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2];
+ c.color[2] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2];
+ };
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptVec4 = function(c) {
+ c.color[0] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2] + 0.125 * c.coords[3];
+ c.color[1] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2] + 0.125 * c.coords[3];
+ c.color[2] = c.coords[0] + 0.5 * c.coords[1] + 0.25 * c.coords[2] + 0.125 * c.coords[3];
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} dataType
+ * @return {function(glsShaderRenderCase.ShaderEvalContext)}
+ */
+ es3fShaderIndexingTests.getVectorSubscriptEvalFunc = function(dataType) {
+ if (dataType === gluShaderUtil.DataType.FLOAT_VEC2) return es3fShaderIndexingTests.evalSubscriptVec2;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC3) return es3fShaderIndexingTests.evalSubscriptVec3;
+ else if (dataType === gluShaderUtil.DataType.FLOAT_VEC4) return es3fShaderIndexingTests.evalSubscriptVec4;
+ else throw new Error('Invalid data type.');
+ };
+
+ /**
+ * @param {string} caseName
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {gluShaderUtil.DataType} varType
+ * @param {es3fShaderIndexingTests.VectorAccessType} writeAccess
+ * @param {es3fShaderIndexingTests.VectorAccessType} readAccess
+ * @return {es3fShaderIndexingTests.ShaderIndexingCase}
+ */
+ es3fShaderIndexingTests.createVectorSubscriptCase = function(caseName, description, isVertexCase, varType, writeAccess, readAccess) {
+ /** @type {string} */ var vtx = '';
+ /** @type {string} */ var frag = '';
+ /** @type {string} */ var op = '' ;
+
+ /** @type {number} */ var vecLen = gluShaderUtil.getDataTypeScalarSize(varType);
+ /** @type {string} */ var vecLenName = glsShaderRenderCase.getIntUniformName(vecLen);
+
+ vtx += '#version 300 es\n';
+ frag += '#version 300 es\n';
+
+ vtx += 'in highp vec4 a_position;\n' +
+ 'in highp vec4 a_coords;\n';
+ frag += 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ if (isVertexCase) {
+ vtx += 'out mediump vec3 v_color;\n';
+ frag += 'in mediump vec3 v_color;\n';
+ }
+ else {
+ vtx += 'out mediump vec4 v_coords;\n';
+ frag += 'in mediump vec4 v_coords;\n';
+ }
+
+ if (writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC ||
+ readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC){
+ op += 'uniform mediump int ui_zero';
+ if (vecLen >= 2) op += ', ui_one';
+ if (vecLen >= 3) op += ', ui_two';
+ if (vecLen >= 4) op += ', ui_three';
+ op += ';\n';
+ }
+
+ if (writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC_LOOP ||
+ readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC_LOOP)
+ op += 'uniform mediump int ' + vecLenName + ';\n';
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ vtx += '\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n';
+
+ frag += '\n' +
+ 'void main()\n' +
+ '{\n';
+
+ // Write vector.
+ if (isVertexCase)
+ op += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(a_coords);\n';
+ else
+ op += ' ${PRECISION} ${VAR_TYPE} coords = ${VAR_TYPE}(v_coords);\n';
+
+ op += ' ${PRECISION} ${VAR_TYPE} tmp;\n';
+ if (writeAccess === es3fShaderIndexingTests.VectorAccessType.DIRECT)
+ op += ' tmp = coords.${SWIZZLE} * vec4(1.0, 0.5, 0.25, 0.125).${SWIZZLE};\n';
+ else if (writeAccess === es3fShaderIndexingTests.VectorAccessType.COMPONENT) {
+ op += ' tmp.x = coords.x;\n';
+ if (vecLen >= 2) op += ' tmp.y = coords.y * 0.5;\n';
+ if (vecLen >= 3) op += ' tmp.z = coords.z * 0.25;\n';
+ if (vecLen >= 4) op += ' tmp.w = coords.w * 0.125;\n';
+ }
+ else if (writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_STATIC) {
+ op += ' tmp[0] = coords.x;\n';
+ if (vecLen >= 2) op += ' tmp[1] = coords.y * 0.5;\n';
+ if (vecLen >= 3) op += ' tmp[2] = coords.z * 0.25;\n';
+ if (vecLen >= 4) op += ' tmp[3] = coords.w * 0.125;\n';
+ }
+ else if (writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC) {
+ op += ' tmp[ui_zero] = coords.x;\n';
+ if (vecLen >= 2) op += ' tmp[ui_one] = coords.y * 0.5;\n';
+ if (vecLen >= 3) op += ' tmp[ui_two] = coords.z * 0.25;\n';
+ if (vecLen >= 4) op += ' tmp[ui_three] = coords.w * 0.125;\n';
+ }
+ else if (writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_STATIC_LOOP) {
+ op += ' for (int i = 0; i < ' + vecLen + '; i++)\n';
+ op += ' {\n';
+ op += ' tmp[i] = coords.x;\n';
+ op += ' coords = coords.${ROT_SWIZZLE} * 0.5;\n';
+ op += ' }\n';
+ }
+ else {
+ assertMsgOptions(writeAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC_LOOP, 'writeAccess not supported.', false, true);
+ op += ' for (int i = 0; i < ' + vecLenName + '; i++)\n';
+ op += ' {\n';
+ op += ' tmp[i] = coords.x;\n';
+ op += ' coords = coords.${ROT_SWIZZLE} * 0.5;\n';
+ op += ' }\n';
+ }
+
+ // Read vector.
+ op += ' ${PRECISION} float res = 0.0;\n';
+ if (readAccess === es3fShaderIndexingTests.VectorAccessType.DIRECT)
+ op += ' res = dot(tmp, ${VAR_TYPE}(1.0));\n';
+ else if (readAccess === es3fShaderIndexingTests.VectorAccessType.COMPONENT) {
+ op += ' res += tmp.x;\n';
+ if (vecLen >= 2) op += ' res += tmp.y;\n';
+ if (vecLen >= 3) op += ' res += tmp.z;\n';
+ if (vecLen >= 4) op += ' res += tmp.w;\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_STATIC) {
+ op += ' res += tmp[0];\n';
+ if (vecLen >= 2) op += ' res += tmp[1];\n';
+ if (vecLen >= 3) op += ' res += tmp[2];\n';
+ if (vecLen >= 4) op += ' res += tmp[3];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC) {
+ op += ' res += tmp[ui_zero];\n';
+ if (vecLen >= 2) op += ' res += tmp[ui_one];\n';
+ if (vecLen >= 3) op += ' res += tmp[ui_two];\n';
+ if (vecLen >= 4) op += ' res += tmp[ui_three];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_STATIC_LOOP) {
+ op += ' for (int i = 0; i < ' + vecLen + '; i++)\n';
+ op += ' res += tmp[i];\n';
+ }
+ else {
+ assertMsgOptions(readAccess === es3fShaderIndexingTests.VectorAccessType.SUBSCRIPT_DYNAMIC_LOOP, 'readAccess not supported', false, true);
+ op += ' for (int i = 0; i < ' + vecLenName + '; i++)\n';
+ op += ' res += tmp[i];\n';
+ }
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ if (isVertexCase) {
+ vtx += ' v_color = vec3(res);\n';
+ frag += ' o_color = vec4(v_color.rgb, 1.0);\n';
+ }
+ else {
+ vtx += ' v_coords = a_coords;\n';
+ frag += ' o_color = vec4(vec3(res), 1.0);\n';
+ }
+
+ vtx += '}\n';
+ frag += '}\n';
+
+ // Fill in shader templates.
+ /** @type {Array<string>} */ var s_swizzles = ['', 'x', 'xy', 'xyz', 'xyzw'];
+ /** @type {Array<string>} */ var s_rotSwizzles = ['', 'x', 'yx', 'yzx', 'yzwx'];
+
+ /** @type {Object} */ var params = {};
+ params["VAR_TYPE"] = gluShaderUtil.getDataTypeName(varType);
+ params["PRECISION"] = "mediump";
+ params["SWIZZLE"] = s_swizzles[vecLen];
+ params["ROT_SWIZZLE"] = s_rotSwizzles[vecLen];
+
+ /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
+ /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
+
+ /** @type {function(glsShaderRenderCase.ShaderEvalContext)} */
+ var evalFunc = es3fShaderIndexingTests.getVectorSubscriptEvalFunc(varType);
+ return new es3fShaderIndexingTests.ShaderIndexingCase(caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource, fragmentShaderSource);
+ };
+
+ // MATRIX SUBSCRIPT.
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat2 = function(c) {
+ var swizzle01 = deMath.swizzle(c.coords, [0, 1]);
+ var swizzle12 = deMath.swizzle(c.coords, [1, 2]);
+ c.color[0] = swizzle01[0] + 0.5 * swizzle12[0];
+ c.color[1] = swizzle01[1] + 0.5 * swizzle12[1];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat2x3 = function(c) {
+ var swizzle012 = deMath.swizzle(c.coords, [0, 1, 2]);
+ var swizzle123 = deMath.swizzle(c.coords, [1, 2, 3]);
+ c.color[0] = swizzle012[0] + 0.5 * swizzle123[0];
+ c.color[1] = swizzle012[1] + 0.5 * swizzle123[1];
+ c.color[2] = swizzle012[2] + 0.5 * swizzle123[2];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat2x4 = function(c) {
+ c.color = deMath.add(
+ deMath.swizzle(c.coords, [0,1,2,3]),
+ deMath.scale(deMath.swizzle(c.coords, [1,2,3,0]), 0.5));
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat3x2 = function(c) {
+ var swizzle01 = deMath.swizzle(c.coords, [0, 1]);
+ var swizzle12 = deMath.swizzle(c.coords, [1, 2]);
+ var swizzle23 = deMath.swizzle(c.coords, [2, 3]);
+ c.color[0] = swizzle01[0] + 0.5 * swizzle12[0] + 0.25 * swizzle23[0];
+ c.color[1] = swizzle01[1] + 0.5 * swizzle12[1] + 0.25 * swizzle23[1];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat3 = function(c) {
+ var swizzle012 = deMath.swizzle(c.coords, [0, 1, 2]);
+ var swizzle123 = deMath.swizzle(c.coords, [1, 2, 3]);
+ var swizzle230 = deMath.swizzle(c.coords, [2, 3, 0]);
+ c.color[0] = swizzle012[0] + 0.5 * swizzle123[0] + 0.25 * swizzle230[0];
+ c.color[1] = swizzle012[1] + 0.5 * swizzle123[1] + 0.25 * swizzle230[1];
+ c.color[2] = swizzle012[2] + 0.5 * swizzle123[2] + 0.25 * swizzle230[2];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat3x4 = function(c) {
+ var swizzle0123 = deMath.swizzle(c.coords, [0, 1, 2, 3]);
+ var swizzle1230 = deMath.swizzle(c.coords, [1, 2, 3, 0]);
+ var swizzle2301 = deMath.swizzle(c.coords, [2, 3, 0, 1]);
+ c.color = deMath.add(
+ swizzle0123,
+ deMath.add(
+ deMath.scale(swizzle1230, 0.5),
+ deMath.scale(swizzle2301, 0.25)));
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat4x2 = function(c) {
+ var swizzle01 = deMath.swizzle(c.coords, [0, 1]);
+ var swizzle12 = deMath.swizzle(c.coords, [1, 2]);
+ var swizzle23 = deMath.swizzle(c.coords, [2, 3]);
+ var swizzle30 = deMath.swizzle(c.coords, [3, 0]);
+ c.color[0] = swizzle01[0] + 0.5 * swizzle12[0] + 0.25 * swizzle23[0] + 0.125 * swizzle30[0];
+ c.color[1] = swizzle01[1] + 0.5 * swizzle12[1] + 0.25 * swizzle23[1] + 0.125 * swizzle30[1];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat4x3 = function(c) {
+ var swizzle012 = deMath.swizzle(c.coords, [0, 1, 2]);
+ var swizzle123 = deMath.swizzle(c.coords, [1, 2, 3]);
+ var swizzle230 = deMath.swizzle(c.coords, [2, 3, 0]);
+ var swizzle301 = deMath.swizzle(c.coords, [3, 0, 1]);
+ c.color[0] = swizzle012[0] + 0.5 * swizzle123[0] + 0.25 * swizzle230[0] + 0.125 * swizzle301[0];
+ c.color[1] = swizzle012[1] + 0.5 * swizzle123[1] + 0.25 * swizzle230[1] + 0.125 * swizzle301[1];
+ c.color[2] = swizzle012[2] + 0.5 * swizzle123[2] + 0.25 * swizzle230[2] + 0.125 * swizzle301[2];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} c */
+ es3fShaderIndexingTests.evalSubscriptMat4 = function(c) {
+ var swizzle1230 = deMath.swizzle(c.coords, [1, 2, 3, 0]);
+ var swizzle2301 = deMath.swizzle(c.coords, [2, 3, 0, 1]);
+ var swizzle3012 = deMath.swizzle(c.coords, [3, 0, 1, 2]);
+ c.color = deMath.add(
+ c.coords,
+ deMath.add(
+ deMath.scale(swizzle1230, 0.5),
+ deMath.add(
+ deMath.scale(swizzle2301, 0.25),
+ deMath.scale(swizzle3012, 0.125))));
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} dataType
+ * @return {function(glsShaderRenderCase.ShaderEvalContext)}
+ */
+ es3fShaderIndexingTests.getMatrixSubscriptEvalFunc = function(dataType) {
+ switch (dataType) {
+ case gluShaderUtil.DataType.FLOAT_MAT2: return es3fShaderIndexingTests.evalSubscriptMat2;
+ case gluShaderUtil.DataType.FLOAT_MAT2X3: return es3fShaderIndexingTests.evalSubscriptMat2x3;
+ case gluShaderUtil.DataType.FLOAT_MAT2X4: return es3fShaderIndexingTests.evalSubscriptMat2x4;
+ case gluShaderUtil.DataType.FLOAT_MAT3X2: return es3fShaderIndexingTests.evalSubscriptMat3x2;
+ case gluShaderUtil.DataType.FLOAT_MAT3: return es3fShaderIndexingTests.evalSubscriptMat3;
+ case gluShaderUtil.DataType.FLOAT_MAT3X4: return es3fShaderIndexingTests.evalSubscriptMat3x4;
+ case gluShaderUtil.DataType.FLOAT_MAT4X2: return es3fShaderIndexingTests.evalSubscriptMat4x2;
+ case gluShaderUtil.DataType.FLOAT_MAT4X3: return es3fShaderIndexingTests.evalSubscriptMat4x3;
+ case gluShaderUtil.DataType.FLOAT_MAT4: return es3fShaderIndexingTests.evalSubscriptMat4;
+ default:
+ throw new Error('Invalid data type.');
+ }
+ };
+
+ /**
+ * @param {string} caseName
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {gluShaderUtil.DataType} varType
+ * @param {es3fShaderIndexingTests.IndexAccessType} writeAccess
+ * @param {es3fShaderIndexingTests.IndexAccessType} readAccess
+ * @return {es3fShaderIndexingTests.ShaderIndexingCase}
+ */
+ es3fShaderIndexingTests.createMatrixSubscriptCase = function(caseName, description, isVertexCase, varType, writeAccess, readAccess) {
+ /** @type {string} */ var vtx = '';
+ /** @type {string} */ var frag = '';
+ /** @type {string} */ var op = '';
+
+ /** @type {number} */ var numCols = gluShaderUtil.getDataTypeMatrixNumColumns(varType);
+ /** @type {number} */ var numRows = gluShaderUtil.getDataTypeMatrixNumRows(varType);
+ /** @type {string} */ var matSizeName = glsShaderRenderCase.getIntUniformName(numCols);
+ /** @type {gluShaderUtil.DataType} */ var vecType = gluShaderUtil.getDataTypeFloatVec(numRows);
+
+ vtx += '#version 300 es\n';
+ frag += '#version 300 es\n';
+
+ vtx += 'in highp vec4 a_position;\n' +
+ 'in highp vec4 a_coords;\n';
+ frag += 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ if (isVertexCase) {
+ vtx += 'out mediump vec4 v_color;\n';
+ frag += 'in mediump vec4 v_color;\n';
+ }
+ else {
+ vtx += 'out mediump vec4 v_coords;\n';
+ frag += 'in mediump vec4 v_coords;\n';
+ }
+
+ if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC || readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ op += 'uniform mediump int ui_zero';
+ if (numCols >= 2) op += ', ui_one';
+ if (numCols >= 3) op += ', ui_two';
+ if (numCols >= 4) op += ', ui_three';
+ op += ';\n';
+ }
+
+ if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP || readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP)
+ op += 'uniform mediump int ' + matSizeName + ';\n';
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ vtx += '\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n';
+
+ frag += '\n' +
+ 'void main()\n' +
+ '{\n';
+
+ // Write matrix.
+ if (isVertexCase)
+ op += ' ${PRECISION} vec4 coords = a_coords;\n';
+ else
+ op += ' ${PRECISION} vec4 coords = v_coords;\n';
+
+ op += ' ${PRECISION} ${MAT_TYPE} tmp;\n';
+ if (writeAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
+ op += ' tmp[0] = ${VEC_TYPE}(coords);\n';
+ if (numCols >= 2) op += ' tmp[1] = ${VEC_TYPE}(coords.yzwx) * 0.5;\n';
+ if (numCols >= 3) op += ' tmp[2] = ${VEC_TYPE}(coords.zwxy) * 0.25;\n';
+ if (numCols >= 4) op += ' tmp[3] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n';
+ }
+ else if (writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ op += ' tmp[ui_zero] = ${VEC_TYPE}(coords);\n';
+ if (numCols >= 2) op += ' tmp[ui_one] = ${VEC_TYPE}(coords.yzwx) * 0.5;\n';
+ if (numCols >= 3) op += ' tmp[ui_two] = ${VEC_TYPE}(coords.zwxy) * 0.25;\n';
+ if (numCols >= 4) op += ' tmp[ui_three] = ${VEC_TYPE}(coords.wxyz) * 0.125;\n';
+ }
+ else if (writeAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
+ op += ' for (int i = 0; i < ' + numCols + '; i++)\n';
+ op += ' {\n';
+ op += ' tmp[i] = ${VEC_TYPE}(coords);\n';
+ op += ' coords = coords.yzwx * 0.5;\n';
+ op += ' }\n';
+ }
+ else {
+ assertMsgOptions(writeAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'writeAccess not supported', false, true);
+ op += ' for (int i = 0; i < ' + matSizeName + '; i++)\n';
+ op += ' {\n';
+ op += ' tmp[i] = ${VEC_TYPE}(coords);\n';
+ op += ' coords = coords.yzwx * 0.5;\n';
+ op += ' }\n';
+ }
+
+ // Read matrix.
+ op += ' ${PRECISION} ${VEC_TYPE} res = ${VEC_TYPE}(0.0);\n';
+ if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC) {
+ op += ' res += tmp[0];\n';
+ if (numCols >= 2) op += ' res += tmp[1];\n';
+ if (numCols >= 3) op += ' res += tmp[2];\n';
+ if (numCols >= 4) op += ' res += tmp[3];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC) {
+ op += ' res += tmp[ui_zero];\n';
+ if (numCols >= 2) op += ' res += tmp[ui_one];\n';
+ if (numCols >= 3) op += ' res += tmp[ui_two];\n';
+ if (numCols >= 4) op += ' res += tmp[ui_three];\n';
+ }
+ else if (readAccess === es3fShaderIndexingTests.IndexAccessType.STATIC_LOOP) {
+ op += ' for (int i = 0; i < ' + numCols + '; i++)\n';
+ op += ' res += tmp[i];\n';
+ }
+ else {
+ assertMsgOptions(readAccess === es3fShaderIndexingTests.IndexAccessType.DYNAMIC_LOOP, 'readAccess not supported', false, true);
+ op += ' for (int i = 0; i < ' + matSizeName + '; i++)\n';
+ op += ' res += tmp[i];\n';
+ }
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ if (isVertexCase) {
+ vtx += ' v_color = vec4(res${PADDING});\n';
+ frag += ' o_color = v_color;\n';
+ }
+ else {
+ vtx += ' v_coords = a_coords;\n';
+ frag += ' o_color = vec4(res${PADDING});\n';
+ }
+
+ vtx += '}\n';
+ frag += '}\n';
+
+ // Fill in shader templates.
+
+ /** @type {Object} */ var params = {};
+ params['MAT_TYPE'] = gluShaderUtil.getDataTypeName(varType);
+ params['VEC_TYPE'] = gluShaderUtil.getDataTypeName(vecType);
+ params['PRECISION'] = "mediump";
+
+
+ if (numRows === 2)
+ params['PADDING'] = ', 0.0, 1.0';
+ else if (numRows === 3)
+ params['PADDING'] = ', 1.0';
+ else
+ params['PADDING'] = '';
+
+ /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
+ /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
+
+ /** @type {function(glsShaderRenderCase.ShaderEvalContext)} */
+ var evalFunc = es3fShaderIndexingTests.getMatrixSubscriptEvalFunc(varType);
+ return new es3fShaderIndexingTests.ShaderIndexingCase(caseName, description, isVertexCase, varType, evalFunc, vertexShaderSource, fragmentShaderSource);
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderIndexingTests.ShaderIndexingTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'indexing', 'Indexing Tests');
+ };
+
+ es3fShaderIndexingTests.ShaderIndexingTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderIndexingTests.ShaderIndexingTests.prototype.constructor = es3fShaderIndexingTests.ShaderIndexingTests;
+
+ es3fShaderIndexingTests.ShaderIndexingTests.prototype.init = function() {
+ var testGroup = tcuTestCase.runner.testCases;
+ /** @type {Array<gluShaderProgram.shaderType>} */ var s_shaderTypes = [
+ gluShaderProgram.shaderType.VERTEX,
+ gluShaderProgram.shaderType.FRAGMENT
+ ];
+ /** @type {Array<gluShaderUtil.DataType>} */ var s_floatAndVecTypes = [
+ gluShaderUtil.DataType.FLOAT,
+ gluShaderUtil.DataType.FLOAT_VEC2,
+ gluShaderUtil.DataType.FLOAT_VEC3,
+ gluShaderUtil.DataType.FLOAT_VEC4
+ ];
+ /** @type {string} */ var name;
+ /** @type {string} */ var desc;
+ /** @type {string} */ var shaderTypeName;
+ /** @type {boolean} */ var isVertexCase;
+ /** @type {gluShaderProgram.shaderType} */ var shaderType;
+ /** @type {string} */ var writeAccessName;
+ /** @type {string} */ var readAccessName;
+ // Varying array access cases.
+ /** @type {tcuTestCase.DeqpTest} */ var varyingGroup = tcuTestCase.newTest('varying_array', 'Varying array access tests.');
+ testGroup.addChild(varyingGroup);
+ /** @type {gluShaderUtil.DataType} */ var varType;
+ for (var typeNdx = 0; typeNdx < s_floatAndVecTypes.length; typeNdx++) {
+ varType = s_floatAndVecTypes[typeNdx];
+ for (var vertAccessStr in es3fShaderIndexingTests.IndexAccessType) {
+ for (var fragAccessStr in es3fShaderIndexingTests.IndexAccessType) {
+ var vertAccess = es3fShaderIndexingTests.IndexAccessType[vertAccessStr];
+ var fragAccess = es3fShaderIndexingTests.IndexAccessType[fragAccessStr];
+ /** @type {string} */ var vertAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(vertAccess);
+ /** @type {string} */ var fragAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(fragAccess);
+ name = gluShaderUtil.getDataTypeName(varType) + '_' + vertAccessName + '_write_' + fragAccessName + '_read';
+ desc = 'Varying array with ' + vertAccessName + ' write in vertex shader and ' + fragAccessName + ' read in fragment shader.';
+ varyingGroup.addChild(es3fShaderIndexingTests.createVaryingArrayCase(name, desc, varType, vertAccess, fragAccess));
+ }
+ }
+ }
+
+ // Uniform array access cases.
+ /** @type {tcuTestCase.DeqpTest} */ var uniformGroup = tcuTestCase.newTest("uniform_array", "Uniform array access tests.");
+ testGroup.addChild(uniformGroup);
+
+ for (var typeNdx = 0; typeNdx < s_floatAndVecTypes.length; typeNdx++) {
+ varType = s_floatAndVecTypes[typeNdx];
+ for (var readAccessStr in es3fShaderIndexingTests.IndexAccessType) {
+ var readAccess = es3fShaderIndexingTests.IndexAccessType[readAccessStr];
+ readAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(readAccess);
+ for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
+ shaderType = s_shaderTypes[shaderTypeNdx];
+ shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
+ name = gluShaderUtil.getDataTypeName(varType) + "_" + readAccessName + "_read_" + shaderTypeName;
+ desc = "Uniform array with " + readAccessName + " read in " + shaderTypeName + " shader.";
+ isVertexCase = shaderType === gluShaderProgram.shaderType.VERTEX;
+ uniformGroup.addChild(es3fShaderIndexingTests.createUniformArrayCase(name, desc, isVertexCase, varType, readAccess));
+ }
+ }
+ }
+
+ // Temporary array access cases.
+ /** @type {tcuTestCase.DeqpTest} */ var tmpGroup = tcuTestCase.newTest("tmp_array", "Temporary array access tests.");
+ testGroup.addChild(tmpGroup);
+
+ for (var typeNdx = 0; typeNdx < s_floatAndVecTypes.length; typeNdx++) {
+ varType = s_floatAndVecTypes[typeNdx];
+ for (var writeAccess in es3fShaderIndexingTests.IndexAccessType) {
+ for (var readAccess in es3fShaderIndexingTests.IndexAccessType) {
+ writeAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(es3fShaderIndexingTests.IndexAccessType[writeAccess]);
+ readAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(es3fShaderIndexingTests.IndexAccessType[readAccess]);
+
+ for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
+ shaderType = s_shaderTypes[shaderTypeNdx];
+ shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
+ name = gluShaderUtil.getDataTypeName(varType) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
+ desc = "Temporary array with " + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
+ isVertexCase = (shaderType === gluShaderProgram.shaderType.VERTEX);
+ tmpGroup.addChild(es3fShaderIndexingTests.createTmpArrayCase(name, desc, isVertexCase, varType, es3fShaderIndexingTests.IndexAccessType[writeAccess], es3fShaderIndexingTests.IndexAccessType[readAccess]));
+ }
+ }
+ }
+ }
+
+ // Vector indexing with subscripts.
+
+ /** @type {Array<gluShaderUtil.DataType>} */ var s_vectorTypes = [
+ gluShaderUtil.DataType.FLOAT_VEC2,
+ gluShaderUtil.DataType.FLOAT_VEC3,
+ gluShaderUtil.DataType.FLOAT_VEC4
+ ];
+
+ for (var typeNdx = 0; typeNdx < s_vectorTypes.length; typeNdx++) {
+ /** @type {tcuTestCase.DeqpTest} */ var vecGroup = tcuTestCase.newTest("vector_subscript", "Vector subscript indexing.");
+ testGroup.addChild(vecGroup);
+
+ varType = s_vectorTypes[typeNdx];
+ for (var writeAccess in es3fShaderIndexingTests.VectorAccessType) {
+ for (var readAccess in es3fShaderIndexingTests.VectorAccessType) {
+ writeAccessName = es3fShaderIndexingTests.getVectorAccessTypeName(es3fShaderIndexingTests.VectorAccessType[writeAccess]);
+ readAccessName = es3fShaderIndexingTests.getVectorAccessTypeName(es3fShaderIndexingTests.VectorAccessType[readAccess]);
+
+ for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
+ shaderType = s_shaderTypes[shaderTypeNdx];
+ shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
+ name = gluShaderUtil.getDataTypeName(varType) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
+ desc = "Vector subscript access with " + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
+ isVertexCase = shaderType === gluShaderProgram.shaderType.VERTEX;
+ vecGroup.addChild(es3fShaderIndexingTests.createVectorSubscriptCase(name, desc, isVertexCase, varType, es3fShaderIndexingTests.VectorAccessType[writeAccess], es3fShaderIndexingTests.VectorAccessType[readAccess]));
+ }
+ }
+ }
+ }
+
+ // Matrix indexing with subscripts.
+ /** @type {Array<tcuTestCase.DeqpTest>} */ var matGroup = [
+ tcuTestCase.newTest("matrix_subscript", "Matrix subscript indexing."),
+ tcuTestCase.newTest("matrix_subscript", "Matrix subscript indexing."),
+ tcuTestCase.newTest("matrix_subscript", "Matrix subscript indexing."),
+ ];
+ for (var ii = 0; ii < matGroup.length; ++ii) {
+ testGroup.addChild(matGroup[ii]);
+ }
+
+ /** @type {Array<gluShaderUtil.DataType>} */ var s_matrixTypes = [
+ gluShaderUtil.DataType.FLOAT_MAT2,
+ gluShaderUtil.DataType.FLOAT_MAT2X3,
+ gluShaderUtil.DataType.FLOAT_MAT2X4,
+ gluShaderUtil.DataType.FLOAT_MAT3X2,
+ gluShaderUtil.DataType.FLOAT_MAT3,
+ gluShaderUtil.DataType.FLOAT_MAT3X4,
+ gluShaderUtil.DataType.FLOAT_MAT4X2,
+ gluShaderUtil.DataType.FLOAT_MAT4X3,
+ gluShaderUtil.DataType.FLOAT_MAT4
+ ];
+
+ for (var typeNdx = 0; typeNdx < s_matrixTypes.length; typeNdx++) {
+ varType = s_matrixTypes[typeNdx];
+ for (var writeAccess in es3fShaderIndexingTests.IndexAccessType) {
+ for (var readAccess in es3fShaderIndexingTests.IndexAccessType) {
+ writeAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(es3fShaderIndexingTests.IndexAccessType[writeAccess]);
+ readAccessName = es3fShaderIndexingTests.getIndexAccessTypeName(es3fShaderIndexingTests.IndexAccessType[readAccess]);
+
+ for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
+ shaderType = s_shaderTypes[shaderTypeNdx];
+ shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
+ name = gluShaderUtil.getDataTypeName(varType) + "_" + writeAccessName + "_write_" + readAccessName + "_read_" + shaderTypeName;
+ desc = "Vector subscript access with " + writeAccessName + " write and " + readAccessName + " read in " + shaderTypeName + " shader.";
+ isVertexCase = shaderType === gluShaderProgram.shaderType.VERTEX;
+ matGroup[typeNdx % matGroup.length].addChild(es3fShaderIndexingTests.createMatrixSubscriptCase(
+ name, desc, isVertexCase, varType, es3fShaderIndexingTests.IndexAccessType[writeAccess], es3fShaderIndexingTests.IndexAccessType[readAccess]));
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fShaderIndexingTests.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fShaderIndexingTests.ShaderIndexingTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fShaderIndexingTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderLoopTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderLoopTests.js
new file mode 100644
index 0000000000..822b121bda
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderLoopTests.js
@@ -0,0 +1,1251 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fShaderLoopTests');
+goog.require('framework.common.tcuStringTemplate');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('modules.shared.glsShaderRenderCase');
+
+goog.scope(function() {
+var es3fShaderLoopTests = functional.gles3.es3fShaderLoopTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var deMath = framework.delibs.debase.deMath;
+var gluShaderUtil = framework.opengl.gluShaderUtil;
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
+var tcuStringTemplate = framework.common.tcuStringTemplate;
+// Repeated with for, while, do-while. Examples given as 'for' loops.
+// Repeated for const, uniform, dynamic loops.
+
+/**
+ * @enum {number}
+ */
+es3fShaderLoopTests.LoopCase = {
+ LOOPCASE_EMPTY_BODY: 0, // for (...) { }
+ LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST: 1, // for (...) { break; <body>; }
+ LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST: 2, // for (...) { <body>; break; }
+ LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK: 3, // for (...) { <body>; if (cond) break; }
+ LOOPCASE_SINGLE_STATEMENT: 4, // for (...) statement;
+ LOOPCASE_COMPOUND_STATEMENT: 5, // for (...) { statement; statement; }
+ LOOPCASE_SEQUENCE_STATEMENT: 6, // for (...) statement, statement;
+ LOOPCASE_NO_ITERATIONS: 7, // for (i=0; i<0; i++) ...
+ LOOPCASE_SINGLE_ITERATION: 8, // for (i=0; i<1; i++) ...
+ LOOPCASE_SELECT_ITERATION_COUNT: 9, // for (i=0; i<a?b:c; i++) ...
+ LOOPCASE_CONDITIONAL_CONTINUE: 10, // for (...) { if (cond) continue; }
+ LOOPCASE_UNCONDITIONAL_CONTINUE: 11, // for (...) { <body>; continue; }
+ LOOPCASE_ONLY_CONTINUE: 12, // for (...) { continue; }
+ LOOPCASE_DOUBLE_CONTINUE: 13, // for (...) { if (cond) continue; <body>; continue; }
+ LOOPCASE_CONDITIONAL_BREAK: 14, // for (...) { if (cond) break; }
+ LOOPCASE_UNCONDITIONAL_BREAK: 15, // for (...) { <body>; break; }
+ LOOPCASE_PRE_INCREMENT: 16, // for (...; ++i) { <body>; }
+ LOOPCASE_POST_INCREMENT: 17, // for (...; i++) { <body>; }
+ LOOPCASE_MIXED_BREAK_CONTINUE: 18,
+ LOOPCASE_VECTOR_COUNTER: 19, // for (ivec3 ndx = ...; ndx.x < ndx.y; ndx.x += ndx.z) { ... }
+ LOOPCASE_101_ITERATIONS: 20, // loop for 101 iterations
+ LOOPCASE_SEQUENCE: 21, // two loops in sequence
+ LOOPCASE_NESTED: 22, // two nested loops
+ LOOPCASE_NESTED_SEQUENCE: 23, // two loops in sequence nested inside a third
+ LOOPCASE_NESTED_TRICKY_DATAFLOW_1: 24, // nested loops with tricky data flow
+ LOOPCASE_NESTED_TRICKY_DATAFLOW_2: 25 // nested loops with tricky data flow
+};
+
+/**
+ * @param {es3fShaderLoopTests.LoopCase} loopCase
+ * @return {string}
+ */
+es3fShaderLoopTests.getLoopCaseName = function(loopCase) {
+ /** @type {Array<string>} */ var s_names = [
+ 'empty_body',
+ 'infinite_with_unconditional_break_first',
+ 'infinite_with_unconditional_break_last',
+ 'infinite_with_conditional_break',
+ 'single_statement',
+ 'compound_statement',
+ 'sequence_statement',
+ 'no_iterations',
+ 'single_iteration',
+ 'select_iteration_count',
+ 'conditional_continue',
+ 'unconditional_continue',
+ 'only_continue',
+ 'double_continue',
+ 'conditional_break',
+ 'unconditional_break',
+ 'pre_increment',
+ 'post_increment',
+ 'mixed_break_continue',
+ 'vector_counter',
+ '101_iterations',
+ 'sequence',
+ 'nested',
+ 'nested_sequence',
+ 'nested_tricky_dataflow_1',
+ 'nested_tricky_dataflow_2'
+ ];
+ // DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == es3fShaderLoopTests.LoopCase.LOOPCASE_LAST);
+ // DE_ASSERT(deInBounds32((int)loopCase, 0, LOOPCASE_LAST));
+ return s_names[loopCase];
+};
+
+// Complex loop cases.
+
+/*enum LoopBody
+{
+ LOOPBODY_READ_UNIFORM = 0,
+ LOOPBODY_READ_UNIFORM_ARRAY,
+ LOOPBODY_READ_
+};*/
+
+/**
+ * @enum {number}
+ */
+es3fShaderLoopTests.LoopType = {
+ LOOPTYPE_FOR: 0,
+ LOOPTYPE_WHILE: 1,
+ LOOPTYPE_DO_WHILE: 2
+};
+
+/**
+ * @param {es3fShaderLoopTests.LoopType} loopType
+ * @return {string}
+ */
+es3fShaderLoopTests.getLoopTypeName = function(loopType) {
+ /** @type {Array<string>} */ var s_names = [
+ 'for',
+ 'while',
+ 'do_while'
+ ];
+
+ // DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) === es3fShaderLoopTests.LoopType.LOOPTYPE_LAST);
+ // DE_ASSERT(deInBounds32((int)loopType, 0, LOOPTYPE_LAST));
+ return s_names[loopType];
+};
+
+/**
+ * @enum {number}
+ */
+es3fShaderLoopTests.LoopCountType = {
+ LOOPCOUNT_CONSTANT: 0,
+ LOOPCOUNT_UNIFORM: 1,
+ LOOPCOUNT_DYNAMIC: 2
+};
+
+/**
+ * @param {es3fShaderLoopTests.LoopCountType} countType
+ * @return {string}
+ */
+es3fShaderLoopTests.getLoopCountTypeName = function(countType) {
+ /** @type {Array<string>} */ var s_names = [
+ 'constant',
+ 'uniform',
+ 'dynamic'
+ ];
+
+ // DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(s_names) == es3fShaderLoopTests.LoopCountType.LOOPCOUNT_LAST);
+ // DE_ASSERT(deInBounds32((int)countType, 0, es3fShaderLoopTests.LoopCountType.LOOPCOUNT_LAST));
+ return s_names[countType];
+};
+
+/**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ */
+es3fShaderLoopTests.evalLoop0Iters = function(c) {
+ var swizzled = deMath.swizzle(c.coords, [0, 1, 2]);
+ c.color[0] = swizzled[0];
+ c.color[1] = swizzled[1];
+ c.color[2] = swizzled[2];
+};
+
+/**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ */
+es3fShaderLoopTests.evalLoop1Iters = function(c) {
+ var swizzled = deMath.swizzle(c.coords, [1, 2, 3]);
+ c.color[0] = swizzled[0];
+ c.color[1] = swizzled[1];
+ c.color[2] = swizzled[2];
+};
+
+/**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ */
+es3fShaderLoopTests.evalLoop2Iters = function(c) {
+ var swizzled = deMath.swizzle(c.coords, [2, 3, 0]);
+ c.color[0] = swizzled[0];
+ c.color[1] = swizzled[1];
+ c.color[2] = swizzled[2];
+};
+
+/**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ */
+es3fShaderLoopTests.evalLoop3Iters = function(c) {
+ var swizzled = deMath.swizzle(c.coords, [3, 0, 1]);
+ c.color[0] = swizzled[0];
+ c.color[1] = swizzled[1];
+ c.color[2] = swizzled[2];
+};
+
+/**
+ * @param {number} numIters
+ * @return {glsShaderRenderCase.ShaderEvalFunc}
+ */
+es3fShaderLoopTests.getLoopEvalFunc = function(numIters) {
+ switch (numIters % 4) {
+ case 0: return es3fShaderLoopTests.evalLoop0Iters;
+ case 1: return es3fShaderLoopTests.evalLoop1Iters;
+ case 2: return es3fShaderLoopTests.evalLoop2Iters;
+ case 3: return es3fShaderLoopTests.evalLoop3Iters;
+ }
+
+ throw new Error('Invalid loop iteration count.');
+};
+
+// ShaderLoopCase
+
+/**
+ * @constructor
+ * @extends {glsShaderRenderCase.ShaderRenderCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {glsShaderRenderCase.ShaderEvalFunc} evalFunc
+ * @param {string} vertShaderSource
+ * @param {string} fragShaderSource
+ */
+es3fShaderLoopTests.ShaderLoopCase = function(name, description, isVertexCase, evalFunc, vertShaderSource, fragShaderSource) {
+ glsShaderRenderCase.ShaderRenderCase.call(this, name, description, isVertexCase, evalFunc);
+ /** @type {string} */ this.m_vertShaderSource = vertShaderSource;
+ /** @type {string} */ this.m_fragShaderSource = fragShaderSource;
+};
+
+es3fShaderLoopTests.ShaderLoopCase.prototype = Object.create(glsShaderRenderCase.ShaderRenderCase.prototype);
+es3fShaderLoopTests.ShaderLoopCase.prototype.constructor = es3fShaderLoopTests.ShaderLoopCase;
+
+// Test case creation.
+
+/**
+ * @param {string} caseName
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {es3fShaderLoopTests.LoopType} loopType
+ * @param {es3fShaderLoopTests.LoopCountType} loopCountType
+ * @param {gluShaderUtil.precision} loopCountPrecision
+ * @param {gluShaderUtil.DataType} loopCountDataType
+ * @return {es3fShaderLoopTests.ShaderLoopCase}
+ */
+es3fShaderLoopTests.createGenericLoopCase = function(caseName, description, isVertexCase, loopType, loopCountType, loopCountPrecision, loopCountDataType) {
+ /** @type {string} */ var vtx = '';
+ /** @type {string} */ var frag = '';
+ /** @type {string} */ var op = '';
+
+ vtx += '#version 300 es\n';
+ frag += '#version 300 es\n';
+
+ vtx += 'in highp vec4 a_position;\n';
+ vtx += 'in highp vec4 a_coords;\n';
+ frag += 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC)
+ vtx += 'in mediump float a_one;\n';
+
+ if (isVertexCase) {
+ vtx += 'out mediump vec3 v_color;\n';
+ frag += 'in mediump vec3 v_color;\n';
+ }
+ else {
+ vtx += 'out mediump vec4 v_coords;\n';
+ frag += 'in mediump vec4 v_coords;\n';
+
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) {
+ vtx += 'out mediump float v_one;\n';
+ frag += 'in mediump float v_one;\n';
+ }
+ }
+
+ // \todo [petri] Pass numLoopIters from outside?
+ /** @type {number} */ var numLoopIters = 3;
+ /** @type {boolean} */ var isIntCounter = gluShaderUtil.isDataTypeIntOrIVec(loopCountDataType);
+
+ if (isIntCounter) {
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM || loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC)
+ op += 'uniform ${COUNTER_PRECISION} int ' + glsShaderRenderCase.getIntUniformName(numLoopIters) + ';\n';
+ }
+ else {
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM || loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC)
+ op += 'uniform ${COUNTER_PRECISION} float ' + glsShaderRenderCase.getFloatFractionUniformName(numLoopIters) + ';\n';
+
+ if (numLoopIters != 1)
+ op += 'uniform ${COUNTER_PRECISION} float uf_one;\n';
+ }
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ vtx += "\n" +
+ "void main()\n" +
+ "{\n" +
+ " gl_Position = a_position;\n";
+
+ frag += "\n" +
+ "void main()\n" +
+ "{\n";
+
+ if (isVertexCase)
+ vtx += ' ${PRECISION} vec4 coords = a_coords;\n';
+ else
+ frag += ' ${PRECISION} vec4 coords = v_coords;\n';
+
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) {
+ if (isIntCounter) {
+ if (isVertexCase)
+ vtx += ' ${COUNTER_PRECISION} int one = int(a_one + 0.5);\n';
+ else
+ frag += ' ${COUNTER_PRECISION} int one = int(v_one + 0.5);\n';
+ }
+ else {
+ if (isVertexCase)
+ vtx += ' ${COUNTER_PRECISION} float one = a_one;\n';
+ else
+ frag += ' ${COUNTER_PRECISION} float one = v_one;\n';
+ }
+ }
+
+ // Read array.
+ op += ' ${PRECISION} vec4 res = coords;\n';
+
+ // Loop iteration count.
+ /** @type {string} */ var iterMaxStr;
+
+ if (isIntCounter) {
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_CONSTANT)
+ iterMaxStr = numLoopIters.toString();
+ else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM)
+ iterMaxStr = glsShaderRenderCase.getIntUniformName(numLoopIters);
+ else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC)
+ iterMaxStr = glsShaderRenderCase.getIntUniformName(numLoopIters) + '*one';
+ else
+ throw new Error('Loop Count Type not supported: ' + loopCountType);
+ }
+ else {
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_CONSTANT)
+ iterMaxStr = '1.0';
+ else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM)
+ iterMaxStr = 'uf_one';
+ else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC)
+ iterMaxStr = 'uf_one*one';
+ else
+ throw new Error('Loop Count Type not supported: ' + loopCountType);
+ }
+
+ // Loop operations.
+ /** @type {string} */ var initValue = isIntCounter ? '0' : '0.05';
+ /** @type {string} */ var loopCountDeclStr = '' + gluShaderUtil.getPrecisionName(loopCountPrecision) + ' ' + gluShaderUtil.getDataTypeName(loopCountDataType) + ' ndx = ' + initValue;
+ /** @type {string} */ var loopCmpStr = 'ndx < ' + iterMaxStr;
+ /** @type {string} */ var incrementStr;
+
+ if (isIntCounter)
+ incrementStr = 'ndx++';
+ else {
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_CONSTANT)
+ incrementStr = 'ndx += ' + (1.0 / numLoopIters);
+ else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM)
+ incrementStr = 'ndx += ' + glsShaderRenderCase.getFloatFractionUniformName(numLoopIters);
+ else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC)
+ incrementStr = 'ndx += ' + glsShaderRenderCase.getFloatFractionUniformName(numLoopIters) + '*one';
+ else
+ throw new Error('Loop Count Type not supported: ' + loopCountType);
+ }
+
+ // Loop body.
+ /** @type {string} */ var loopBody = ' res = res.yzwx;\n';;
+
+ if (loopType === es3fShaderLoopTests.LoopType.LOOPTYPE_FOR) {
+ op += ' for (' + loopCountDeclStr + '; ' + loopCmpStr + '; ' + incrementStr + ')\n' +
+ ' {\n' +
+ loopBody +
+ ' }\n';
+ }
+ else if (loopType === es3fShaderLoopTests.LoopType.LOOPTYPE_WHILE) {
+ op += '\t' + loopCountDeclStr + ';\n' +
+ ' while (' + loopCmpStr + ')\n' +
+ ' {\n' +
+ loopBody +
+ '\t\t' + incrementStr + ';\n' +
+ ' }\n';
+ }
+ else if (loopType === es3fShaderLoopTests.LoopType.LOOPTYPE_DO_WHILE)
+ {
+ op += '\t' + loopCountDeclStr + ';\n' +
+ ' do\n' +
+ ' {\n' +
+ loopBody +
+ '\t\t' + incrementStr + ';\n' +
+ ' } while (' + loopCmpStr + ');\n';
+ }
+ else
+ throw new Error('Loop Type not supported: ' + loopType);
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ if (isVertexCase) {
+ vtx += ' v_color = res.rgb;\n';
+ frag += ' o_color = vec4(v_color.rgb, 1.0);\n';
+ }
+ else {
+ vtx += ' v_coords = a_coords;\n';
+ frag += ' o_color = vec4(res.rgb, 1.0);\n';
+
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC)
+ vtx += ' v_one = a_one;\n';
+ }
+
+ vtx += '}\n';
+ frag += '}\n';
+
+ // Fill in shader templates.
+ /** @type {Object} */ var params = {};
+ params['LOOP_VAR_TYPE'] = gluShaderUtil.getDataTypeName(loopCountDataType);
+ params['PRECISION'] = 'mediump';
+ params['COUNTER_PRECISION'] = gluShaderUtil.getPrecisionName(loopCountPrecision);
+
+ /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
+ /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
+
+ // Create the case.
+ /** @type {glsShaderRenderCase.ShaderEvalFunc} */
+ var evalFunc = es3fShaderLoopTests.getLoopEvalFunc(numLoopIters);
+ return new es3fShaderLoopTests.ShaderLoopCase(caseName, description, isVertexCase, evalFunc, vertexShaderSource, fragmentShaderSource);
+};
+
+// \todo [petri] Generalize to float as well?
+
+/**
+ * @param {string} caseName
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {es3fShaderLoopTests.LoopCase} loopCase
+ * @param {es3fShaderLoopTests.LoopType} loopType
+ * @param {es3fShaderLoopTests.LoopCountType} loopCountType
+ * @return {es3fShaderLoopTests.ShaderLoopCase}
+ */
+es3fShaderLoopTests.createSpecialLoopCase = function(caseName, description, isVertexCase, loopCase, loopType, loopCountType) {
+ /** @type {string} */ var vtx = '';
+ /** @type {string} */ var frag = '';
+ /** @type {string} */ var op = '';
+
+ vtx += '#version 300 es\n';
+ frag += '#version 300 es\n';
+
+ vtx += 'in highp vec4 a_position;\n';
+ vtx += 'in highp vec4 a_coords;\n';
+ frag += 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC)
+ vtx += 'in mediump float a_one;\n';
+
+ // Attribute and varyings.
+ if (isVertexCase) {
+ vtx += 'out mediump vec3 v_color;\n';
+ frag += 'in mediump vec3 v_color;\n';
+ }
+ else {
+ vtx += 'out mediump vec4 v_coords;\n';
+ frag += 'in mediump vec4 v_coords;\n';
+
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) {
+ vtx += 'out mediump float v_one;\n';
+ frag += 'in mediump float v_one;\n';
+ }
+ }
+
+ if (loopCase === es3fShaderLoopTests.LoopCase.LOOPCASE_SELECT_ITERATION_COUNT)
+ op += 'uniform bool ub_true;\n';
+
+ op += 'uniform ${COUNTER_PRECISION} int ui_zero, ui_one, ui_two, ui_three, ui_four, ui_five, ui_six;\n';
+ if (loopCase === es3fShaderLoopTests.LoopCase.LOOPCASE_101_ITERATIONS)
+ op += 'uniform ${COUNTER_PRECISION} int ui_oneHundredOne;\n';
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ /** @type {number} */ var iterCount = 3; // value to use in loop
+ /** @type {number} */ var numIters = 3; // actual number of iterations
+
+ vtx += '\n' +
+ 'void main()\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n';
+
+ frag += '\n' +
+ 'void main()\n' +
+ '{\n';
+
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) {
+ if (isVertexCase)
+ vtx += ' ${COUNTER_PRECISION} int one = int(a_one + 0.5);\n';
+ else
+ frag += ' ${COUNTER_PRECISION} int one = int(v_one + 0.5);\n';
+ }
+
+ if (isVertexCase)
+ vtx += ' ${PRECISION} vec4 coords = a_coords;\n';
+ else
+ frag += ' ${PRECISION} vec4 coords = v_coords;\n';
+
+ // Read array.
+ op += ' ${PRECISION} vec4 res = coords;\n';
+
+ // Handle all loop types.
+ /** @type {string} */ var counterPrecisionStr = 'mediump';
+ /** @type {string} */ var forLoopStr = '';
+ /** @type {string} */ var whileLoopStr = '';
+ /** @type {string} */ var doWhileLoopPreStr = '';
+ /** @type {string} */ var doWhileLoopPostStr = '';
+
+ if (loopType === es3fShaderLoopTests.LoopType.LOOPTYPE_FOR) {
+ switch (loopCase) {
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_EMPTY_BODY:
+ numIters = 0;
+ op += ' ${FOR_LOOP} {}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST:
+ numIters = 0;
+ op += ' for (;;) { break; res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST:
+ numIters = 1;
+ op += ' for (;;) { res = res.yzwx; break; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK:
+ numIters = 2;
+ op += ' ${COUNTER_PRECISION} int i = 0;\n' +
+ ' for (;;) { res = res.yzwx; if (i == ${ONE}) break; i++; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_SINGLE_STATEMENT:
+ op += ' ${FOR_LOOP} res = res.yzwx;\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_COMPOUND_STATEMENT:
+ iterCount = 2;
+ numIters = 2 * iterCount;
+ op += ' ${FOR_LOOP} { res = res.yzwx; res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_SEQUENCE_STATEMENT:
+ iterCount = 2;
+ numIters = 2 * iterCount;
+ op += ' ${FOR_LOOP} res = res.yzwx, res = res.yzwx;\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_NO_ITERATIONS:
+ iterCount = 0;
+ numIters = 0;
+ op += ' ${FOR_LOOP} res = res.yzwx;\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_SINGLE_ITERATION:
+ iterCount = 1;
+ numIters = 1;
+ op += ' ${FOR_LOOP} res = res.yzwx;\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_SELECT_ITERATION_COUNT:
+ op += ' for (int i = 0; i < (ub_true ? ${ITER_COUNT} : 0); i++) res = res.yzwx;\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_CONDITIONAL_CONTINUE:
+ numIters = iterCount - 1;
+ op += ' ${FOR_LOOP} { if (i == ${TWO}) continue; res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_UNCONDITIONAL_CONTINUE:
+ op += ' ${FOR_LOOP} { res = res.yzwx; continue; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_ONLY_CONTINUE:
+ numIters = 0;
+ op += ' ${FOR_LOOP} { continue; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_DOUBLE_CONTINUE:
+ numIters = iterCount - 1;
+ op += ' ${FOR_LOOP} { if (i == ${TWO}) continue; res = res.yzwx; continue; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_CONDITIONAL_BREAK:
+ numIters = 2;
+ op += ' ${FOR_LOOP} { if (i == ${TWO}) break; res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_UNCONDITIONAL_BREAK:
+ numIters = 1;
+ op += ' ${FOR_LOOP} { res = res.yzwx; break; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_PRE_INCREMENT:
+ op += ' for (int i = 0; i < ${ITER_COUNT}; ++i) { res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_POST_INCREMENT:
+ op += ' ${FOR_LOOP} { res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_MIXED_BREAK_CONTINUE:
+ numIters = 2;
+ iterCount = 5;
+ op += ' ${FOR_LOOP} { if (i == 0) continue; else if (i == 3) break; res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_VECTOR_COUNTER:
+ op += ' for (${COUNTER_PRECISION} ivec4 i = ivec4(0, 1, ${ITER_COUNT}, 0); i.x < i.z; i.x += i.y) { res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_101_ITERATIONS:
+ numIters = iterCount = 101;
+ op += ' ${FOR_LOOP} res = res.yzwx;\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_SEQUENCE:
+ iterCount = 5;
+ numIters = 5;
+ op += ' ${COUNTER_PRECISION} int i;\n' +
+ ' for (i = 0; i < ${TWO}; i++) { res = res.yzwx; }\n' +
+ ' for (; i < ${ITER_COUNT}; i++) { res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED:
+ numIters = 2 * iterCount;
+ op += ' for (${COUNTER_PRECISION} int i = 0; i < ${TWO}; i++)\n' +
+ ' {\n' +
+ ' for (${COUNTER_PRECISION} int j = 0; j < ${ITER_COUNT}; j++)\n' +
+ ' res = res.yzwx;\n' +
+ ' }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_SEQUENCE:
+ numIters = 3 * iterCount;
+ op += ' for (${COUNTER_PRECISION} int i = 0; i < ${ITER_COUNT}; i++)\n' +
+ ' {\n' +
+ ' for (${COUNTER_PRECISION} int j = 0; j < ${TWO}; j++)\n' +
+ ' res = res.yzwx;\n' +
+ ' for (${COUNTER_PRECISION} int j = 0; j < ${ONE}; j++)\n' +
+ ' res = res.yzwx;\n' +
+ ' }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_TRICKY_DATAFLOW_1:
+ numIters = 2;
+ op += ' ${FOR_LOOP}\n' +
+ ' {\n' +
+ ' res = coords; // ignore outer loop effect \n' +
+ ' for (${COUNTER_PRECISION} int j = 0; j < ${TWO}; j++)\n' +
+ ' res = res.yzwx;\n' +
+ ' }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_TRICKY_DATAFLOW_2:
+ numIters = iterCount;
+ op += ' ${FOR_LOOP}\n' +
+ ' {\n' +
+ ' res = coords.wxyz;\n' +
+ ' for (${COUNTER_PRECISION} int j = 0; j < ${TWO}; j++)\n' +
+ ' res = res.yzwx;\n' +
+ ' coords = res;\n' +
+ ' }\n';
+ break;
+
+ default:
+ throw new Error('Case not supported: ' + loopCase);
+ }
+
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_CONSTANT)
+ forLoopStr = 'for (' + counterPrecisionStr + ' int i = 0; i < ' + iterCount + '; i++)';
+ else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM)
+ forLoopStr = 'for (' + counterPrecisionStr + ' int i = 0; i < ' + glsShaderRenderCase.getIntUniformName(iterCount) + '; i++)';
+ else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC)
+ forLoopStr = 'for (' + counterPrecisionStr + ' int i = 0; i < one*' + glsShaderRenderCase.getIntUniformName(iterCount) + '; i++)';
+ else
+ throw new Error('Loop Count Type not supported: ' + loopCountType);
+ }
+ else if (loopType === es3fShaderLoopTests.LoopType.LOOPTYPE_WHILE) {
+ switch (loopCase) {
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_EMPTY_BODY:
+ numIters = 0;
+ op += ' ${WHILE_LOOP} {}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST:
+ numIters = 0;
+ op += ' while (true) { break; res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST:
+ numIters = 1;
+ op += ' while (true) { res = res.yzwx; break; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK:
+ numIters = 2;
+ op += ' ${COUNTER_PRECISION} int i = 0;\n' +
+ ' while (true) { res = res.yzwx; if (i == ${ONE}) break; i++; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_SINGLE_STATEMENT:
+ op += ' ${WHILE_LOOP} res = res.yzwx;\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_COMPOUND_STATEMENT:
+ iterCount = 2;
+ numIters = 2 * iterCount;
+ op += ' ${WHILE_LOOP} { res = res.yzwx; res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_SEQUENCE_STATEMENT:
+ iterCount = 2;
+ numIters = 2 * iterCount;
+ op += ' ${WHILE_LOOP} res = res.yzwx, res = res.yzwx;\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_NO_ITERATIONS:
+ iterCount = 0;
+ numIters = 0;
+ op += ' ${WHILE_LOOP} res = res.yzwx;\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_SINGLE_ITERATION:
+ iterCount = 1;
+ numIters = 1;
+ op += ' ${WHILE_LOOP} res = res.yzwx;\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_SELECT_ITERATION_COUNT:
+ op += ' ${COUNTER_PRECISION} int i = 0;\n' +
+ ' while (i < (ub_true ? ${ITER_COUNT} : 0)) { res = res.yzwx; i++; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_CONDITIONAL_CONTINUE:
+ numIters = iterCount - 1;
+ op += ' ${WHILE_LOOP} { if (i == ${TWO}) continue; res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_UNCONDITIONAL_CONTINUE:
+ op += ' ${WHILE_LOOP} { res = res.yzwx; continue; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_ONLY_CONTINUE:
+ numIters = 0;
+ op += ' ${WHILE_LOOP} { continue; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_DOUBLE_CONTINUE:
+ numIters = iterCount - 1;
+ op += ' ${WHILE_LOOP} { if (i == ${ONE}) continue; res = res.yzwx; continue; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_CONDITIONAL_BREAK:
+ numIters = 2;
+ op += ' ${WHILE_LOOP} { if (i == ${THREE}) break; res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_UNCONDITIONAL_BREAK:
+ numIters = 1;
+ op += ' ${WHILE_LOOP} { res = res.yzwx; break; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_PRE_INCREMENT:
+ numIters = iterCount - 1;
+ op += ' ${COUNTER_PRECISION} int i = 0;\n' +
+ ' while (++i < ${ITER_COUNT}) { res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_POST_INCREMENT:
+ op += ' ${COUNTER_PRECISION} int i = 0;\n' +
+ ' while (i++ < ${ITER_COUNT}) { res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_MIXED_BREAK_CONTINUE:
+ numIters = 2;
+ iterCount = 5;
+ op += ' ${WHILE_LOOP} { if (i == 0) continue; else if (i == 3) break; res = res.yzwx; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_VECTOR_COUNTER:
+ op += ' ${COUNTER_PRECISION} ivec4 i = ivec4(0, 1, ${ITER_COUNT}, 0);\n' +
+ ' while (i.x < i.z) { res = res.yzwx; i.x += i.y; }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_101_ITERATIONS:
+ numIters = iterCount = 101;
+ op += ' ${WHILE_LOOP} res = res.yzwx;\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_SEQUENCE:
+ iterCount = 6;
+ numIters = iterCount - 1;
+ op += ' ${COUNTER_PRECISION} int i = 0;\n' +
+ ' while (i++ < ${TWO}) { res = res.yzwx; }\n' +
+ ' while (i++ < ${ITER_COUNT}) { res = res.yzwx; }\n'; // \note skips one iteration
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED:
+ numIters = 2 * iterCount;
+ op += ' ${COUNTER_PRECISION} int i = 0;\n' +
+ ' while (i++ < ${TWO})\n' +
+ ' {\n' +
+ ' ${COUNTER_PRECISION} int j = 0;\n' +
+ ' while (j++ < ${ITER_COUNT})\n' +
+ ' res = res.yzwx;\n' +
+ ' }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_SEQUENCE:
+ numIters = 2 * iterCount;
+ op += ' ${COUNTER_PRECISION} int i = 0;\n' +
+ ' while (i++ < ${ITER_COUNT})\n' +
+ ' {\n' +
+ ' ${COUNTER_PRECISION} int j = 0;\n' +
+ ' while (j++ < ${ONE})\n' +
+ ' res = res.yzwx;\n' +
+ ' while (j++ < ${THREE})\n' + // \note skips one iteration
+ ' res = res.yzwx;\n' +
+ ' }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_TRICKY_DATAFLOW_1:
+ numIters = 2;
+ op += ' ${WHILE_LOOP}\n' +
+ ' {\n' +
+ ' res = coords; // ignore outer loop effect \n' +
+ ' ${COUNTER_PRECISION} int j = 0;\n' +
+ ' while (j++ < ${TWO})\n' +
+ ' res = res.yzwx;\n' +
+ ' }\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_TRICKY_DATAFLOW_2:
+ numIters = iterCount;
+ op += ' ${WHILE_LOOP}\n' +
+ ' {\n' +
+ ' res = coords.wxyz;\n' +
+ ' ${COUNTER_PRECISION} int j = 0;\n' +
+ ' while (j++ < ${TWO})\n' +
+ ' res = res.yzwx;\n' +
+ ' coords = res;\n' +
+ ' }\n';
+ break;
+
+ default:
+ throw new Error('Loop Case not supported: ' + loopCase);
+ }
+
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_CONSTANT)
+ whileLoopStr = '\t' + counterPrecisionStr + ' int i = 0;\n' + ' while(i++ < ' + iterCount + ')';
+ else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM)
+ whileLoopStr = '\t' + counterPrecisionStr + ' int i = 0;\n' + ' while(i++ < ' + glsShaderRenderCase.getIntUniformName(iterCount) + ')';
+ else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC)
+ whileLoopStr = '\t' + counterPrecisionStr + ' int i = 0;\n' + ' while(i++ < one*' + glsShaderRenderCase.getIntUniformName(iterCount) + ')';
+ else
+ throw new Error('Loop Count Type not supported: ' + loopCountType);
+ }
+ else {
+ assertMsgOptions(loopType === es3fShaderLoopTests.LoopType.LOOPTYPE_DO_WHILE, 'Expected LOOPTYPE_DO_WHILE', false, true);
+
+ switch (loopCase) {
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_EMPTY_BODY:
+ numIters = 0;
+ op += ' ${DO_WHILE_PRE} {} ${DO_WHILE_POST}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_FIRST:
+ numIters = 0;
+ op += ' do { break; res = res.yzwx; } while (true);\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_UNCONDITIONAL_BREAK_LAST:
+ numIters = 1;
+ op += ' do { res = res.yzwx; break; } while (true);\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_INFINITE_WITH_CONDITIONAL_BREAK:
+ numIters = 2;
+ op += ' ${COUNTER_PRECISION} int i = 0;\n' +
+ ' do { res = res.yzwx; if (i == ${ONE}) break; i++; } while (true);\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_SINGLE_STATEMENT:
+ op += ' ${DO_WHILE_PRE} res = res.yzwx; ${DO_WHILE_POST}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_COMPOUND_STATEMENT:
+ iterCount = 2;
+ numIters = 2 * iterCount;
+ op += ' ${DO_WHILE_PRE} { res = res.yzwx; res = res.yzwx; } ${DO_WHILE_POST}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_SEQUENCE_STATEMENT:
+ iterCount = 2;
+ numIters = 2 * iterCount;
+ op += ' ${DO_WHILE_PRE} res = res.yzwx, res = res.yzwx; ${DO_WHILE_POST}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_NO_ITERATIONS:
+ //assertMsgOptions(false, 'LOOPCASE_NO_ITERATIONS', false, false);
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_SINGLE_ITERATION:
+ iterCount = 1;
+ numIters = 1;
+ op += ' ${DO_WHILE_PRE} res = res.yzwx; ${DO_WHILE_POST}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_SELECT_ITERATION_COUNT:
+ op += ' ${COUNTER_PRECISION} int i = 0;\n' +
+ ' do { res = res.yzwx; } while (++i < (ub_true ? ${ITER_COUNT} : 0));\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_CONDITIONAL_CONTINUE:
+ numIters = iterCount - 1;
+ op += ' ${DO_WHILE_PRE} { if (i == ${TWO}) continue; res = res.yzwx; } ${DO_WHILE_POST}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_UNCONDITIONAL_CONTINUE:
+ op += ' ${DO_WHILE_PRE} { res = res.yzwx; continue; } ${DO_WHILE_POST}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_ONLY_CONTINUE:
+ numIters = 0;
+ op += ' ${DO_WHILE_PRE} { continue; } ${DO_WHILE_POST}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_DOUBLE_CONTINUE:
+ numIters = iterCount - 1;
+ op += ' ${DO_WHILE_PRE} { if (i == ${TWO}) continue; res = res.yzwx; continue; } ${DO_WHILE_POST}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_CONDITIONAL_BREAK:
+ numIters = 2;
+ op += ' ${DO_WHILE_PRE} { res = res.yzwx; if (i == ${ONE}) break; } ${DO_WHILE_POST}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_UNCONDITIONAL_BREAK:
+ numIters = 1;
+ op += ' ${DO_WHILE_PRE} { res = res.yzwx; break; } ${DO_WHILE_POST}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_PRE_INCREMENT:
+ op += ' ${COUNTER_PRECISION} int i = 0;\n' +
+ ' do { res = res.yzwx; } while (++i < ${ITER_COUNT});\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_POST_INCREMENT:
+ numIters = iterCount + 1;
+ op += ' ${COUNTER_PRECISION} int i = 0;\n' +
+ ' do { res = res.yzwx; } while (i++ < ${ITER_COUNT});\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_MIXED_BREAK_CONTINUE:
+ numIters = 2;
+ iterCount = 5;
+ op += ' ${DO_WHILE_PRE} { if (i == 0) continue; else if (i == 3) break; res = res.yzwx; } ${DO_WHILE_POST}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_VECTOR_COUNTER:
+ op += ' ${COUNTER_PRECISION} ivec4 i = ivec4(0, 1, ${ITER_COUNT}, 0);\n' +
+ ' do { res = res.yzwx; } while ((i.x += i.y) < i.z);\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_101_ITERATIONS:
+ numIters = iterCount = 101;
+ op += ' ${DO_WHILE_PRE} res = res.yzwx; ${DO_WHILE_POST}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_SEQUENCE:
+ iterCount = 5;
+ numIters = 5;
+ op += ' ${COUNTER_PRECISION} int i = 0;\n' +
+ ' do { res = res.yzwx; } while (++i < ${TWO});\n' +
+ ' do { res = res.yzwx; } while (++i < ${ITER_COUNT});\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED:
+ numIters = 2 * iterCount;
+ op += ' ${COUNTER_PRECISION} int i = 0;\n' +
+ ' do\n' +
+ ' {\n' +
+ ' ${COUNTER_PRECISION} int j = 0;\n' +
+ ' do\n' +
+ ' res = res.yzwx;\n' +
+ ' while (++j < ${ITER_COUNT});\n' +
+ ' } while (++i < ${TWO});\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_SEQUENCE:
+ numIters = 3 * iterCount;
+ op += ' ${COUNTER_PRECISION} int i = 0;\n' +
+ ' do\n' +
+ ' {\n' +
+ ' ${COUNTER_PRECISION} int j = 0;\n' +
+ ' do\n' +
+ ' res = res.yzwx;\n' +
+ ' while (++j < ${TWO});\n' +
+ ' do\n' +
+ ' res = res.yzwx;\n' +
+ ' while (++j < ${THREE});\n' +
+ ' } while (++i < ${ITER_COUNT});\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_TRICKY_DATAFLOW_1:
+ numIters = 2;
+ op += ' ${DO_WHILE_PRE}\n' +
+ ' {\n' +
+ ' res = coords; // ignore outer loop effect \n' +
+ ' ${COUNTER_PRECISION} int j = 0;\n' +
+ ' do\n' +
+ ' res = res.yzwx;\n' +
+ ' while (++j < ${TWO});\n' +
+ ' } ${DO_WHILE_POST}\n';
+ break;
+
+ case es3fShaderLoopTests.LoopCase.LOOPCASE_NESTED_TRICKY_DATAFLOW_2:
+ numIters = iterCount;
+ op += ' ${DO_WHILE_PRE}\n' +
+ ' {\n' +
+ ' res = coords.wxyz;\n' +
+ ' ${COUNTER_PRECISION} int j = 0;\n' +
+ ' while (j++ < ${TWO})\n' +
+ ' res = res.yzwx;\n' +
+ ' coords = res;\n' +
+ ' } ${DO_WHILE_POST}\n';
+ break;
+
+ default:
+ throw new Error('Loop Case not supported: ' + loopCase);
+ }
+
+ doWhileLoopPreStr = '\t' + counterPrecisionStr + ' int i = 0;\n' + '\tdo ';
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_CONSTANT)
+ doWhileLoopPostStr = ' while (++i < ' + iterCount + ');\n';
+ else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM)
+ doWhileLoopPostStr = ' while (++i < ' + glsShaderRenderCase.getIntUniformName(iterCount) + ');\n';
+ else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC)
+ doWhileLoopPostStr = ' while (++i < one*' + glsShaderRenderCase.getIntUniformName(iterCount) + ');\n';
+ else
+ throw new Error('Loop Count Type not supported: ' + loopCountType);
+ }
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ // Shader footers.
+ if (isVertexCase) {
+ vtx += ' v_color = res.rgb;\n';
+ frag += ' o_color = vec4(v_color.rgb, 1.0);\n';
+ }
+ else {
+ vtx += ' v_coords = a_coords;\n';
+ frag += ' o_color = vec4(res.rgb, 1.0);\n';
+
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC)
+ vtx += ' v_one = a_one;\n';
+ }
+
+ vtx += '}\n';
+ frag += '}\n';
+
+ // Constants.
+ /** @type {string} */ var oneStr = '';
+ /** @type {string} */ var twoStr = '';
+ /** @type {string} */ var threeStr = '';
+ /** @type {string} */ var iterCountStr = '';
+
+ if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_CONSTANT) {
+ oneStr = '1';
+ twoStr = '2';
+ threeStr = '3';
+ iterCountStr = iterCount.toString();
+ }
+ else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_UNIFORM) {
+ oneStr = 'ui_one';
+ twoStr = 'ui_two';
+ threeStr = 'ui_three';
+ iterCountStr = glsShaderRenderCase.getIntUniformName(iterCount);
+ }
+ else if (loopCountType === es3fShaderLoopTests.LoopCountType.LOOPCOUNT_DYNAMIC) {
+ oneStr = 'one*ui_one';
+ twoStr = 'one*ui_two';
+ threeStr = 'one*ui_three';
+ iterCountStr = 'one*' + glsShaderRenderCase.getIntUniformName(iterCount);
+ }
+ else throw new Error('Loop Count Type not supported: ' + loopCountType);
+
+ // Fill in shader templates.
+ /** @type {Object} */ var params = {};
+ params["PRECISION"] = "mediump";
+ params["ITER_COUNT"] = iterCountStr;
+ params["COUNTER_PRECISION"] = counterPrecisionStr;
+ params["FOR_LOOP"] = forLoopStr;
+ params["WHILE_LOOP"] = whileLoopStr;
+ params["DO_WHILE_PRE"] = doWhileLoopPreStr;
+ params["DO_WHILE_POST"] = doWhileLoopPostStr;
+ params["ONE"] = oneStr;
+ params["TWO"] = twoStr;
+ params["THREE"] = threeStr;
+
+ /** @type {string} */ var vertexShaderSource = tcuStringTemplate.specialize(vtx, params);
+ /** @type {string} */ var fragmentShaderSource = tcuStringTemplate.specialize(frag, params);
+
+ // Create the case.
+ /** @type {glsShaderRenderCase.ShaderEvalFunc} */
+ var evalFunc = es3fShaderLoopTests.getLoopEvalFunc(numIters);
+ return new es3fShaderLoopTests.ShaderLoopCase(caseName, description, isVertexCase, evalFunc, vertexShaderSource, fragmentShaderSource);
+};
+
+// ShaderLoopTests.
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+es3fShaderLoopTests.ShaderLoopTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'loops', 'Loop Tests');
+};
+
+es3fShaderLoopTests.ShaderLoopTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fShaderLoopTests.ShaderLoopTests.prototype.constructor = es3fShaderLoopTests.ShaderLoopTests;
+
+es3fShaderLoopTests.ShaderLoopTests.prototype.init = function() {
+ var testGroup = tcuTestCase.runner.testCases;
+ // Loop cases.
+
+ /** @type {Array<gluShaderProgram.shaderType>} */ var s_shaderTypes = [
+ gluShaderProgram.shaderType.VERTEX,
+ gluShaderProgram.shaderType.FRAGMENT
+ ];
+
+ /** @type {Array<gluShaderUtil.DataType>} */ var s_countDataType = [
+ gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.FLOAT
+ ];
+
+ /** @type {gluShaderProgram.shaderType} */ var shaderType;
+ /** @type {string} */ var shaderTypeName;
+ /** @type {boolean} */ var isVertexCase;
+ /** @type {string} */ var name;
+ /** @type {string} */ var desc;
+
+ for (var loopType in es3fShaderLoopTests.LoopType) {
+ /** @type {string} */ var loopTypeName = es3fShaderLoopTests.getLoopTypeName(es3fShaderLoopTests.LoopType[loopType]);
+ /** @type {tcuTestCase.DeqpTest} */ var loopTypeGroup = tcuTestCase.newTest(loopTypeName, 'Loop tests with ' + loopTypeName + ' loop type');
+ testGroup.addChild(loopTypeGroup);
+
+ for (var loopCountType in es3fShaderLoopTests.LoopCountType) {
+ /** @type {string} */ var loopCountName = es3fShaderLoopTests.getLoopCountTypeName(es3fShaderLoopTests.LoopCountType[loopCountType]);
+
+ /** @type {string} */ var groupName = loopCountName + '_iterations';
+ /** @type {string} */ var groupDesc = 'Loop tests with ' + loopCountName + ' loop counter.';
+
+ /** @type {tcuTestCase.DeqpTest} */ var group = tcuTestCase.newTest(groupName, groupDesc);
+ loopTypeGroup.addChild(group);
+
+ // Generic cases.
+
+ for (var precision in gluShaderUtil.precision) {
+ /** @type {string} */ var precisionName = gluShaderUtil.getPrecisionName(gluShaderUtil.precision[precision]);
+
+ for (var dataTypeNdx = 0; dataTypeNdx < s_countDataType.length; dataTypeNdx++) {
+ /** @type {gluShaderUtil.DataType} */ var loopDataType = s_countDataType[dataTypeNdx];
+ /** @type {string} */ var dataTypeName = gluShaderUtil.getDataTypeName(loopDataType);
+
+ for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
+ shaderType = s_shaderTypes[shaderTypeNdx];
+ shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
+ isVertexCase = (shaderType == gluShaderProgram.shaderType.VERTEX);
+
+
+ name = 'basic_' + precisionName + '_' + dataTypeName + '_' + shaderTypeName;
+ desc = loopTypeName + ' loop with ' + precisionName + dataTypeName + ' ' + loopCountName + ' iteration count in ' + shaderTypeName + ' shader.';
+ group.addChild(es3fShaderLoopTests.createGenericLoopCase(name, desc, isVertexCase, es3fShaderLoopTests.LoopType[loopType], es3fShaderLoopTests.LoopCountType[loopCountType], gluShaderUtil.precision[precision], loopDataType));
+ }
+ }
+ }
+
+ // Special cases.
+
+ for (var loopCase in es3fShaderLoopTests.LoopCase) {
+ /** @type {string} */ var loopCaseName = es3fShaderLoopTests.getLoopCaseName(es3fShaderLoopTests.LoopCase[loopCase]);
+
+ // no-iterations not possible with do-while.
+ if ((es3fShaderLoopTests.LoopCase[loopCase] == es3fShaderLoopTests.LoopCase.LOOPCASE_NO_ITERATIONS) && (es3fShaderLoopTests.LoopType[loopType] == es3fShaderLoopTests.LoopType.LOOPTYPE_DO_WHILE))
+ continue;
+
+ for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
+ shaderType = s_shaderTypes[shaderTypeNdx];
+ shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
+ isVertexCase = (shaderType == gluShaderProgram.shaderType.VERTEX);
+
+ name = loopCaseName + '_' + shaderTypeName;
+ desc = loopCaseName + ' loop with ' + loopTypeName + ' iteration count in ' + shaderTypeName + ' shader.';
+ group.addChild(es3fShaderLoopTests.createSpecialLoopCase(name, desc, isVertexCase, es3fShaderLoopTests.LoopCase[loopCase], es3fShaderLoopTests.LoopType[loopType], es3fShaderLoopTests.LoopCountType[loopCountType]));
+ }
+ }
+ }
+ }
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fShaderLoopTests.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fShaderLoopTests.ShaderLoopTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+ try {
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fShaderLoopTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderMatrixTest.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderMatrixTest.js
new file mode 100644
index 0000000000..5af21863f5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderMatrixTest.js
@@ -0,0 +1,1852 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+'use strict';
+goog.provide('functional.gles3.es3fShaderMatrixTest');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('modules.shared.glsShaderRenderCase');
+goog.require('framework.common.tcuMatrix');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.common.tcuTestCase');
+
+goog.scope(function() {
+
+ var es3fShaderMatrixTest= functional.gles3.es3fShaderMatrixTest;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
+ var tcuMatrix = framework.common.tcuMatrix;
+ var deMath = framework.delibs.debase.deMath;
+ var tcuTestCase = framework.common.tcuTestCase;
+
+
+ /** @const {Array<number>}*/ var s_constInFloat = [0.5, -0.2];
+ /** @const {Array<Array<number>>}*/ var s_constInVec2 = [[1.2, 0.5], [0.5, 1.0]];
+ /** @const {Array<Array<number>>}*/ var s_constInVec3 = [[1.1, 0.1, 0.5], [-0.2, 0.5, 0.8]];
+ /** @const {Array<Array<number>>}*/ var s_constInVec4 = [[1.4, 0.2, -0.5, 0.7], [0.2, -1.0, 0.5, 0.8]];
+
+ /** @typedef {function(glsShaderRenderCase.ShaderEvalContext)} */ es3fShaderMatrixTest.MatrixShaderEvalFunc;
+
+ /** @const {Array<Array<number>>}*/ var s_constInMat2x2 = [
+ [-0.1, 1.0, -0.2, 0.0],
+ [0.8, 0.1, 0.5, -0.9]
+ ];
+ /** @const {Array<Array<number>>}*/ var s_constInMat3x2 = [
+ [0.8, -0.3, 0.3, 1.0, 1.2, -1.2],
+ [1.2, -1.0, 0.5, -0.8, 1.1, 0.3]
+ ];
+
+ /** @const {Array<Array<number>>}*/ var s_constInMat4x2 = [
+ [-0.2, 0.5, 0.0, -1.0, 1.2, -0.5, 0.3, -0.9],
+ [1.0, 0.1, -1.1, 0.6, 0.8, -1.2, -1.1, 0.7]
+ ];
+
+ /** @const {Array<Array<number>>}*/ var s_constInMat2x3 = [
+ [-0.6, -0.1, -0.7, -1.2, -0.2, 0.0],
+ [1.1, 0.6, 0.8, 1.0, 0.7, 0.1]
+ ];
+
+ /** @const {Array<Array<number>>}*/ var s_constInMat3x3 = [
+ [-0.2, 1.1, 1.2, -1.0, 1.2, 0.5, 0.7, -0.2, 1.0],
+ [-0.1, -0.1, 0.1, -0.1, -0.2, 1.0, -0.5, 0.1, -0.4]
+ ];
+
+ /** @const {Array<Array<number>>}*/ var s_constInMat4x3 = [
+ [-0.9, 0.0, 0.6, 0.2, 0.9, -0.1, -0.3, -0.7, -0.1, 0.1, 1.0, 0.0],
+ [0.5, 0.7, 0.7, 1.2, 1.1, 0.1, 1.0, -1.0, -0.2, -0.2, -0.3, -0.5]
+ ];
+
+ /** @const {Array<Array<number>>}*/ var s_constInMat2x4 = [
+ [-0.6, -1.1, -0.6, -0.6, -0.2, -0.6, -0.1, -0.1],
+ [-1.2, -1.0, 0.7, -1.0, 0.7, 0.7, -0.4, -0.3]
+ ];
+
+ /** @const {Array<Array<number>>}*/ var s_constInMat3x4 = [
+ [0.6, -0.4, 1.2, 0.9, 0.8, 0.4, 1.1, 0.3, 0.5, -0.2, 0.0, 1.1],
+ [-0.8, 1.2, -0.2, -1.1, -0.9, -0.5, -1.2, 1.0, 1.2, 0.1, -0.7, -0.5]
+ ];
+
+ /** @const {Array<Array<number>>}*/ var s_constInMat4x4 = [
+ [0.3, 0.9, -0.2, 1.0, -0.4, -0.6, 0.6, -1.0, -0.9, -0.1, 0.3, -0.2, -0.3, -0.9, 1.0, 0.1],
+ [0.4, -0.7, -0.8, 0.7, -0.4, -0.8, 0.6, -0.3, 0.7, -1.0, 0.1, -0.3, 0.2, 0.6, 0.4, -1.0]
+ ];
+
+ // Operation info
+
+ /**
+ * @enum
+ */
+ es3fShaderMatrixTest.OperationType = {
+ OPERATIONTYPE_BINARY_OPERATOR: 0,
+ OPERATIONTYPE_BINARY_FUNCTION: 1,
+ OPERATIONTYPE_UNARY_PREFIX_OPERATOR: 2,
+ OPERATIONTYPE_UNARY_POSTFIX_OPERATOR: 3,
+ OPERATIONTYPE_UNARY_FUNCTION: 4,
+ OPERATIONTYPE_ASSIGNMENT: 5
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {string}
+ */
+ es3fShaderMatrixTest.getOperationName = function(op) {
+ switch (op) {
+ case es3fShaderMatrixTest.MatrixOp.OP_ADD: return '+';
+ case es3fShaderMatrixTest.MatrixOp.OP_SUB: return '-';
+ case es3fShaderMatrixTest.MatrixOp.OP_MUL: return '*';
+ case es3fShaderMatrixTest.MatrixOp.OP_DIV: return '/';
+ case es3fShaderMatrixTest.MatrixOp.OP_COMP_MUL: return 'matrixCompMult';
+ case es3fShaderMatrixTest.MatrixOp.OP_OUTER_PRODUCT: return 'outerProduct';
+ case es3fShaderMatrixTest.MatrixOp.OP_TRANSPOSE: return 'transpose';
+ case es3fShaderMatrixTest.MatrixOp.OP_INVERSE: return 'inverse';
+ case es3fShaderMatrixTest.MatrixOp.OP_DETERMINANT: return 'determinant';
+ case es3fShaderMatrixTest.MatrixOp.OP_UNARY_PLUS: return '+';
+ case es3fShaderMatrixTest.MatrixOp.OP_NEGATION: return '-';
+ case es3fShaderMatrixTest.MatrixOp.OP_PRE_INCREMENT: return '++';
+ case es3fShaderMatrixTest.MatrixOp.OP_PRE_DECREMENT: return '--';
+ case es3fShaderMatrixTest.MatrixOp.OP_POST_INCREMENT: return '++';
+ case es3fShaderMatrixTest.MatrixOp.OP_POST_DECREMENT: return '--';
+ case es3fShaderMatrixTest.MatrixOp.OP_ADD_INTO: return '+=';
+ case es3fShaderMatrixTest.MatrixOp.OP_SUBTRACT_FROM: return '-=';
+ case es3fShaderMatrixTest.MatrixOp.OP_MULTIPLY_INTO: return '*=';
+ case es3fShaderMatrixTest.MatrixOp.OP_DIVIDE_INTO: return '/=';
+ default:
+ throw new Error('Error invalid Matrix Operation');
+ }
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {es3fShaderMatrixTest.OperationType}
+ */
+ es3fShaderMatrixTest.getOperationType = function (op) {
+ switch (op)
+ {
+ case es3fShaderMatrixTest.MatrixOp.OP_ADD: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_BINARY_OPERATOR;
+ case es3fShaderMatrixTest.MatrixOp.OP_SUB: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_BINARY_OPERATOR;
+ case es3fShaderMatrixTest.MatrixOp.OP_MUL: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_BINARY_OPERATOR;
+ case es3fShaderMatrixTest.MatrixOp.OP_DIV: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_BINARY_OPERATOR;
+ case es3fShaderMatrixTest.MatrixOp.OP_COMP_MUL: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_BINARY_FUNCTION;
+ case es3fShaderMatrixTest.MatrixOp.OP_OUTER_PRODUCT: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_BINARY_FUNCTION;
+ case es3fShaderMatrixTest.MatrixOp.OP_TRANSPOSE: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_UNARY_FUNCTION;
+ case es3fShaderMatrixTest.MatrixOp.OP_INVERSE: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_UNARY_FUNCTION;
+ case es3fShaderMatrixTest.MatrixOp.OP_DETERMINANT: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_UNARY_FUNCTION;
+ case es3fShaderMatrixTest.MatrixOp.OP_UNARY_PLUS: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
+ case es3fShaderMatrixTest.MatrixOp.OP_NEGATION: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
+ case es3fShaderMatrixTest.MatrixOp.OP_PRE_INCREMENT: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
+ case es3fShaderMatrixTest.MatrixOp.OP_PRE_DECREMENT: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_UNARY_PREFIX_OPERATOR;
+ case es3fShaderMatrixTest.MatrixOp.OP_POST_INCREMENT: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_UNARY_POSTFIX_OPERATOR;
+ case es3fShaderMatrixTest.MatrixOp.OP_POST_DECREMENT: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_UNARY_POSTFIX_OPERATOR;
+ case es3fShaderMatrixTest.MatrixOp.OP_ADD_INTO: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_ASSIGNMENT;
+ case es3fShaderMatrixTest.MatrixOp.OP_SUBTRACT_FROM: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_ASSIGNMENT;
+ case es3fShaderMatrixTest.MatrixOp.OP_MULTIPLY_INTO: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_ASSIGNMENT;
+ case es3fShaderMatrixTest.MatrixOp.OP_DIVIDE_INTO: return es3fShaderMatrixTest.OperationType.OPERATIONTYPE_ASSIGNMENT;
+ default:
+ throw new Error('Error invalid Matrix Operation');
+ }
+ };
+
+ /**
+ * @enum
+ */
+ es3fShaderMatrixTest.MatrixType = {
+ TESTMATRIXTYPE_DEFAULT: 0,
+ TESTMATRIXTYPE_NEGATED: 1,
+ TESTMATRIXTYPE_INCREMENTED: 2,
+ TESTMATRIXTYPE_DECREMENTED: 3,
+ TESTMATRIXTYPE_NEGATED_INCREMENTED: 4,
+ TESTMATRIXTYPE_INCREMENTED_LESS: 5
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {es3fShaderMatrixTest.MatrixType}
+ */
+ es3fShaderMatrixTest.getOperationTestMatrixType = function (op) {
+ switch(op) {
+ case es3fShaderMatrixTest.MatrixOp.OP_ADD: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_DEFAULT;
+ case es3fShaderMatrixTest.MatrixOp.OP_SUB: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_DEFAULT;
+ case es3fShaderMatrixTest.MatrixOp.OP_MUL: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_DEFAULT;
+ case es3fShaderMatrixTest.MatrixOp.OP_DIV: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_DEFAULT;
+ case es3fShaderMatrixTest.MatrixOp.OP_COMP_MUL: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_DEFAULT;
+ case es3fShaderMatrixTest.MatrixOp.OP_OUTER_PRODUCT: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_DEFAULT;
+ case es3fShaderMatrixTest.MatrixOp.OP_TRANSPOSE: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_DEFAULT;
+ case es3fShaderMatrixTest.MatrixOp.OP_INVERSE: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_DEFAULT;
+ case es3fShaderMatrixTest.MatrixOp.OP_DETERMINANT: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_DEFAULT;
+ case es3fShaderMatrixTest.MatrixOp.OP_UNARY_PLUS: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_DECREMENTED;
+ case es3fShaderMatrixTest.MatrixOp.OP_NEGATION: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_NEGATED_INCREMENTED;
+ case es3fShaderMatrixTest.MatrixOp.OP_PRE_INCREMENT: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_NEGATED;
+ case es3fShaderMatrixTest.MatrixOp.OP_PRE_DECREMENT: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_INCREMENTED;
+ case es3fShaderMatrixTest.MatrixOp.OP_POST_INCREMENT: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_NEGATED;
+ case es3fShaderMatrixTest.MatrixOp.OP_POST_DECREMENT: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_DEFAULT;
+ case es3fShaderMatrixTest.MatrixOp.OP_ADD_INTO: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_DEFAULT;
+ case es3fShaderMatrixTest.MatrixOp.OP_SUBTRACT_FROM: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_INCREMENTED_LESS;
+ case es3fShaderMatrixTest.MatrixOp.OP_MULTIPLY_INTO: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_NEGATED;
+ case es3fShaderMatrixTest.MatrixOp.OP_DIVIDE_INTO: return es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_DECREMENTED;
+ default:
+ throw new Error('Error invalid Matrix Operation');
+ }
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {boolean}
+ */
+ es3fShaderMatrixTest.isOperationBinary = function (op) {
+ return es3fShaderMatrixTest.getOperationType(op) == es3fShaderMatrixTest.OperationType.OPERATIONTYPE_BINARY_OPERATOR ||
+ es3fShaderMatrixTest.getOperationType(op) == es3fShaderMatrixTest.OperationType.OPERATIONTYPE_BINARY_FUNCTION ||
+ es3fShaderMatrixTest.getOperationType(op) == es3fShaderMatrixTest.OperationType.OPERATIONTYPE_ASSIGNMENT;
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {boolean}
+ */
+ es3fShaderMatrixTest.isOperationMatrixScalar = function (op) {
+ return op == es3fShaderMatrixTest.MatrixOp.OP_ADD ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_SUB ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_MUL ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_DIV;
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {boolean}
+ */
+ es3fShaderMatrixTest.isOperationMatrixVector = function (op) {
+ return op == es3fShaderMatrixTest.MatrixOp.OP_MUL;
+ };
+
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {boolean}
+ */
+ es3fShaderMatrixTest.isOperationArithmeticMatrixMatrix = function (op) {
+ return op == es3fShaderMatrixTest.MatrixOp.OP_MUL;
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {boolean}
+ */
+ es3fShaderMatrixTest.isOperationComponentwiseMatrixMatrix = function (op) {
+ return op == es3fShaderMatrixTest.MatrixOp.OP_ADD ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_SUB ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_MUL ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_DIV ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_COMP_MUL;
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {boolean}
+ */
+ es3fShaderMatrixTest.isOperationVectorVector = function (op) {
+ return op == es3fShaderMatrixTest.MatrixOp.OP_OUTER_PRODUCT;
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {boolean}
+ */
+ es3fShaderMatrixTest.isOperationUnaryAnyMatrix = function (op) {
+ return op == es3fShaderMatrixTest.MatrixOp.OP_TRANSPOSE ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_UNARY_PLUS ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_NEGATION ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_PRE_INCREMENT ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_PRE_DECREMENT ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_POST_INCREMENT ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_POST_DECREMENT;
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {boolean}
+ */
+ es3fShaderMatrixTest.isOperationUnarySymmetricMatrix = function (op) {
+ return op == es3fShaderMatrixTest.MatrixOp.OP_INVERSE ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_DETERMINANT;
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {boolean}
+ */
+ es3fShaderMatrixTest.isOperationValueModifying = function (op) {
+ return op == es3fShaderMatrixTest.MatrixOp.OP_PRE_INCREMENT ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_PRE_DECREMENT ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_POST_INCREMENT ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_POST_DECREMENT;
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {boolean}
+ */
+ es3fShaderMatrixTest.isOperationAssignment = function(op) {
+ return op == es3fShaderMatrixTest.MatrixOp.OP_ADD_INTO ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_SUBTRACT_FROM ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_MULTIPLY_INTO ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_DIVIDE_INTO;
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {boolean}
+ */
+ es3fShaderMatrixTest.isOperationAssignmentAnyMatrix = function(op) {
+ return op == es3fShaderMatrixTest.MatrixOp.OP_ADD_INTO ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_SUBTRACT_FROM ||
+ op == es3fShaderMatrixTest.MatrixOp.OP_DIVIDE_INTO;
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {boolean}
+ */
+ es3fShaderMatrixTest.isOperationAssignmentSymmetricMatrix = function(op) {
+ return op == es3fShaderMatrixTest.MatrixOp.OP_MULTIPLY_INTO;
+ };
+
+ // Operation nature
+
+ /**
+ * @enum
+ */
+ es3fShaderMatrixTest.OperationNature = {
+ OPERATIONNATURE_PURE: 0,
+ OPERATIONNATURE_MUTATING: 1,
+ OPERATIONNATURE_ASSIGNMENT: 2
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @return {es3fShaderMatrixTest.OperationNature}
+ */
+ es3fShaderMatrixTest.getOperationNature = function (op) {
+ if (es3fShaderMatrixTest.isOperationAssignment(op))
+ return es3fShaderMatrixTest.OperationNature.OPERATIONNATURE_ASSIGNMENT;
+ if (es3fShaderMatrixTest.isOperationValueModifying(op))
+ return es3fShaderMatrixTest.OperationNature.OPERATIONNATURE_MUTATING;
+ return es3fShaderMatrixTest.OperationNature.OPERATIONNATURE_PURE;
+ };
+
+ // Input value loader.
+ /**
+ * @param {es3fShaderMatrixTest.InputType} inputType
+ * @param {gluShaderUtil.DataType} typeFormat
+ * @param {glsShaderRenderCase.ShaderEvalContext} evalCtx
+ * @param {number} inputNdx
+ * @return {Array<number>|tcuMatrix.Matrix|number}
+ */
+ es3fShaderMatrixTest.getInputValue = function (inputType, typeFormat, evalCtx, inputNdx) {
+ if (inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_CONST) {
+ switch (typeFormat) {
+ case gluShaderUtil.DataType.FLOAT:
+ return s_constInFloat[inputNdx];
+ case gluShaderUtil.DataType.FLOAT_VEC2:
+ return s_constInVec2[inputNdx];
+ case gluShaderUtil.DataType.FLOAT_VEC3:
+ return s_constInVec3[inputNdx];
+ case gluShaderUtil.DataType.FLOAT_VEC4:
+ return s_constInVec4[inputNdx];
+ case gluShaderUtil.DataType.FLOAT_MAT2:
+ return tcuMatrix.matrixFromDataArray(2, 2, s_constInMat2x2[inputNdx]);
+ case gluShaderUtil.DataType.FLOAT_MAT2X3:
+ return tcuMatrix.matrixFromDataArray(3, 2, s_constInMat2x3[inputNdx]);
+ case gluShaderUtil.DataType.FLOAT_MAT2X4:
+ return tcuMatrix.matrixFromDataArray(4, 2, s_constInMat2x4[inputNdx]);
+ case gluShaderUtil.DataType.FLOAT_MAT3X2:
+ return tcuMatrix.matrixFromDataArray(2, 3, s_constInMat3x2[inputNdx]);
+ case gluShaderUtil.DataType.FLOAT_MAT3:
+ return tcuMatrix.matrixFromDataArray(3, 3, s_constInMat3x3[inputNdx]);
+ case gluShaderUtil.DataType.FLOAT_MAT3X4:
+ return tcuMatrix.matrixFromDataArray(4, 3, s_constInMat3x4[inputNdx]);
+ case gluShaderUtil.DataType.FLOAT_MAT4X2:
+ return tcuMatrix.matrixFromDataArray(2, 4, s_constInMat4x2[inputNdx]);
+ case gluShaderUtil.DataType.FLOAT_MAT4X3:
+ return tcuMatrix.matrixFromDataArray(3, 4, s_constInMat4x3[inputNdx]);
+ case gluShaderUtil.DataType.FLOAT_MAT4:
+ return tcuMatrix.matrixFromDataArray(4, 4, s_constInMat4x4[inputNdx]);
+ }
+ } else if (inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC) {
+ switch (typeFormat) {
+ case gluShaderUtil.DataType.FLOAT:
+ return evalCtx.coords[0];
+ case gluShaderUtil.DataType.FLOAT_VEC2:
+ return deMath.swizzle(evalCtx.coords, [0, 1]);
+ case gluShaderUtil.DataType.FLOAT_VEC3:
+ return deMath.swizzle(evalCtx.coords, [0, 1, 2]);
+ case gluShaderUtil.DataType.FLOAT_VEC4:
+ return deMath.swizzle(evalCtx.coords, [0, 1, 2, 3]);
+ case gluShaderUtil.DataType.FLOAT_MAT2:
+ var m = new tcuMatrix.Matrix(2, 2);
+ m.setCol(0, deMath.swizzle(evalCtx.in_[0], [0, 1]));
+ m.setCol(1, deMath.swizzle(evalCtx.in_[1], [0, 1]));
+ return m;
+ case gluShaderUtil.DataType.FLOAT_MAT2X3:
+ var m = new tcuMatrix.Matrix(3, 2);
+ m.setCol(0, deMath.swizzle(evalCtx.in_[0], [0, 1, 2]));
+ m.setCol(1, deMath.swizzle(evalCtx.in_[1], [0, 1, 2]));
+ return m;
+ case gluShaderUtil.DataType.FLOAT_MAT2X4:
+ var m = new tcuMatrix.Matrix(4, 2);
+ m.setCol(0, deMath.swizzle(evalCtx.in_[0], [0, 1, 2, 3]));
+ m.setCol(1, deMath.swizzle(evalCtx.in_[1], [0, 1, 2, 3]));
+ return m;
+ case gluShaderUtil.DataType.FLOAT_MAT3X2:
+ var m = new tcuMatrix.Matrix(2, 3);
+ m.setCol(0, deMath.swizzle(evalCtx.in_[0], [0, 1]));
+ m.setCol(1, deMath.swizzle(evalCtx.in_[1], [0, 1]));
+ m.setCol(2, deMath.swizzle(evalCtx.in_[2], [0, 1]));
+ return m;
+ case gluShaderUtil.DataType.FLOAT_MAT3:
+ var m = new tcuMatrix.Matrix(3, 3);
+ m.setCol(0, deMath.swizzle(evalCtx.in_[0], [0, 1, 2]));
+ m.setCol(1, deMath.swizzle(evalCtx.in_[1], [0, 1, 2]));
+ m.setCol(2, deMath.swizzle(evalCtx.in_[2], [0, 1, 2]));
+ return m;
+ case gluShaderUtil.DataType.FLOAT_MAT3X4:
+ var m = new tcuMatrix.Matrix(4, 3);
+ m.setCol(0, evalCtx.in_[0]);
+ m.setCol(1, evalCtx.in_[1]);
+ m.setCol(2, evalCtx.in_[2]);
+ return m;
+ case gluShaderUtil.DataType.FLOAT_MAT4X2:
+ var m = new tcuMatrix.Matrix(2, 4);
+ m.setCol(0, deMath.swizzle(evalCtx.in_[0], [0, 1]));
+ m.setCol(1, deMath.swizzle(evalCtx.in_[1], [0, 1]));
+ m.setCol(2, deMath.swizzle(evalCtx.in_[2], [0, 1]));
+ m.setCol(3, deMath.swizzle(evalCtx.in_[3], [0, 1]));
+ return m;
+ case gluShaderUtil.DataType.FLOAT_MAT4X3:
+ var m = new tcuMatrix.Matrix(3, 4);
+ m.setCol(0, deMath.swizzle(evalCtx.in_[0], [0, 1, 2]));
+ m.setCol(1, deMath.swizzle(evalCtx.in_[1], [0, 1, 2]));
+ m.setCol(2, deMath.swizzle(evalCtx.in_[2], [0, 1, 2]));
+ m.setCol(3, deMath.swizzle(evalCtx.in_[3], [0, 1, 2]));
+ return m;
+ case gluShaderUtil.DataType.FLOAT_MAT4:
+ var m = new tcuMatrix.Matrix(4, 4);
+ m.setCol(0, evalCtx.in_[0]);
+ m.setCol(1, evalCtx.in_[1]);
+ m.setCol(2, evalCtx.in_[2]);
+ m.setCol(3, evalCtx.in_[3]);
+ return m;
+ }
+ }
+ throw new Error('Invalid input type');
+ };
+
+ /**
+ * @param {Array<number>} value
+ * @return {Array<number>}
+ */
+ es3fShaderMatrixTest.reduceVecToVec3 = function (value) {
+ if (value.length == 3) {
+ return value;
+ } else if (value.length == 2) {
+ return deMath.swizzle(value, [0, 1, 0])
+ } else {
+ return [value[0], value[1], value[2] + value[3]];
+ }
+ };
+
+ /**
+ * @param {tcuMatrix.Matrix} value
+ * @return {Array<number>}
+ */
+ es3fShaderMatrixTest.reduceMatToVec3 = function (value) {
+ if (value.cols == 2) {
+ if (value.rows == 2) {
+ // mat2
+ return [value.get(0, 0), value.get(0, 1), value.get(1, 0) + value.get(1, 1)];
+ } else if (value.rows == 3){
+ //mat2x3
+ return deMath.add(value.getColumn(0), value.getColumn(1));
+ } else {
+ //mat2x4
+ return deMath.add(deMath.swizzle(value.getColumn(0), [0, 1, 2]), deMath.swizzle(value.getColumn(1), [1, 2, 3]));
+ }
+ } else if (value.cols == 3) {
+ if (value.rows == 2) {
+ return [value.get(0, 0) + value.get(1, 0), value.get(0, 1) + value.get(1, 1), value.get(0, 2) + value.get(1, 2)];
+ } else if (value.rows == 3) {
+ return deMath.add(deMath.add(value.getColumn(0), value.getColumn(1)), value.getColumn(2));
+ } else {
+ return deMath.add(deMath.add(deMath.swizzle(value.getColumn(0), [0, 1, 2]), deMath.swizzle(value.getColumn(1), [1, 2, 3])), deMath.swizzle(value.getColumn(2), [2, 3, 0]))
+ }
+ } else {
+ if (value.rows == 2) {
+ return [value.get(0, 0) + value.get(1, 0) + value.get(0, 3), value.get(0, 1) + value.get(1, 1) + value.get(1, 3), value.get(0, 2) + value.get(1, 2)];
+ } else if (value.rows == 3) {
+ return deMath.add(deMath.add(deMath.add(value.getColumn(0), value.getColumn(1)), value.getColumn(2)), value.getColumn(3));
+ } else {
+ return deMath.add(deMath.add(deMath.add(deMath.swizzle(value.getColumn(0), [0, 1, 2]), deMath.swizzle(value.getColumn(1), [1, 2, 3])), deMath.swizzle(value.getColumn(2), [2, 3, 0])), deMath.swizzle(value.getColumn(3), [3, 0, 1]));
+ }
+ }
+ };
+
+ /**
+ * @param {Array<number>|tcuMatrix.Matrix|number} value
+ * @return {Array<number>}
+ */
+ es3fShaderMatrixTest.reduceToVec3 = function (value) {
+ if (value instanceof tcuMatrix.Matrix)
+ return es3fShaderMatrixTest.reduceMatToVec3(value);
+ else if (value instanceof Array)
+ return es3fShaderMatrixTest.reduceVecToVec3(value);
+ else
+ throw new Error('Impossible case');
+ };
+
+ es3fShaderMatrixTest.add = function (a, b) {
+ if (a instanceof tcuMatrix.Matrix) {
+ if (b instanceof tcuMatrix.Matrix)
+ return tcuMatrix.add(a, b);
+ else if (b instanceof Array)
+ throw new Error('Unimplemented');
+ else
+ return tcuMatrix.addMatScal(a, b);
+ }
+ else {
+ if (b instanceof tcuMatrix.Matrix)
+ throw new Error('Unimplemented');
+ else
+ return deMath.add(a, b);
+ }
+ };
+
+ es3fShaderMatrixTest.subtract = function (a, b) {
+ if (a instanceof tcuMatrix.Matrix) {
+ if (b instanceof tcuMatrix.Matrix)
+ return tcuMatrix.subtract(a, b);
+ else if (b instanceof Array)
+ throw new Error('Unimplemented');
+ else
+ return tcuMatrix.subtractMatScal(a, b);
+ }
+ else {
+ if (b instanceof tcuMatrix.Matrix)
+ throw new Error('Unimplemented');
+ else
+ return deMath.subtract(a, b);
+ }
+ };
+
+ es3fShaderMatrixTest.multiply = function (a, b) {
+ if (a instanceof tcuMatrix.Matrix) {
+ if (b instanceof tcuMatrix.Matrix)
+ return tcuMatrix.multiply(a, b);
+ else if (b instanceof Array)
+ return tcuMatrix.multiplyMatVec(a, b);
+ else
+ return tcuMatrix.multiplyMatScal(a, b);
+ } else {
+ if (b instanceof tcuMatrix.Matrix)
+ return tcuMatrix.multiplyVecMat(a, b);
+ else
+ return deMath.multiply(a, b);
+ }
+ };
+
+ es3fShaderMatrixTest.divide = function (a, b) {
+ if (a instanceof tcuMatrix.Matrix) {
+ if (b instanceof tcuMatrix.Matrix)
+ return tcuMatrix.divide(a, b);
+ else if (b instanceof Array)
+ throw new Error('Unimplemented');
+ else
+ return tcuMatrix.divideMatScal(a, b);
+ }
+ else {
+ if (b instanceof tcuMatrix.Matrix)
+ throw new Error('Unimplemented');
+ else
+ return deMath.divide(a, b);
+ }
+ };
+
+
+ /**
+ * @param {tcuMatrix.Matrix} a
+ * @param {tcuMatrix.Matrix} b
+ * @return {tcuMatrix.Matrix}
+ */
+ es3fShaderMatrixTest.matrixCompMult = function (a, b) {
+ /** @type {tcuMatrix.Matrix} */ var retVal = new tcuMatrix.Matrix(a.rows, a.cols);
+
+ for (var r = 0; r < a.rows; ++r) {
+ for (var c = 0; c < a.cols; ++c) {
+ retVal.set(r, c, a.get(r, c) * b.get(r, c));
+ }
+ }
+ return retVal;
+ };
+
+ /**
+ * @param {tcuMatrix.Matrix} mat
+ * @return {tcuMatrix.Matrix}
+ */
+ es3fShaderMatrixTest.transpose = function (mat) {
+ /** @type {tcuMatrix.Matrix} */ var retVal = new tcuMatrix.Matrix(mat.cols, mat.rows);
+
+ for (var r = 0; r < mat.rows; ++r) {
+ for (var c = 0; c < mat.cols; ++c) {
+ retVal.set(c, r, mat.get(r, c));
+ }
+ }
+
+ return retVal;
+ };
+
+ /**
+ * @param {tcuMatrix.Matrix} mat
+ * @return {number}
+ */
+ es3fShaderMatrixTest.determinantMat2 = function (mat) {
+ return mat.get(0, 0) * mat.get(1, 1) - mat.get(1, 0) * mat.get(0,1);
+ };
+
+ /**
+ * @param {tcuMatrix.Matrix} mat
+ * @return {number}
+ */
+ es3fShaderMatrixTest.determinantMat3 = function (mat) {
+ return + mat.get(0, 0) * mat.get(1, 1) * mat.get(2, 2)
+ + mat.get(0, 1) * mat.get(1, 2) * mat.get(2, 0)
+ + mat.get(0, 2) * mat.get(1, 0) * mat.get(2, 1)
+ - mat.get(0, 0) * mat.get(1, 2) * mat.get(2, 1)
+ - mat.get(0, 1) * mat.get(1, 0) * mat.get(2, 2)
+ - mat.get(0, 2) * mat.get(1, 1) * mat.get(2, 0);
+ };
+
+ /**
+ * @param {tcuMatrix.Matrix} mat
+ * @return {number}
+ */
+ es3fShaderMatrixTest.determinantMat4 = function (mat) {
+ /** @type {Array<Array<number>>} */ var minorMatrices = [
+ [
+ mat.get(1, 1), mat.get(2, 1), mat.get(3, 1),
+ mat.get(1, 2), mat.get(2, 2), mat.get(3, 2),
+ mat.get(1, 3), mat.get(2, 3), mat.get(3, 3)
+ ],
+ [
+ mat.get(1, 0), mat.get(2, 0), mat.get(3, 0),
+ mat.get(1, 2), mat.get(2, 2), mat.get(3, 2),
+ mat.get(1, 3), mat.get(2, 3), mat.get(3, 3)
+ ],
+ [
+ mat.get(1, 0), mat.get(2, 0), mat.get(3, 0),
+ mat.get(1, 1), mat.get(2, 1), mat.get(3, 1),
+ mat.get(1, 3), mat.get(2, 3), mat.get(3, 3)
+ ],
+ [
+ mat.get(1, 0), mat.get(2, 0), mat.get(3, 0),
+ mat.get(1, 1), mat.get(2, 1), mat.get(3, 1),
+ mat.get(1, 2), mat.get(2, 2), mat.get(3, 2)
+ ]
+ ];
+
+ return + mat.get(0, 0) * es3fShaderMatrixTest.determinant(tcuMatrix.matrixFromDataArray(3, 3, minorMatrices[0]))
+ - mat.get(0, 1) * es3fShaderMatrixTest.determinant(tcuMatrix.matrixFromDataArray(3, 3, minorMatrices[1]))
+ + mat.get(0, 2) * es3fShaderMatrixTest.determinant(tcuMatrix.matrixFromDataArray(3, 3, minorMatrices[2]))
+ - mat.get(0, 3) * es3fShaderMatrixTest.determinant(tcuMatrix.matrixFromDataArray(3, 3, minorMatrices[3]));
+ };
+
+ /**
+ * @param {tcuMatrix.Matrix} mat
+ * @return {number}
+ */
+ es3fShaderMatrixTest.determinant = function (mat) {
+ if (mat.rows == 2) {
+ return es3fShaderMatrixTest.determinantMat2(mat);
+ } else if (mat.rows == 3) {
+ return es3fShaderMatrixTest.determinantMat3(mat);
+ } else {
+ return es3fShaderMatrixTest.determinantMat4(mat);
+ }
+ };
+
+ /**
+ * @param {tcuMatrix.Matrix} mat
+ * @return {tcuMatrix.Matrix}
+ */
+ es3fShaderMatrixTest.inverseMat2 = function (mat) {
+ /** @type {number} */ var det = es3fShaderMatrixTest.determinant(mat);
+ /** @type {tcuMatrix.Matrix} */ var retVal = new tcuMatrix.Mat2();
+
+ if (det == 0.0) {
+ throw new Error('Wrong determinant')
+ }
+
+ retVal.set(0, 0, mat.get(1, 1) / det);
+ retVal.set(0, 1, -mat.get(0, 1) / det);
+ retVal.set(1, 0, -mat.get(1, 0) / det);
+ retVal.set(1, 1, mat.get(0, 0) / det);
+
+ return retVal;
+ };
+
+ /**
+ * @param {tcuMatrix.Matrix} mat
+ * @return {tcuMatrix.Matrix}
+ */
+ es3fShaderMatrixTest.inverseMat3 = function (mat) {
+ if (es3fShaderMatrixTest.determinant(mat) == 0.0) {
+ throw new Error('Wrong determinant')
+ }
+
+ /** @type {Array<number>} */ var areaA = [mat.get(0, 0), mat.get(0, 1), mat.get(1, 0), mat.get(1,1)];
+ /** @type {Array<number>} */ var areaB = [mat.get(0, 2), mat.get(1, 2)];
+ /** @type {Array<number>} */ var areaC = [mat.get(2, 0), mat.get(2, 1)];
+ /** @type {Array<number>} */ var areaD = [mat.get(2,2)];
+
+ /** @type {tcuMatrix.Matrix} */ var invA = es3fShaderMatrixTest.inverse(tcuMatrix.matrixFromDataArray(2, 2, areaA));
+ /** @type {tcuMatrix.Matrix} */ var matB = tcuMatrix.matrixFromDataArray(2, 1, areaB);
+ /** @type {tcuMatrix.Matrix} */ var matC = tcuMatrix.matrixFromDataArray(1, 2, areaC);
+ /** @type {tcuMatrix.Matrix} */ var matD = tcuMatrix.matrixFromDataArray(1, 1, areaD);
+
+ /** @type {tcuMatrix.Matrix} */ var tmp = tcuMatrix.subtract(matD, tcuMatrix.multiply(matC, tcuMatrix.multiply(invA, matB)));
+ /** @type {number} */ var schurComplement = 1.0 / tmp.get(0, 0);
+ /** @type {tcuMatrix.Matrix} */ var zeroMat = new tcuMatrix.Matrix(2, 2, 0);
+
+ /** @type {tcuMatrix.Matrix} */ var blockA = tcuMatrix.add(invA, tcuMatrix.multiply(tcuMatrix.multiply(invA, tcuMatrix.multiply(tcuMatrix.multiplyMatScal(matB, schurComplement), matC)), invA));
+ /** @type {tcuMatrix.Matrix} */ var blockB = tcuMatrix.multiplyMatScal(tcuMatrix.multiply(tcuMatrix.subtract(zeroMat, invA), matB), schurComplement);
+ /** @type {tcuMatrix.Matrix} */ var blockC = tcuMatrix.multiply(matC, tcuMatrix.multiplyMatScal(invA, - schurComplement));
+ /** @type {number} */ var blockD = schurComplement;
+
+ /** @type {Array<number>} */ var result = [
+ blockA.get(0, 0), blockA.get(0, 1), blockB.get(0, 0),
+ blockA.get(1, 0), blockA.get(1, 1), blockB.get(1, 0),
+ blockC.get(0, 0), blockC.get(0, 1), blockD
+ ];
+
+ return tcuMatrix.matrixFromDataArray(3, 3, result);
+ }
+
+ /**
+ * @param {tcuMatrix.Matrix} mat
+ * @return {tcuMatrix.Matrix}
+ */
+ es3fShaderMatrixTest.inverseMat4 = function (mat) {
+ // Blockwise inversion
+ if (es3fShaderMatrixTest.determinant(mat) == 0.0) {
+ throw new Error('Wrong determinant')
+ }
+
+ /** @type {Array<number>} */ var areaA = [
+ mat.get(0, 0), mat.get(0, 1),
+ mat.get(1, 0), mat.get(1, 1)
+ ];
+ /** @type {Array<number>} */ var areaB = [
+ mat.get(0, 2), mat.get(0, 3),
+ mat.get(1, 2), mat.get(1, 3)
+ ];
+ /** @type {Array<number>} */ var areaC = [
+ mat.get(2, 0), mat.get(2, 1),
+ mat.get(3, 0), mat.get(3, 1)
+ ];
+ /** @type {Array<number>} */ var areaD = [
+ mat.get(2, 2), mat.get(2, 3),
+ mat.get(3, 2), mat.get(3, 3)
+ ];
+
+ /** @type {tcuMatrix.Matrix} */ var invA = es3fShaderMatrixTest.inverse(tcuMatrix.matrixFromDataArray(2, 2, areaA));
+ /** @type {tcuMatrix.Matrix} */ var matB = tcuMatrix.matrixFromDataArray(2, 2, areaB);
+ /** @type {tcuMatrix.Matrix} */ var matC = tcuMatrix.matrixFromDataArray(2, 2, areaC);
+ /** @type {tcuMatrix.Matrix} */ var matD = tcuMatrix.matrixFromDataArray(2, 2, areaD);
+
+ /** @type {tcuMatrix.Matrix} */ var schurComplement = es3fShaderMatrixTest.inverse(tcuMatrix.subtract(matD, (tcuMatrix.multiply(matC, tcuMatrix.multiply(invA, matB)))));
+ /** @type {tcuMatrix.Matrix} */ var zeroMat = new tcuMatrix.Matrix(2, 2, 0);
+
+ /** @type {tcuMatrix.Matrix} */ var blockA = tcuMatrix.add(invA, tcuMatrix.multiply(tcuMatrix.multiply(tcuMatrix.multiply(tcuMatrix.multiply(invA, matB), schurComplement), matC), invA));
+ /** @type {tcuMatrix.Matrix} */ var blockB = tcuMatrix.multiply(tcuMatrix.multiply(tcuMatrix.subtract(zeroMat, invA), matB), schurComplement);
+ /** @type {tcuMatrix.Matrix} */ var blockC = tcuMatrix.multiply(tcuMatrix.multiply(tcuMatrix.subtract(zeroMat, schurComplement),matC), invA);
+ /** @type {tcuMatrix.Matrix} */ var blockD = schurComplement;
+
+ /** @type {Array<number>} */ var result = [
+ blockA.get(0, 0), blockA.get(0, 1), blockB.get(0, 0), blockB.get(0, 1),
+ blockA.get(1, 0), blockA.get(1, 1), blockB.get(1, 0), blockB.get(1, 1),
+ blockC.get(0, 0), blockC.get(0, 1), blockD.get(0, 0), blockD.get(0, 1),
+ blockC.get(1, 0), blockC.get(1, 1), blockD.get(1, 0), blockD.get(1, 1)
+ ];
+
+ return tcuMatrix.matrixFromDataArray(4, 4, result);
+ };
+
+ /**
+ * @param {tcuMatrix.Matrix} mat
+ * @return {tcuMatrix.Matrix}
+ */
+ es3fShaderMatrixTest.inverse = function (mat) {
+ if (mat.cols == 2) {
+ return es3fShaderMatrixTest.inverseMat2(mat)
+ } else if (mat.cols == 3) {
+ return es3fShaderMatrixTest.inverseMat3(mat)
+ } else {
+ return es3fShaderMatrixTest.inverseMat4(mat)
+ }
+ };
+
+ /**
+ * @param {tcuMatrix.Matrix} mat
+ * @return {tcuMatrix.Matrix}
+ */
+ es3fShaderMatrixTest.negate = function (mat) {
+ /** @type {tcuMatrix.Matrix} */ var retVal = new tcuMatrix.Matrix(mat.rows, mat.cols);
+
+ for (var r = 0; r < mat.rows; ++r)
+ for (var c = 0; c < mat.cols; ++c)
+ retVal.set(r,c, -mat.get(r, c));
+
+ return retVal;
+ };
+
+ /**
+ * @param {tcuMatrix.Matrix} mat
+ * @return {tcuMatrix.Matrix}
+ */
+ es3fShaderMatrixTest.increment = function (mat) {
+ /** @type {tcuMatrix.Matrix} */ var retVal = new tcuMatrix.Matrix(mat.rows, mat.cols);
+
+ for (var r = 0; r < mat.rows; ++r)
+ for (var c = 0; c < mat.cols; ++c)
+ retVal.set(r,c, mat.get(r, c) + 1.0);
+
+ return retVal;
+ };
+
+ /**
+ * @param {tcuMatrix.Matrix} mat
+ * @return {tcuMatrix.Matrix}
+ */
+ es3fShaderMatrixTest.decrement = function (mat) {
+ /** @type {tcuMatrix.Matrix} */ var retVal = new tcuMatrix.Matrix(mat.rows, mat.cols);
+
+ for (var r = 0; r < mat.rows; ++r)
+ for (var c = 0; c < mat.cols; ++c)
+ retVal.set(r,c, mat.get(r, c) - 1.0);
+
+ return retVal;
+ };
+
+ /**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @return {tcuMatrix.Matrix}
+ */
+ es3fShaderMatrixTest.outerProduct = function (a, b) {
+ /** @type {tcuMatrix.Matrix} */ var retVal = new tcuMatrix.Matrix(b.length, a.length);
+
+ for (var r = 0; r < b.length; ++r) {
+ for (var c = 0; c < a.length; ++c) {
+ retVal.set(r, c, a[c] * b[r]);
+ }
+ }
+
+ return es3fShaderMatrixTest.transpose(retVal);
+ };
+
+ /**
+ * @enum
+ */
+ es3fShaderMatrixTest.InputType = {
+ INPUTTYPE_CONST: 0,
+ INPUTTYPE_UNIFORM: 1,
+ INPUTTYPE_DYNAMIC: 2
+ };
+
+ /**
+ * @enum
+ */
+ es3fShaderMatrixTest.MatrixOp = {
+ OP_ADD: 0,
+ OP_SUB: 1,
+ OP_MUL: 2,
+ OP_DIV: 3,
+ OP_COMP_MUL: 4,
+ OP_OUTER_PRODUCT: 5,
+ OP_TRANSPOSE: 6,
+ OP_INVERSE: 7,
+ OP_DETERMINANT: 8,
+ OP_UNARY_PLUS: 9,
+ OP_NEGATION: 10,
+ OP_PRE_INCREMENT: 11,
+ OP_PRE_DECREMENT: 12,
+ OP_POST_INCREMENT: 13,
+ OP_POST_DECREMENT: 14,
+ OP_ADD_INTO: 15,
+ OP_SUBTRACT_FROM: 16,
+ OP_MULTIPLY_INTO: 17,
+ OP_DIVIDE_INTO: 18,
+ OP_LAST: 19
+ };
+
+ /**
+ * @constructor
+ * @param {es3fShaderMatrixTest.InputType=} inputType_
+ * @param {gluShaderUtil.DataType=} dataType_
+ * @param {gluShaderUtil.precision=} precision_
+ * @struct
+ */
+ es3fShaderMatrixTest.ShaderInput = function (inputType_, dataType_, precision_){
+ this.inputType = inputType_ || es3fShaderMatrixTest.InputType.INPUTTYPE_CONST;
+ this.dataType = dataType_ || gluShaderUtil.DataType.INVALID;
+ this.precision = precision_ || gluShaderUtil.precision.PRECISION_LOWP;
+ };
+
+ /**
+ * @param {es3fShaderMatrixTest.ShaderInput} in0
+ * @param {es3fShaderMatrixTest.ShaderInput} in1
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ */
+ es3fShaderMatrixTest.getEvalFunc = function (in0, in1, op) {
+ var setColor = function(evalCtx, src) {
+ for (var i = 0; i < 3; i++)
+ evalCtx.color[i] = src[i];
+ };
+ switch(op){
+ case es3fShaderMatrixTest.MatrixOp.OP_ADD:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+ var in1_ = in1.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in1.inputType, in1.dataType, evalCtx, 1)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in1.dataType, evalCtx, 1);
+
+ setColor(evalCtx, es3fShaderMatrixTest.reduceToVec3(es3fShaderMatrixTest.add(in0_, in1_)));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_SUB:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+ var in1_ = in1.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in1.inputType, in1.dataType, evalCtx, 1)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in1.dataType, evalCtx, 1);
+
+ setColor(evalCtx, es3fShaderMatrixTest.reduceToVec3(es3fShaderMatrixTest.subtract(in0_, in1_)));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_MUL:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+ var in1_ = in1.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in1.inputType, in1.dataType, evalCtx, 1)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in1.dataType, evalCtx, 1);
+
+ setColor(evalCtx, es3fShaderMatrixTest.reduceToVec3(es3fShaderMatrixTest.multiply(in0_, in1_)));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_DIV:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+ var in1_ = in1.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in1.inputType, in1.dataType, evalCtx, 1)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in1.dataType, evalCtx, 1);
+
+ setColor(evalCtx, es3fShaderMatrixTest.reduceToVec3(es3fShaderMatrixTest.divide(in0_, in1_)));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_COMP_MUL:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+ var in1_ = in1.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in1.inputType, in1.dataType, evalCtx, 1)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in1.dataType, evalCtx, 1);
+
+ setColor(evalCtx, es3fShaderMatrixTest.reduceToVec3(es3fShaderMatrixTest.matrixCompMult(/** @type {tcuMatrix.Matrix} */(in0_), /** @type {tcuMatrix.Matrix} */(in1_))));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_OUTER_PRODUCT:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+ var in1_ = in1.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in1.inputType, in1.dataType, evalCtx, 1)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in1.dataType, evalCtx, 1);
+
+ setColor(evalCtx, es3fShaderMatrixTest.reduceToVec3(es3fShaderMatrixTest.outerProduct(/** @type {Array<number>} */(in0_), /** @type {Array<number>} */(in1_))));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_TRANSPOSE:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+
+ setColor(evalCtx, es3fShaderMatrixTest.reduceToVec3(es3fShaderMatrixTest.transpose(/** @type {tcuMatrix.Matrix} */(in0_))));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_INVERSE:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+
+ setColor(evalCtx, es3fShaderMatrixTest.reduceToVec3(es3fShaderMatrixTest.inverse(/** @type {tcuMatrix.Matrix} */(in0_))));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_DETERMINANT:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+
+ var det = es3fShaderMatrixTest.determinant(/** @type {tcuMatrix.Matrix} */(in0_));
+ setColor(evalCtx, [det, det, det]);
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_UNARY_PLUS:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+
+ setColor(evalCtx, es3fShaderMatrixTest.reduceToVec3(/** @type {tcuMatrix.Matrix} */(in0_)));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_NEGATION:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+
+ setColor(evalCtx, es3fShaderMatrixTest.reduceToVec3(es3fShaderMatrixTest.negate(/** @type {tcuMatrix.Matrix} */(in0_))));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_PRE_INCREMENT:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+
+ var val0 = es3fShaderMatrixTest.reduceToVec3(es3fShaderMatrixTest.increment(/** @type {tcuMatrix.Matrix} */(in0_)));
+ var val1 = es3fShaderMatrixTest.reduceToVec3(es3fShaderMatrixTest.increment(/** @type {tcuMatrix.Matrix} */(in0_)));
+ setColor(evalCtx, deMath.add(val0, val1));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_PRE_DECREMENT:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+
+ var val0 = es3fShaderMatrixTest.reduceToVec3(es3fShaderMatrixTest.decrement(/** @type {tcuMatrix.Matrix} */(in0_)));
+ var val1 = es3fShaderMatrixTest.reduceToVec3(es3fShaderMatrixTest.decrement(/** @type {tcuMatrix.Matrix} */(in0_)));
+ setColor(evalCtx, deMath.add(val0, val1));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_POST_INCREMENT:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+
+ var val0 = es3fShaderMatrixTest.reduceToVec3((in0_));
+ var val1 = es3fShaderMatrixTest.reduceToVec3(es3fShaderMatrixTest.increment(/** @type {tcuMatrix.Matrix} */(in0_)));
+ setColor(evalCtx, deMath.add(val0, val1));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_POST_DECREMENT:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+
+ var val0 = es3fShaderMatrixTest.reduceToVec3((in0_));
+ var val1 = es3fShaderMatrixTest.reduceToVec3(es3fShaderMatrixTest.decrement(/** @type {tcuMatrix.Matrix} */(in0_)));
+ setColor(evalCtx, deMath.add(val0, val1));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_ADD_INTO:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+ var in1_ = in1.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in1.inputType, in0.dataType, evalCtx, 1)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in1.dataType, evalCtx, 1);
+
+ setColor(evalCtx, es3fShaderMatrixTest.reduceToVec3(tcuMatrix.add(/** @type {tcuMatrix.Matrix} */(in0_), /** @type {tcuMatrix.Matrix} */(in1_))));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_SUBTRACT_FROM:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+ var in1_ = in1.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in1.inputType, in0.dataType, evalCtx, 1)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in1.dataType, evalCtx, 1);
+
+ setColor(evalCtx, es3fShaderMatrixTest.reduceToVec3(tcuMatrix.subtract(/** @type {tcuMatrix.Matrix} */(in0_), /** @type {tcuMatrix.Matrix} */(in1_))));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_MULTIPLY_INTO:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+ var in1_ = in1.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in1.inputType, in0.dataType, evalCtx, 1)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in1.dataType, evalCtx, 1);
+
+ setColor(evalCtx, es3fShaderMatrixTest.reduceToVec3(tcuMatrix.multiply(/** @type {tcuMatrix.Matrix} */(in0_), /** @type {tcuMatrix.Matrix} */(in1_))));
+ };
+ case es3fShaderMatrixTest.MatrixOp.OP_DIVIDE_INTO:
+ return function (evalCtx) {
+ var in0_ = in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in0.inputType, in0.dataType, evalCtx, 0)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in0.dataType, evalCtx, 0);
+ var in1_ = in1.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ?
+ es3fShaderMatrixTest.getInputValue(in1.inputType, in1.dataType, evalCtx, 1)
+ : es3fShaderMatrixTest.getInputValue(es3fShaderMatrixTest.InputType.INPUTTYPE_CONST, in1.dataType, evalCtx, 1);
+
+ setColor(evalCtx, es3fShaderMatrixTest.reduceToVec3(tcuMatrix.divide(/** @type {tcuMatrix.Matrix} */(in0_), /** @type {tcuMatrix.Matrix} */(in1_))));
+ };
+ }
+ };
+
+ /**
+ * @constructor
+ * @param {es3fShaderMatrixTest.MatrixShaderEvalFunc} evalFunc
+ * @param {es3fShaderMatrixTest.InputType} inType0
+ * @param {es3fShaderMatrixTest.InputType} inType1
+ * @extends {glsShaderRenderCase.ShaderEvaluator}
+ */
+ es3fShaderMatrixTest.MatrixShaderEvaluator = function(evalFunc, inType0, inType1) {
+ glsShaderRenderCase.ShaderEvaluator.call(this);
+ this.m_matEvalFunc = evalFunc;
+ this.m_inType0 = inType0;
+ this.m_inType1 = inType1;
+ };
+
+ es3fShaderMatrixTest.MatrixShaderEvaluator.prototype = Object.create(glsShaderRenderCase.ShaderEvaluator);
+ es3fShaderMatrixTest.MatrixShaderEvaluator.prototype.constructor = es3fShaderMatrixTest.MatrixShaderEvaluator;
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} evalCtx
+ */
+ es3fShaderMatrixTest.MatrixShaderEvaluator.prototype.evaluate = function (evalCtx) {
+ this.m_matEvalFunc(evalCtx);
+ }
+
+ /**
+ * @param {Array<number>} v
+ * @param {number} size
+ */
+ es3fShaderMatrixTest.writeVectorConstructor = function (v, size) {
+ var str = 'vec' + size + '';
+ for (var ndx = 0; ndx < size; ndx++) {
+ if (ndx != 0)
+ str += ', ';
+ str += v[ndx].toString;
+ }
+ str += ')';
+ return str;
+ }
+
+ /**
+ * @param {tcuMatrix.Matrix} m
+ */
+ es3fShaderMatrixTest.writeMatrixConstructor = function (m) {
+ var str = '';
+ if (m.rows == m.cols)
+ str += 'mat' + m.cols;
+ else
+ str += 'mat' + m.cols + 'x' + m.rows;
+
+ str += '(';
+ for (var colNdx = 0; colNdx < m.cols; colNdx++) {
+ for (var rowNdx = 0; rowNdx < m.rows; rowNdx++) {
+ if (rowNdx > 0 || colNdx > 0)
+ str += ', ';
+ str += m.get(rowNdx, colNdx).toString();
+ }
+ }
+ str += ')';
+ return str;
+ };
+
+ /**
+ * @constructor
+ * @param {string} name
+ * @param {string} desc
+ * @param {es3fShaderMatrixTest.ShaderInput} in0
+ * @param {es3fShaderMatrixTest.ShaderInput} in1
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @param {boolean} isVertexCase
+ * @extends {glsShaderRenderCase.ShaderRenderCase}
+ */
+ es3fShaderMatrixTest.ShaderMatrixCase = function(name, desc, in0, in1, op, isVertexCase) {
+ var evalFunc = es3fShaderMatrixTest.getEvalFunc(in0, in1, op);
+ glsShaderRenderCase.ShaderRenderCase.call(this, name, desc, isVertexCase, evalFunc);
+ this.m_in0 = in0;
+ this.m_in1 = in1;
+ this.m_op = op;
+ this.m_evaluator = new es3fShaderMatrixTest.MatrixShaderEvaluator(evalFunc, in0.inputType, in1.inputType);
+ };
+
+ es3fShaderMatrixTest.ShaderMatrixCase.prototype = Object.create(glsShaderRenderCase.ShaderRenderCase.prototype);
+ es3fShaderMatrixTest.ShaderMatrixCase.prototype.constructor = es3fShaderMatrixTest.ShaderMatrixCase;
+
+
+ es3fShaderMatrixTest.ShaderMatrixCase.prototype.init = function () {
+ var shaderSources = [ '', '' ];
+ var vtx = 0;
+ var frag = 1;
+ var op = this.m_isVertexCase ? vtx : frag;
+
+ /** @type {boolean} */ var isInDynMat0 = gluShaderUtil.isDataTypeMatrix(this.m_in0.dataType) && this.m_in0.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC;
+ /** @type {boolean} */ var isInDynMat1 = gluShaderUtil.isDataTypeMatrix(this.m_in1.dataType) && this.m_in1.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC;
+ /** @type {Array<string>} */ var inValues = [];
+ /** @type {gluShaderUtil.DataType} */ var resultType;
+ /** @type {gluShaderUtil.precision} */ var resultPrec = this.m_in0.precision;
+ /** @type {Array<string>} */ var passVars = [];
+ /** @type {number} */ var numInputs = (es3fShaderMatrixTest.isOperationBinary(this.m_op)) ? (2) : (1);
+
+ /** @type {string} */ var operationValue0 = '';
+ /** @type {string} */ var operationValue1 = '';
+
+ if (isInDynMat0 && isInDynMat1) {
+ throw new Error ('Only single dynamic matrix input is allowed.');
+ }
+
+ if (this.m_op == es3fShaderMatrixTest.MatrixOp.OP_MUL && gluShaderUtil.isDataTypeMatrix(this.m_in0.dataType) && gluShaderUtil.isDataTypeMatrix(this.m_in1.dataType)) {
+ resultType = gluShaderUtil.getDataTypeMatrix(gluShaderUtil.getDataTypeMatrixNumColumns(this.m_in1.dataType), gluShaderUtil.getDataTypeMatrixNumRows(this.m_in0.dataType));
+ } else if (this.m_op == es3fShaderMatrixTest.MatrixOp.OP_OUTER_PRODUCT) {
+ resultType = gluShaderUtil.getDataTypeMatrix(gluShaderUtil.getDataTypeScalarSize(this.m_in1.dataType), gluShaderUtil.getDataTypeScalarSize(this.m_in0.dataType));
+ } else if (this.m_op == es3fShaderMatrixTest.MatrixOp.OP_TRANSPOSE) {
+ resultType = gluShaderUtil.getDataTypeMatrix(gluShaderUtil.getDataTypeMatrixNumRows(this.m_in0.dataType), gluShaderUtil.getDataTypeMatrixNumColumns(this.m_in0.dataType));
+ } else if (this.m_op == es3fShaderMatrixTest.MatrixOp.OP_INVERSE) {
+ resultType = this.m_in0.dataType;
+ } else if (this.m_op == es3fShaderMatrixTest.MatrixOp.OP_DETERMINANT) {
+ resultType = gluShaderUtil.DataType.FLOAT;
+ } else if (es3fShaderMatrixTest.getOperationType(this.m_op) == es3fShaderMatrixTest.OperationType.OPERATIONTYPE_UNARY_PREFIX_OPERATOR ||
+ es3fShaderMatrixTest.getOperationType(this.m_op) == es3fShaderMatrixTest.OperationType.OPERATIONTYPE_UNARY_POSTFIX_OPERATOR) {
+ resultType = this.m_in0.dataType;
+ } else if (gluShaderUtil.isDataTypeMatrix(this.m_in0.dataType) && gluShaderUtil.isDataTypeMatrix(this.m_in1.dataType)) {
+ if (this.m_in0.dataType !== this.m_in1.dataType) {
+ throw new Error ('Incompatible data types');
+ }
+ resultType = this.m_in0.dataType;
+ } else if (gluShaderUtil.isDataTypeMatrix(this.m_in0.dataType) || gluShaderUtil.isDataTypeMatrix(this.m_in1.dataType)) {
+ /** @type {number} */ var matNdx = gluShaderUtil.isDataTypeMatrix(this.m_in0.dataType) ? 0 : 1;
+ /** @type {gluShaderUtil.DataType} */ var matrixType = matNdx == 0 ? this.m_in0.dataType : this.m_in1.dataType;
+ /** @type {gluShaderUtil.DataType} */ var otherType = matNdx == 0 ? this.m_in1.dataType : this.m_in0.dataType;
+
+ if (otherType == gluShaderUtil.DataType.FLOAT)
+ resultType = matrixType;
+ else {
+ if (!gluShaderUtil.isDataTypeVector(otherType)) {
+ throw new Error ('Is not data type vector');
+ }
+ resultType = gluShaderUtil.getDataTypeFloatVec(matNdx == 0 ? gluShaderUtil.getDataTypeMatrixNumRows(matrixType) : gluShaderUtil.getDataTypeMatrixNumColumns(matrixType));
+ }
+ } else {
+ throw new Error ('Error');
+ }
+
+ shaderSources[vtx] += '#version 300 es\n';
+ shaderSources[frag] += '#version 300 es\n';
+
+ shaderSources[vtx] += 'in highp vec4 a_position;\n';
+ shaderSources[frag] += 'layout(location = 0) out mediump vec4 dEQP_FragColor;\n';
+ if (this.m_isVertexCase) {
+ shaderSources[vtx] += 'out mediump vec4 v_color;\n';
+ shaderSources[frag] += 'in mediump vec4 v_color;\n';
+ }
+
+ // Input declarations.
+ for (var inNdx = 0; inNdx < numInputs; inNdx++) {
+ /** @type {es3fShaderMatrixTest.ShaderInput} */ var ind = inNdx > 0 ? this.m_in1 : this.m_in0;
+ /** @type {string} */ var precName = gluShaderUtil.getPrecisionName(ind.precision);
+ /** @type {string} */ var typeName = gluShaderUtil.getDataTypeName(ind.dataType);
+ /** @type {number} */ var inValueNdx = inNdx > 0 ? 1 : 0;
+
+ if (ind.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC) {
+ shaderSources[vtx] += 'in ' + precName + ' ' + typeName + ' a_';
+
+ if (gluShaderUtil.isDataTypeMatrix(ind.dataType)) {
+ // a_matN, v_matN
+ shaderSources[vtx] += typeName + ';\n';
+ if (!this.m_isVertexCase) {
+ shaderSources[vtx] += 'out ' + precName + ' ' + typeName + ' v_' + typeName + ';\n';
+ shaderSources[frag] += 'in ' + precName + ' ' + typeName + ' v_' + typeName + ';\n';
+ passVars.push(typeName);
+ }
+
+ inValues[inValueNdx] = (this.m_isVertexCase ? 'a_' : 'v_') + gluShaderUtil.getDataTypeName(ind.dataType);
+ } else {
+ // a_coords, v_coords
+ shaderSources[vtx] += 'coords;\n';
+ if (!this.m_isVertexCase) {
+ shaderSources[vtx] += 'out ' + precName + ' ' + typeName + ' v_coords;\n';
+ shaderSources[frag] += 'in ' + precName + ' ' + typeName + ' v_coords;\n';
+ passVars.push('coords');
+ }
+
+ inValues[inValueNdx] = this.m_isVertexCase ? 'a_coords' : 'v_coords';
+ }
+ } else if (ind.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_UNIFORM) {
+ shaderSources[op] += 'uniform ' + precName + ' ' + typeName + ' u_in' + inNdx + ';\n';
+ inValues[inValueNdx] = 'u_in' + inNdx.toString();
+ } else if (ind.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_CONST) {
+ shaderSources[op] += 'const ' + precName + ' ' + typeName + ' in' + inNdx + ' = ';
+
+ // Generate declaration.
+ switch (ind.dataType) {
+ case gluShaderUtil.DataType.FLOAT:
+ shaderSources[op] += s_constInFloat[inNdx].toString();
+ break;
+ case gluShaderUtil.DataType.FLOAT_VEC2:
+ shaderSources[op] += es3fShaderMatrixTest.writeVectorConstructor( s_constInVec2[inNdx], 2);
+ break;
+ case gluShaderUtil.DataType.FLOAT_VEC3:
+ shaderSources[op] += es3fShaderMatrixTest.writeVectorConstructor( s_constInVec3[inNdx], 3);
+ break;
+ case gluShaderUtil.DataType.FLOAT_VEC4:
+ shaderSources[op] += es3fShaderMatrixTest.writeVectorConstructor( s_constInVec4[inNdx], 4);
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT2:
+ shaderSources[op] += es3fShaderMatrixTest.writeMatrixConstructor( tcuMatrix.matrixFromDataArray(2, 2, s_constInMat2x2[inNdx]));
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT2X3:
+ shaderSources[op] += es3fShaderMatrixTest.writeMatrixConstructor( tcuMatrix.matrixFromDataArray(3, 2, s_constInMat2x3[inNdx]));
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT2X4:
+ shaderSources[op] += es3fShaderMatrixTest.writeMatrixConstructor( tcuMatrix.matrixFromDataArray(4, 2, s_constInMat2x4[inNdx]));
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT3X2:
+ shaderSources[op] += es3fShaderMatrixTest.writeMatrixConstructor( tcuMatrix.matrixFromDataArray(2, 3, s_constInMat3x2[inNdx]));
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT3:
+ shaderSources[op] += es3fShaderMatrixTest.writeMatrixConstructor( tcuMatrix.matrixFromDataArray(3, 3, s_constInMat3x3[inNdx]));
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT3X4:
+ shaderSources[op] += es3fShaderMatrixTest.writeMatrixConstructor( tcuMatrix.matrixFromDataArray(4, 3, s_constInMat3x4[inNdx]));
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT4X2:
+ shaderSources[op] += es3fShaderMatrixTest.writeMatrixConstructor( tcuMatrix.matrixFromDataArray(2, 4, s_constInMat4x2[inNdx]));
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT4X3:
+ shaderSources[op] += es3fShaderMatrixTest.writeMatrixConstructor( tcuMatrix.matrixFromDataArray(3, 4, s_constInMat4x3[inNdx]));
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT4:
+ shaderSources[op] += es3fShaderMatrixTest.writeMatrixConstructor( tcuMatrix.matrixFromDataArray(4, 4, s_constInMat4x4[inNdx]));
+ break;
+
+ default:
+ throw new Error('Data type error');
+ }
+
+ shaderSources[op] += ';\n';
+
+ inValues[inValueNdx] = 'in' + inNdx.toString();
+ }
+ }
+
+ shaderSources[vtx] += '\n'
+ + 'void main (void)\n'
+ + '{\n'
+ + ' gl_Position = a_position;\n';
+ shaderSources[frag] += '\n'
+ + 'void main (void)\n'
+ + '{\n';
+
+ if (this.m_isVertexCase)
+ shaderSources[frag] += ' dEQP_FragColor = v_color;\n';
+ else {
+ for (var i = 0; i != passVars.length; i++)
+ shaderSources[vtx] += ' v_' + passVars[i] + ' = ' + 'a_' + passVars[i] + ';\n';
+ }
+
+ // Operation.
+
+ switch (es3fShaderMatrixTest.getOperationNature(this.m_op)) {
+ case es3fShaderMatrixTest.OperationNature.OPERATIONNATURE_PURE:
+ if (es3fShaderMatrixTest.getOperationType(this.m_op) == es3fShaderMatrixTest.OperationType.OPERATIONTYPE_ASSIGNMENT)
+ throw new Error('Wrong operation type');
+
+ operationValue0 = inValues[0];
+ operationValue1 = inValues[1];
+ break;
+
+ case es3fShaderMatrixTest.OperationNature.OPERATIONNATURE_MUTATING:
+ if (es3fShaderMatrixTest.getOperationType(this.m_op) == es3fShaderMatrixTest.OperationType.OPERATIONTYPE_ASSIGNMENT)
+ throw new Error('Wrong operation type');
+
+ shaderSources[op] += ' ' + gluShaderUtil.getPrecisionName(resultPrec) + ' ' + gluShaderUtil.getDataTypeName(resultType) + ' tmpValue = ' + inValues[0] + ';\n';
+
+ operationValue0 = 'tmpValue';
+ operationValue1 = inValues[1];
+ break;
+
+ case es3fShaderMatrixTest.OperationNature.OPERATIONNATURE_ASSIGNMENT:
+ if (es3fShaderMatrixTest.getOperationType(this.m_op) != es3fShaderMatrixTest.OperationType.OPERATIONTYPE_ASSIGNMENT)
+ throw new Error('Wrong operation type');
+
+ operationValue0 = inValues[0];
+ operationValue1 = inValues[1];
+ break;
+
+ default:
+ throw new Error('Wrong operation nature');
+ }
+
+ switch (es3fShaderMatrixTest.getOperationType(this.m_op)) {
+ case es3fShaderMatrixTest.OperationType.OPERATIONTYPE_BINARY_OPERATOR:
+ shaderSources[op] += ' ' + gluShaderUtil.getPrecisionName(resultPrec) + ' '
+ + gluShaderUtil.getDataTypeName(resultType)
+ + ' res = ' + operationValue0 + ' '
+ + es3fShaderMatrixTest.getOperationName(this.m_op) + ' '
+ + operationValue1 + ';\n';
+ break;
+ case es3fShaderMatrixTest.OperationType.OPERATIONTYPE_UNARY_PREFIX_OPERATOR:
+ shaderSources[op] += ' ' + gluShaderUtil.getPrecisionName(resultPrec) + ' '
+ + gluShaderUtil.getDataTypeName(resultType)
+ + ' res = ' + es3fShaderMatrixTest.getOperationName(this.m_op)
+ + operationValue0 + ';\n';
+ break;
+ case es3fShaderMatrixTest.OperationType.OPERATIONTYPE_UNARY_POSTFIX_OPERATOR:
+ shaderSources[op] += ' ' + gluShaderUtil.getPrecisionName(resultPrec) + ' '
+ + gluShaderUtil.getDataTypeName(resultType)
+ + ' res = ' + operationValue0
+ + es3fShaderMatrixTest.getOperationName(this.m_op) + ';\n';
+ break;
+ case es3fShaderMatrixTest.OperationType.OPERATIONTYPE_BINARY_FUNCTION:
+ shaderSources[op] += ' ' + gluShaderUtil.getPrecisionName(resultPrec)
+ + ' ' + gluShaderUtil.getDataTypeName(resultType)
+ + ' res = ' + es3fShaderMatrixTest.getOperationName(this.m_op)
+ + '(' + operationValue0
+ + ', ' + operationValue1 + ');\n';
+ break;
+ case es3fShaderMatrixTest.OperationType.OPERATIONTYPE_UNARY_FUNCTION:
+ shaderSources[op] += ' ' + gluShaderUtil.getPrecisionName(resultPrec)
+ + ' ' + gluShaderUtil.getDataTypeName(resultType)
+ + ' res = ' + es3fShaderMatrixTest.getOperationName(this.m_op)
+ + '(' + operationValue0 + ');\n';
+ break;
+ case es3fShaderMatrixTest.OperationType.OPERATIONTYPE_ASSIGNMENT:
+ shaderSources[op] += ' ' + gluShaderUtil.getPrecisionName(resultPrec)
+ + ' ' + gluShaderUtil.getDataTypeName(resultType)
+ + ' res = ' + operationValue0 + ';\n';
+ shaderSources[op] += ' res ' + es3fShaderMatrixTest.getOperationName(this.m_op)
+ + ' ' + operationValue1 + ';\n';
+ break;
+ default:
+ throw new Error('Wrong operation type');
+ }
+
+ // Reduction to vec3 (rgb). Check the used value too if it was modified
+ shaderSources[op] += ' ' + (this.m_isVertexCase ? 'v_color' : 'dEQP_FragColor') + ' = ';
+
+ if (es3fShaderMatrixTest.isOperationValueModifying(this.m_op))
+ shaderSources[op] += 'vec4(' + this.genGLSLMatToVec3Reduction(resultType, 'res')
+ + ', 1.0) + vec4(' + this.genGLSLMatToVec3Reduction(resultType, 'tmpValue')
+ + ', 0.0);\n';
+ else
+ shaderSources[op] += 'vec4(' + this.genGLSLMatToVec3Reduction(resultType, 'res')
+ + ', 1.0);\n';
+
+ shaderSources[vtx] += '}\n';
+ shaderSources[frag] += '}\n';
+
+ this.m_vertShaderSource = shaderSources[vtx];
+ this.m_fragShaderSource = shaderSources[frag];
+
+ // \todo [2012-02-14 pyry] Compute better values for matrix tests.
+ for (var attribNdx = 0; attribNdx < 4; attribNdx++) {
+ this.m_userAttribTransforms[attribNdx] = new tcuMatrix.Matrix(4, 4, 0);
+ this.m_userAttribTransforms[attribNdx].set(0, 3, 0.2);// !< prevent matrix*vec from going into zero (assuming vec.w != 0)
+ this.m_userAttribTransforms[attribNdx].set(1, 3, 0.1);// !<
+ this.m_userAttribTransforms[attribNdx].set(2, 3, 0.4 + 0.15 * attribNdx);// !<
+ this.m_userAttribTransforms[attribNdx].set(3, 3, 0.7);// !<
+ this.m_userAttribTransforms[attribNdx].set((0 + attribNdx) % 4, 0, 1.0);
+ this.m_userAttribTransforms[attribNdx].set((1 + attribNdx) % 4, 1, 1.0);
+ this.m_userAttribTransforms[attribNdx].set((2 + attribNdx) % 4, 2, 1.0);
+ this.m_userAttribTransforms[attribNdx].set((3 + attribNdx) % 4, 3, 1.0);
+ }
+
+ // prevent bad reference cases such as black result images by fine-tuning used matrices
+ if (es3fShaderMatrixTest.getOperationTestMatrixType(this.m_op) != es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_DEFAULT) {
+ for (var attribNdx = 0; attribNdx < 4; attribNdx++) {
+ for (var row = 0; row < 4; row++)
+ for (var col = 0; col < 4; col++) {
+ switch (es3fShaderMatrixTest.getOperationTestMatrixType(this.m_op)) {
+ case es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_NEGATED:
+ this.m_userAttribTransforms[attribNdx].set(row, col, -this.m_userAttribTransforms[attribNdx].get(row, col));
+ break;
+ case es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_INCREMENTED:
+ this.m_userAttribTransforms[attribNdx].set(row, col, this.m_userAttribTransforms[attribNdx].get(row, col) + 0.3);
+ break;
+ case es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_DECREMENTED:
+ this.m_userAttribTransforms[attribNdx].set(row, col, this.m_userAttribTransforms[attribNdx].get(row, col) - 0.3);
+ break;
+ case es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_NEGATED_INCREMENTED:
+ this.m_userAttribTransforms[attribNdx].set(row, col, -(this.m_userAttribTransforms[attribNdx].get(row, col) + 0.3));
+ break;
+ case es3fShaderMatrixTest.MatrixType.TESTMATRIXTYPE_INCREMENTED_LESS:
+ this.m_userAttribTransforms[attribNdx].set(row, col, this.m_userAttribTransforms[attribNdx].get(row, col) - 0.1);
+ break;
+ default:
+ throw new Error('Wrong Matrix type');
+ }
+ }
+ }
+ }
+
+ glsShaderRenderCase.ShaderRenderCase.prototype.init.call(this);
+ };
+
+
+ es3fShaderMatrixTest.ShaderMatrixCase.prototype.setupUniforms = function(programId, constCoords) {
+ for (var inNdx = 0; inNdx < 2; inNdx++)
+ {
+ var input = inNdx > 0 ? this.m_in1 : this.m_in0;
+
+ if (input.inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_UNIFORM)
+ {
+ var loc = gl.getUniformLocation(programId, "u_in" + inNdx);
+
+ if (!loc)
+ continue;
+
+ switch (input.dataType)
+ {
+ case gluShaderUtil.DataType.FLOAT: gl.uniform1f(loc, s_constInFloat[inNdx]); break;
+ case gluShaderUtil.DataType.FLOAT_VEC2: gl.uniform2fv(loc, s_constInVec2[inNdx]); break;
+ case gluShaderUtil.DataType.FLOAT_VEC3: gl.uniform3fv(loc, s_constInVec3[inNdx]); break;
+ case gluShaderUtil.DataType.FLOAT_VEC4: gl.uniform4fv(loc, s_constInVec4[inNdx]); break;
+ // \note GLES3 supports transpose in matrix upload.
+ case gluShaderUtil.DataType.FLOAT_MAT2: gl.uniformMatrix2fv (loc, true, s_constInMat2x2[inNdx]); break;
+ case gluShaderUtil.DataType.FLOAT_MAT2X3: gl.uniformMatrix2x3fv(loc, true, s_constInMat2x3[inNdx]); break;
+ case gluShaderUtil.DataType.FLOAT_MAT2X4: gl.uniformMatrix2x4fv(loc, true, s_constInMat2x4[inNdx]); break;
+ case gluShaderUtil.DataType.FLOAT_MAT3X2: gl.uniformMatrix3x2fv(loc, true, s_constInMat3x2[inNdx]); break;
+ case gluShaderUtil.DataType.FLOAT_MAT3: gl.uniformMatrix3fv (loc, true, s_constInMat3x3[inNdx]); break;
+ case gluShaderUtil.DataType.FLOAT_MAT3X4: gl.uniformMatrix3x4fv(loc, true, s_constInMat3x4[inNdx]); break;
+ case gluShaderUtil.DataType.FLOAT_MAT4X2: gl.uniformMatrix4x2fv(loc, true, s_constInMat4x2[inNdx]); break;
+ case gluShaderUtil.DataType.FLOAT_MAT4X3: gl.uniformMatrix4x3fv(loc, true, s_constInMat4x3[inNdx]); break;
+ case gluShaderUtil.DataType.FLOAT_MAT4: gl.uniformMatrix4fv (loc, true, s_constInMat4x4[inNdx]); break;
+ default:
+ throw new Error('Invalid datatype' + input.dataType);
+ }
+ }
+ }
+ };
+
+
+
+ /**
+ * @param {gluShaderUtil.DataType} matType
+ * @param {string} varName
+ * @return {string}
+ */
+ es3fShaderMatrixTest.ShaderMatrixCase.prototype.genGLSLMatToVec3Reduction = function (matType, varName) {
+ /** @type {string} */ var op = '';
+
+ switch (matType) {
+ case gluShaderUtil.DataType.FLOAT:
+ op += varName + ', '
+ + varName + ', '
+ + varName + '';
+ break;
+ case gluShaderUtil.DataType.FLOAT_VEC2:
+ op += varName + '.x, '
+ + varName + '.y, '
+ + varName + '.x';
+ break;
+ case gluShaderUtil.DataType.FLOAT_VEC3:
+ op += varName + '';
+ break;
+ case gluShaderUtil.DataType.FLOAT_VEC4:
+ op += varName + '.x, '
+ + varName + '.y, '
+ + varName + '.z+'
+ + varName + '.w';
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT2:
+ op += varName + '[0][0], '
+ + varName + '[1][0], '
+ + varName + '[0][1]+'
+ + varName + '[1][1]';
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT2X3:
+ op += varName + '[0] + '
+ + varName + '[1]';
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT2X4:
+ op += varName + '[0].xyz + '
+ + varName + '[1].yzw';
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT3X2:
+ op += varName + '[0][0]+'
+ + varName + '[0][1], '
+ + varName + '[1][0]+'
+ + varName + '[1][1], '
+ + varName + '[2][0]+'
+ + varName + '[2][1]';
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT3:
+ op += varName + '[0] + '
+ + varName + '[1] + '
+ + varName + '[2]';
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT3X4:
+ op += varName + '[0].xyz + '
+ + varName + '[1].yzw + '
+ + varName + '[2].zwx';
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT4X2:
+ op += varName + '[0][0]+'
+ + varName + '[0][1]+'
+ + varName + '[3][0], '
+ + varName + '[1][0]+'
+ + varName + '[1][1]+'
+ + varName + '[3][1], '
+ + varName + '[2][0]+'
+ + varName + '[2][1]';
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT4X3:
+ op += varName + '[0] + '
+ + varName + '[1] + '
+ + varName + '[2] + '
+ + varName + '[3]';
+ break;
+ case gluShaderUtil.DataType.FLOAT_MAT4:
+ op += varName + '[0].xyz+'
+ + varName + '[1].yzw+'
+ + varName + '[2].zwx+'
+ + varName + '[3].wxy';
+ break;
+
+ default:
+ throw new Error('Wrong data type');
+ }
+
+ return op;
+ }
+
+ /**
+ * @constructor
+ * @param {string} name
+ * @param {string} desc
+ * @param {es3fShaderMatrixTest.MatrixOp} op
+ * @param {boolean} extendedInputTypeCases
+ * @param {boolean} createInputTypeGroup
+ */
+ es3fShaderMatrixTest.ops = function (name, desc, op, extendedInputTypeCases, createInputTypeGroup) {
+ this.name = name;
+ this.desc = desc;
+ this.op = op;
+ this.extendedInputTypeCases = extendedInputTypeCases;
+ this.createInputTypeGroup = createInputTypeGroup;
+ };
+
+ /**
+ * @constructor
+ * @param {string} name
+ * @param {string} desc
+ * @param {es3fShaderMatrixTest.InputType} type
+ */
+ es3fShaderMatrixTest.InputTypeSpec = function (name, desc, type) {
+ this.name = name;
+ this.desc = desc;
+ this.type = type;
+ };
+
+ es3fShaderMatrixTest.init = function () {
+ var state = tcuTestCase.runner;
+
+ var ops = [
+ new es3fShaderMatrixTest.ops('add', 'Matrix addition tests', es3fShaderMatrixTest.MatrixOp.OP_ADD, true, true),
+ new es3fShaderMatrixTest.ops('sub', 'Matrix subtraction tests', es3fShaderMatrixTest.MatrixOp.OP_SUB, true, true),
+ new es3fShaderMatrixTest.ops('mul', 'Matrix multiplication tests', es3fShaderMatrixTest.MatrixOp.OP_MUL, true, true),
+ new es3fShaderMatrixTest.ops('div', 'Matrix division tests', es3fShaderMatrixTest.MatrixOp.OP_DIV, true, true),
+ new es3fShaderMatrixTest.ops('matrixcompmult', 'Matrix component-wise multiplication tests', es3fShaderMatrixTest.MatrixOp.OP_COMP_MUL, false, true),
+ new es3fShaderMatrixTest.ops('outerproduct', 'Matrix outerProduct() tests', es3fShaderMatrixTest.MatrixOp.OP_OUTER_PRODUCT, false, true),
+ new es3fShaderMatrixTest.ops('transpose', 'Matrix transpose() tests', es3fShaderMatrixTest.MatrixOp.OP_TRANSPOSE, false, true),
+ new es3fShaderMatrixTest.ops('determinant', 'Matrix determinant() tests', es3fShaderMatrixTest.MatrixOp.OP_DETERMINANT, false, true),
+ new es3fShaderMatrixTest.ops('inverse', 'Matrix inverse() tests', es3fShaderMatrixTest.MatrixOp.OP_INVERSE, false, true),
+ new es3fShaderMatrixTest.ops('unary_addition', 'Matrix unary addition tests', es3fShaderMatrixTest.MatrixOp.OP_UNARY_PLUS, false, false),
+ new es3fShaderMatrixTest.ops('negation', 'Matrix negation tests', es3fShaderMatrixTest.MatrixOp.OP_NEGATION, false, false),
+ new es3fShaderMatrixTest.ops('pre_increment', 'Matrix prefix increment tests', es3fShaderMatrixTest.MatrixOp.OP_PRE_INCREMENT, false, false),
+ new es3fShaderMatrixTest.ops('pre_decrement', 'Matrix prefix decrement tests', es3fShaderMatrixTest.MatrixOp.OP_PRE_DECREMENT, false, false),
+ new es3fShaderMatrixTest.ops('post_increment', 'Matrix postfix increment tests', es3fShaderMatrixTest.MatrixOp.OP_POST_INCREMENT, false, false),
+ new es3fShaderMatrixTest.ops('post_decrement', 'Matrix postfix decrement tests', es3fShaderMatrixTest.MatrixOp.OP_POST_DECREMENT, false, false),
+ new es3fShaderMatrixTest.ops('add_assign', 'Matrix add into tests', es3fShaderMatrixTest.MatrixOp.OP_ADD_INTO, false, false),
+ new es3fShaderMatrixTest.ops('sub_assign', 'Matrix subtract from tests', es3fShaderMatrixTest.MatrixOp.OP_SUBTRACT_FROM,false, false),
+ new es3fShaderMatrixTest.ops('mul_assign', 'Matrix multiply into tests', es3fShaderMatrixTest.MatrixOp.OP_MULTIPLY_INTO,false, false),
+ new es3fShaderMatrixTest.ops('div_assign', 'Matrix divide into tests', es3fShaderMatrixTest.MatrixOp.OP_DIVIDE_INTO,false, false)
+ ];
+
+ var extendedInputTypes = [
+ new es3fShaderMatrixTest.InputTypeSpec('const', 'Constant matrix input', es3fShaderMatrixTest.InputType.INPUTTYPE_CONST),
+ new es3fShaderMatrixTest.InputTypeSpec('uniform', 'Uniform matrix input', es3fShaderMatrixTest.InputType.INPUTTYPE_UNIFORM),
+ new es3fShaderMatrixTest.InputTypeSpec('dynamic', 'Dynamic matrix input', es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC)
+ ];
+
+ var reducedInputTypes = [
+ new es3fShaderMatrixTest.InputTypeSpec('dynamic', 'Dynamic matrix input', es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC)
+ ];
+
+ /** @type {Array<gluShaderUtil.DataType>} */ var matrixTypes = [
+ gluShaderUtil.DataType.FLOAT_MAT2,
+ gluShaderUtil.DataType.FLOAT_MAT2X3,
+ gluShaderUtil.DataType.FLOAT_MAT2X4,
+ gluShaderUtil.DataType.FLOAT_MAT3X2,
+ gluShaderUtil.DataType.FLOAT_MAT3,
+ gluShaderUtil.DataType.FLOAT_MAT3X4,
+ gluShaderUtil.DataType.FLOAT_MAT4X2,
+ gluShaderUtil.DataType.FLOAT_MAT4X3,
+ gluShaderUtil.DataType.FLOAT_MAT4
+ ];
+
+ /** @type {Array<gluShaderUtil.precision>} */ var precisions = [
+ gluShaderUtil.precision.PRECISION_LOWP,
+ gluShaderUtil.precision.PRECISION_MEDIUMP,
+ gluShaderUtil.precision.PRECISION_HIGHP
+ ];
+
+ for (var opNdx = 0; opNdx < ops.length; opNdx++) {
+ var inTypeList = ops[opNdx].extendedInputTypeCases ? extendedInputTypes : reducedInputTypes;
+ var inTypeListSize = ops[opNdx].extendedInputTypeCases ? extendedInputTypes.length : reducedInputTypes.length;
+ var op = ops[opNdx].op;
+
+ for (var inTypeNdx = 0; inTypeNdx < inTypeListSize; inTypeNdx++) {
+ var inputType = inTypeList[inTypeNdx].type;
+ var group = [];
+
+ if (ops[opNdx].name != 'mul') {
+ if (ops[opNdx].createInputTypeGroup) {
+ group[0] = tcuTestCase.newTest(ops[opNdx].name + '.' + inTypeList[inTypeNdx].name, inTypeList[inTypeNdx].desc);
+ } else {
+ group[0] = tcuTestCase.newTest(ops[opNdx].name, ops[opNdx].desc);
+ }
+ state.testCases.addChild(group[0]);
+ } else {
+ for (var ii = 0; ii < precisions.length; ++ii) {
+ group[ii] = tcuTestCase.newTest(ops[opNdx].name + '.' + inTypeList[inTypeNdx].name, inTypeList[inTypeNdx].desc);
+ state.testCases.addChild(group[ii]);
+ }
+ }
+
+ for (var matTypeNdx = 0; matTypeNdx < matrixTypes.length; matTypeNdx++) {
+ var matType = matrixTypes[matTypeNdx];
+ var numCols = gluShaderUtil.getDataTypeMatrixNumColumns(matType);
+ var numRows = gluShaderUtil.getDataTypeMatrixNumRows(matType);
+ var matTypeName = gluShaderUtil.getDataTypeName(matType);
+
+ for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
+ var inGroup;
+ if (ops[opNdx].name != 'mul') {
+ inGroup = group[0];
+ } else {
+ inGroup = group[precNdx];
+ }
+
+ var precision = precisions[precNdx];
+ var precName = gluShaderUtil.getPrecisionName(precision);
+ var baseName = precName + '_' + matTypeName + '_';
+ var matIn = new es3fShaderMatrixTest.ShaderInput(inputType, matType, precision);
+
+ if (es3fShaderMatrixTest.isOperationMatrixScalar(op)) {
+ // Matrix-scalar \note For div cases we use uniform input.
+ var scalarIn = new es3fShaderMatrixTest.ShaderInput(op == es3fShaderMatrixTest.MatrixOp.OP_DIV ? es3fShaderMatrixTest.InputType.INPUTTYPE_UNIFORM : es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC, gluShaderUtil.DataType.FLOAT, precision);
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(baseName + 'float_vertex', 'Matrix-scalar case', matIn, scalarIn, op, true));
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(baseName + 'float_fragment', 'Matrix-scalar case', matIn, scalarIn, op, false));
+ }
+
+ if (es3fShaderMatrixTest.isOperationMatrixVector(op)) {
+ // Matrix-vector.
+ var colVecType = gluShaderUtil.getDataTypeFloatVec(numCols);
+ var colVecIn = new es3fShaderMatrixTest.ShaderInput(op == es3fShaderMatrixTest.MatrixOp.OP_DIV ? es3fShaderMatrixTest.InputType.INPUTTYPE_UNIFORM : es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC, colVecType, precision);
+
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(baseName + gluShaderUtil.getDataTypeName(colVecType) + '_vertex', 'Matrix-vector case', matIn, colVecIn, op, true));
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(baseName + gluShaderUtil.getDataTypeName(colVecType) + '_fragment', 'Matrix-vector case', matIn, colVecIn, op, false));
+
+ // Vector-matrix.
+ var rowVecType = gluShaderUtil.getDataTypeFloatVec(numRows);
+ var rowVecIn = new es3fShaderMatrixTest.ShaderInput(op == es3fShaderMatrixTest.MatrixOp.OP_DIV ? es3fShaderMatrixTest.InputType.INPUTTYPE_UNIFORM : es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC, rowVecType, precision);
+ var vecMatName = precName + '_' + gluShaderUtil.getDataTypeName(rowVecType) + '_' + matTypeName;
+
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(vecMatName + '_vertex', 'Vector-matrix case', rowVecIn, matIn, op, true));
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(vecMatName + '_fragment', 'Vector-matrix case', rowVecIn, matIn, op, false));
+ }
+
+ if (es3fShaderMatrixTest.isOperationArithmeticMatrixMatrix(op)) {
+ // Arithmetic matrix-matrix multiplication.
+ for (var otherCols = 2; otherCols <= 4; otherCols++) {
+ var otherMatIn = new es3fShaderMatrixTest.ShaderInput(inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ? es3fShaderMatrixTest.InputType.INPUTTYPE_UNIFORM : inputType, gluShaderUtil.getDataTypeMatrix(otherCols, numCols), precision);
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(baseName + gluShaderUtil.getDataTypeName(otherMatIn.dataType) + '_vertex', 'Matrix-matrix case', matIn, otherMatIn, op, true));
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(baseName + gluShaderUtil.getDataTypeName(otherMatIn.dataType) + '_fragment', 'Matrix-matrix case', matIn, otherMatIn, op, false));
+ }
+ } else if (es3fShaderMatrixTest.isOperationComponentwiseMatrixMatrix(op)) {
+ // Component-wise.
+ var otherMatIn = new es3fShaderMatrixTest.ShaderInput(inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ? es3fShaderMatrixTest.InputType.INPUTTYPE_UNIFORM : inputType, matType, precision);
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(baseName + matTypeName + '_vertex', 'Matrix-matrix case', matIn, otherMatIn, op, true));
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(baseName + matTypeName + '_fragment', 'Matrix-matrix case', matIn, otherMatIn, op, false));
+ }
+
+ if (es3fShaderMatrixTest.isOperationVectorVector(op)) {
+ var vec1In = new es3fShaderMatrixTest.ShaderInput(inputType, gluShaderUtil.getDataTypeFloatVec(numRows), precision);
+ var vec2In = new es3fShaderMatrixTest.ShaderInput((inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC) ? es3fShaderMatrixTest.InputType.INPUTTYPE_UNIFORM : inputType, gluShaderUtil.getDataTypeFloatVec(numCols), precision);
+
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(baseName + 'float_vertex', 'Vector-vector case', vec1In, vec2In, op, true));
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(baseName + 'float_fragment', 'Vector-vector case', vec1In, vec2In, op, false));
+ }
+
+ if (es3fShaderMatrixTest.isOperationUnaryAnyMatrix(op) || (es3fShaderMatrixTest.isOperationUnarySymmetricMatrix(op) && numCols == numRows)) {
+ var voidInput = new es3fShaderMatrixTest.ShaderInput();
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(baseName + 'float_vertex', 'Matrix case', matIn, voidInput, op, true));
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(baseName + 'float_fragment', 'Matrix case', matIn, voidInput, op, false));
+ }
+
+ if (es3fShaderMatrixTest.isOperationAssignmentAnyMatrix(op) || (es3fShaderMatrixTest.isOperationAssignmentSymmetricMatrix(op) && numCols == numRows)) {
+ var otherMatIn = new es3fShaderMatrixTest.ShaderInput(inputType == es3fShaderMatrixTest.InputType.INPUTTYPE_DYNAMIC ? es3fShaderMatrixTest.InputType.INPUTTYPE_UNIFORM : inputType, matType, precision);
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(baseName + 'float_vertex', 'Matrix assignment case', matIn, otherMatIn, op, true));
+ inGroup.addChild(new es3fShaderMatrixTest.ShaderMatrixCase(baseName + 'float_fragment', 'Matrix assignment case', matIn, otherMatIn, op, false));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ es3fShaderMatrixTest.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var testName = 'shader_matrix';
+ var testDescription = 'Shader Matrix Test';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.testCases = tcuTestCase.newTest(testName, testDescription, null);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ es3fShaderMatrixTest.init();
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ bufferedLogToConsole(err);
+ tcuTestCase.runner.terminate();
+ }
+ };
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderOperatorTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderOperatorTests.js
new file mode 100644
index 0000000000..5dfd0311d3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderOperatorTests.js
@@ -0,0 +1,3252 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fShaderOperatorTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.delibs.debase.deMath');
+goog.require('modules.shared.glsShaderRenderCase');
+goog.require('framework.common.tcuMatrix');
+
+goog.scope(function() {
+var es3fShaderOperatorTests = functional.gles3.es3fShaderOperatorTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var gluShaderUtil = framework.opengl.gluShaderUtil;
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+var deMath = framework.delibs.debase.deMath;
+var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
+var tcuMatrix = framework.common.tcuMatrix;
+
+/** @const */ es3fShaderOperatorTests.MAX_INPUTS = 3;
+
+let canvasWH = 256;
+if (tcuTestCase.isQuickMode()) {
+ canvasWH = 32;
+}
+
+es3fShaderOperatorTests.stringJoin = function(elems, delim) {
+ var result = '';
+ for (var i = 0; i < elems.length; i++)
+ result += (i > 0 ? delim : '') + elems[i];
+ return result;
+};
+
+es3fShaderOperatorTests.twoValuedVec4 = function(first, second, firstMask) {
+ var elems = [];
+ for (var i = 0; i < 4; i++)
+ elems[i] = firstMask[i] ? first : second;
+
+ return 'vec4(' + es3fShaderOperatorTests.stringJoin(elems, ', ') + ')';
+};
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+var negate = function(x) {
+ return -x;
+};
+
+var addOne = function(x) {
+ return x + 1;
+};
+
+var subOne = function(x) {
+ return x - 1;
+};
+
+/**
+ * @param {number} a
+ * @param {number} b
+ */
+var add = function(a, b) {
+ return a + b;
+};
+
+/**
+ * @param {number} a
+ * @param {number} b
+ */
+var sub = function(a, b) {
+ return a - b;
+};
+
+/**
+ * @param {number} a
+ * @param {number} b
+ */
+var mul = function(a, b) {
+ return a * b;
+};
+
+/**
+ * @param {number} a
+ * @param {number} b
+ */
+var div = function(a, b) {
+ return a / b;
+};
+
+/**
+ * @param {number} a
+ * @param {number} b
+ * @return {number}
+ */
+var lessThan = function(a, b) {
+ return a < b ? 1 : 0;
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @return {Array<number>}
+ */
+var lessThanVec = function(a, b) {
+ var res = [];
+ for (var i = 0; i < a.length; i++)
+ res[i] = a[i] < b[i];
+ return res
+};
+
+/**
+ * @param {number} a
+ * @param {number} b
+ * @return {number}
+ */
+var lessThanEqual = function(a, b) {
+ return a <= b ? 1 : 0;
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @return {Array<number>}
+ */
+var lessThanEqualVec = function(a, b) {
+ var res = [];
+ for (var i = 0; i < a.length; i++)
+ res[i] = a[i] <= b[i];
+ return res;
+};
+
+/**
+ * @param {number} a
+ * @param {number} b
+ */
+var greaterThan = function(a, b) {
+ return a > b ? 1 : 0;
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @return {Array<number>}
+ */
+var greaterThanVec = function(a, b) {
+ var res = [];
+ for (var i = 0; i < a.length; i++)
+ res[i] = a[i] > b[i];
+ return res;
+};
+
+/**
+ * @param {number} a
+ * @param {number} b
+ */
+var greaterThanEqual = function(a, b) {
+ return a >= b ? 1 : 0;
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @return {Array<number>}
+ */
+var greaterThanEqualVec = function(a, b) {
+ var res = [];
+ for (var i = 0; i < a.length; i++)
+ res[i] = a[i] >= b[i];
+ return res;
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @return {number}
+ */
+var allEqual = function(a, b) {
+ return deMath.equal(a, b) ? 1 : 0;
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @return {Array<number>}
+ */
+var allEqualVec = function(a, b) {
+ var res = [];
+ for (var i = 0; i < a.length; i++)
+ res[i] = a[i] == b[i];
+ return res;
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @return {number}
+ */
+var anyNotEqual = function(a, b) {
+ return !deMath.equal(a, b) ? 1 : 0;
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @return {Array<number>}
+ */
+var anyNotEqualVec = function(a, b) {
+ var res = [];
+ for (var i = 0; i < a.length; i++)
+ res[i] = a[i] != b[i];
+ return res;
+};
+
+/**
+ * @param {Array<number>} a
+ * @return {Array<number>}
+ */
+var boolNotVec = function(a) {
+ var res = [];
+ for (var i = 0; i < a.length; i++)
+ res[i] = !a[i];
+ return res;
+}
+
+/**
+ * @param {Array<number>} a
+ * @return {boolean}
+ */
+var boolAny = function(a) {
+ for (var i = 0; i < a.length; i++)
+ if (a[i] == true)
+ return true;
+ return false;
+}
+
+/**
+ * @param {Array<number>} a
+ * @return {boolean}
+ */
+var boolAll = function(a) {
+ for (var i = 0; i < a.length; i++)
+ if (a[i] == false)
+ return false;
+ return true;
+}
+
+/**
+ * @param {number} a
+ * @param {number} b
+ */
+var logicalAnd = function(a, b) {
+ return a && b ? 1 : 0;
+};
+
+/**
+ * @param {number} a
+ * @param {number} b
+ */
+var logicalOr = function(a, b) {
+ return a || b ? 1 : 0;
+};
+
+/**
+ * @param {number} a
+ * @param {number} b
+ */
+var logicalXor = function(a, b) {
+ return a != b ? 1 : 0;
+};
+
+/**
+ * @param {number} a
+ */
+var exp2 = function(a) {
+ return deFloatExp2(a);
+};
+
+/**
+ * @param {number} a
+ */
+var inverseSqrt = function(a) {
+ return deFloatRsq(a);
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {number} b
+ * @return {Array<number>}
+ */
+var minVecScalar = function(a, b) {
+ var res = [];
+ for (var i = 0; i < a.length; i++)
+ res[i] = Math.min(a[i], b);
+ return res;
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {number} b
+ * @return {Array<number>}
+ */
+var maxVecScalar = function(a, b) {
+ var res = [];
+ for (var i = 0; i < a.length; i++)
+ res[i] = Math.max(a[i], b);
+ return res;
+};
+
+/**
+ * @param {number} a
+ * @param {number} b
+ * @param {number} c
+ * @return {number}
+ */
+var mix = function(a, b, c) {
+ return a * (1.0 - c) + b * c;
+};
+/**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @param {number} c
+ * @return {Array<number>}
+ */
+var mixVecVecScalar = function(a, b, c) {
+ var res = [];
+ for (var i = 0; i < a.length; i++)
+ res[i] = mix(a[i], b[i], c);
+ return res;
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {number} b
+ * @param {number} c
+ * @return {Array<number>}
+ */
+var clampVecScalarScalar = function(a, b, c) {
+ var res = [];
+ for (var i = 0; i < a.length; i++)
+ res[i] = deMath.clamp(a[i], b, c);
+ return res;
+};
+
+/**
+ * @param {number} a
+ * @param {number} b
+ * @return {number}
+ */
+var step = function(a, b) {
+ return b < a ? 0.0 : 1.0;
+};
+
+/**
+ * @param {number} a
+ * @param {Array<number>} b
+ * @return {Array<number>}
+ */
+var stepScalarVec = function(a, b) {
+ var res = [];
+ for (var i = 0; i < b.length; i++)
+ res[i] = step(a, b[i]);
+ return res;
+};
+
+/**
+ * @param {number} a
+ * @param {number} b
+ * @param {number} c
+ * @return {number}
+ */
+var smoothStep = function(a, b, c) {
+ if (c <= a) return 0.0;
+ if (c >= b) return 1.0;
+ var t = deMath.clamp((c - a) / (b - a), 0.0, 1.0);
+ return t * t * (3.0 - 2.0 * t);
+};
+
+/**
+ * @param {number} a
+ * @param {number} b
+ * @param {Array<number>} c
+ * @return {Array<number>}
+ */
+var smoothStepScalarScalarVec = function(a, b, c) {
+ var res = [];
+ for (var i = 0; i < c.length; i++)
+ res[i] = smoothStep(a, b, c[i]);
+ return res;
+};
+
+/**
+ * @param {number} a
+ * @return {number}
+ */
+var roundToEven = function(a) {
+ var q = deMath.deFloatFrac(a);
+ var r = a - q;
+
+ if (q > 0.5)
+ r += 1.0;
+ else if (q == 0.5 && r % 2 != 0)
+ r += 1.0;
+
+ return r;
+};
+
+/**
+ * @param {number} a
+ * @return {number}
+ */
+var fract = function(a) {
+ return a - Math.floor(a);
+};
+
+/**
+ * @param {number} a
+ * @return {number}
+ */
+var radians = function(a) {
+ return deFloatRadians(a);
+}
+
+/**
+ * @param {number} a
+ * @return {number}
+ */
+var degrees = function(a) {
+ return deFloatDegrees(a);
+}
+
+/**
+ * @param {number} a
+ * @param {Array<number>} b
+ */
+var addScalarVec = function(a, b) {
+ return deMath.addScalar(b, a);
+};
+
+/**
+ * @param {number} a
+ * @param {Array<number>} b
+ */
+var subScalarVec = function(a, b) {
+ var dst = [];
+ for (var i = 0; i < b.length; i++)
+ dst.push(a - b[i]);
+ return dst;
+};
+
+/**
+ * @param {number} a
+ * @param {Array<number>} b
+ */
+var mulScalarVec = function(a, b) {
+ var dst = [];
+ for (var i = 0; i < b.length; i++)
+ dst.push(a * b[i]);
+ return dst;
+};
+
+/**
+ * @param {number} a
+ * @param {Array<number>} b
+ */
+var divScalarVec = function(a, b) {
+ var dst = [];
+ for (var i = 0; i < b.length; i++)
+ dst.push(a / b[i]);
+ return dst;
+};
+
+/**
+ * @param {number} a
+ * @param {Array<number>} b
+ */
+var modScalarVec = function(a, b) {
+ var dst = [];
+ for (var i = 0; i < b.length; i++)
+ dst.push(a % b[i]);
+ return dst;
+};
+
+var bitwiseAndScalarVec = function(a, b) {
+ var dst = [];
+ for (var i = 0; i < b.length; i++)
+ dst.push(deMath.binaryOp(a, b[i], deMath.BinaryOp.AND));
+ return dst;
+};
+
+var bitwiseOrScalarVec = function(a, b) {
+ var dst = [];
+ for (var i = 0; i < b.length; i++)
+ dst.push(deMath.binaryOp(a, b[i], deMath.BinaryOp.OR));
+ return dst;
+};
+
+var bitwiseXorScalarVec = function(a, b) {
+ var dst = [];
+ for (var i = 0; i < b.length; i++)
+ dst.push(deMath.binaryOp(a, b[i], deMath.BinaryOp.XOR));
+ return dst;
+};
+
+/**
+ * @param {Array<number>} a
+ * @return {number}
+ */
+var length = function(a) {
+ var squareSum = 0;
+ for (var i = 0; i < a.length; i++)
+ squareSum += a[i] * a[i];
+ return Math.sqrt(squareSum);
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @return {number}
+ */
+var distance = function(a, b) {
+ var res = deMath.subtract(a, b)
+ return length(res);
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @return {number}
+ */
+var dot = function(a, b) {
+ var res = deMath.multiply(a, b);
+ var sum = 0;
+ for (var i = 0; i < res.length; i++)
+ sum += res[i];
+ return sum;
+};
+
+/**
+ * @param {Array<number>} a
+ * @return {Array<number>}
+ */
+var normalize = function(a) {
+ var ooLen = 1 / length(a);
+ var res = [];
+ for (var i = 0; i < a.length; i++)
+ res[i] = ooLen * a[i];
+ return res;
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @param {Array<number>} c
+ * @return {Array<number>}
+ */
+var faceforward = function(a, b, c) {
+ return dot(c, b) < 0 ? a : deMath.scale(a, -1);
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @return {Array<number>}
+ */
+var reflect = function(a, b) {
+ return deMath.subtract(a, deMath.scale(deMath.scale(b, dot(b, a)), 2));
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @param {number} c
+ * @return {Array<number>}
+ */
+var refract = function(a, b, c) {
+ var cosAngle = dot(b, a);
+ var k = 1 - c * c * (1 - cosAngle * cosAngle);
+ if (k < 0) {
+ var res = new Array(a.length);
+ return res.fill(0)
+ } else
+ return deMath.subtract(deMath.scale(a, c), deMath.scale(b, c * cosAngle + Math.sqrt(k)));
+};
+
+/**
+ * @param {Array<number>} a
+ * @param {Array<number>} b
+ * @return {Array<number>}
+ */
+var cross = function(a, b) {
+ if (a.length != 3 || b.length != 3)
+ throw new Error('Arrays must have the size of 3');
+ return [
+ a[1] * b[2] - b[1] * a[2],
+ a[2] * b[0] - b[2] * a[0],
+ a[0] * b[1] - b[0] * a[1]];
+};
+
+var nop = function(v) {
+ return v;
+};
+
+var selection = function(cond, a, b) {
+ return cond ? a : b;
+};
+
+var boolNot = function(a) {
+ return !a;
+};
+
+var bitwiseNot = function(a) {
+ return ~a;
+};
+
+/**
+ * @param {number} x
+ * @return {number}
+ */
+var deFloatRadians = function(x) {
+ return x * (Math.PI / 180.0);
+};
+
+/**
+ * @param {number} x
+ * @return {number}
+ */
+var deFloatDegrees = function(x) {
+ return x * (180.0 / Math.PI);
+};
+
+/**
+ * @param {number} x
+ * @return {number}
+ */
+var deFloatExp2 = function(x) {
+ return Math.exp(x * Math.LN2);
+};
+
+/**
+ * @param {number} x
+ * @return {number}
+ */
+var deFloatLog2 = function(x) {
+ return Math.log(x) * Math.LOG2E;
+};
+
+/**
+ * @param {number} x
+ * @return {number}
+ */
+var deFloatRsq = function(x) {
+ var s = Math.sqrt(x);
+ return s == 0.0 ? 0.0 : (1.0 / s);
+};
+
+/**
+ * @constructor
+ * @param {boolean} low
+ * @param {boolean} medium
+ * @param {boolean} high
+ */
+es3fShaderOperatorTests.Precision = function(low, medium, high) {
+ this.low = low;
+ this.medium = medium;
+ this.high = high;
+};
+
+/** @const */ es3fShaderOperatorTests.Precision.Low = new es3fShaderOperatorTests.Precision(true, false, false);
+/** @const */ es3fShaderOperatorTests.Precision.Medium = new es3fShaderOperatorTests.Precision(false, true, false);
+/** @const */ es3fShaderOperatorTests.Precision.High = new es3fShaderOperatorTests.Precision(false, false, true);
+/** @const */ es3fShaderOperatorTests.Precision.LowMedium = new es3fShaderOperatorTests.Precision(true, true, false);
+/** @const */ es3fShaderOperatorTests.Precision.MediumHigh = new es3fShaderOperatorTests.Precision(false, true, true);
+/** @const */ es3fShaderOperatorTests.Precision.All = new es3fShaderOperatorTests.Precision(true, true, true);
+/** @const */ es3fShaderOperatorTests.Precision.None = new es3fShaderOperatorTests.Precision(false, false, false);
+
+/**
+ * @enum
+ */
+es3fShaderOperatorTests.ValueType = {
+ NONE: 0,
+ FLOAT: (1 << 0), // float scalar
+ FLOAT_VEC: (1 << 1), // float vector
+ FLOAT_GENTYPE: (1 << 2), // float scalar/vector
+ VEC3: (1 << 3), // vec3 only
+ MATRIX: (1 << 4), // matrix
+ BOOL: (1 << 5), // boolean scalar
+ BOOL_VEC: (1 << 6), // boolean vector
+ BOOL_GENTYPE: (1 << 7), // boolean scalar/vector
+ INT: (1 << 8), // int scalar
+ INT_VEC: (1 << 9), // int vector
+ INT_GENTYPE: (1 << 10), // int scalar/vector
+ UINT: (1 << 11), // uint scalar
+ UINT_VEC: (1 << 12), // uint vector
+ UINT_GENTYPE: (1 << 13) // uint scalar/vector
+};
+
+/**
+ * @param {es3fShaderOperatorTests.ValueType} type
+ * @return {boolean}
+ */
+es3fShaderOperatorTests.isBoolType = function(type) {
+ return (type & (es3fShaderOperatorTests.ValueType.BOOL | es3fShaderOperatorTests.ValueType.BOOL_VEC | es3fShaderOperatorTests.ValueType.BOOL_GENTYPE)) != 0;
+};
+
+/**
+ * @param {es3fShaderOperatorTests.ValueType} type
+ * @return {boolean}
+ */
+es3fShaderOperatorTests.isIntType = function(type) {
+ return (type & (es3fShaderOperatorTests.ValueType.INT | es3fShaderOperatorTests.ValueType.INT_VEC | es3fShaderOperatorTests.ValueType.INT_GENTYPE)) != 0;
+};
+
+/**
+ * @param {es3fShaderOperatorTests.ValueType} type
+ * @return {boolean}
+ */
+es3fShaderOperatorTests.isUintType = function(type) {
+ return (type & (es3fShaderOperatorTests.ValueType.UINT | es3fShaderOperatorTests.ValueType.UINT_VEC | es3fShaderOperatorTests.ValueType.UINT_GENTYPE)) != 0;
+};
+
+/**
+ * @param {es3fShaderOperatorTests.ValueType} type
+ * @return {boolean}
+ */
+es3fShaderOperatorTests.isScalarType = function(type) {
+ return type == es3fShaderOperatorTests.ValueType.FLOAT || type == es3fShaderOperatorTests.ValueType.BOOL || type == es3fShaderOperatorTests.ValueType.INT || type == es3fShaderOperatorTests.ValueType.UINT;
+};
+
+/**
+ * @param {es3fShaderOperatorTests.ValueType} type
+ * @return {boolean}
+ */
+es3fShaderOperatorTests.isFloatType = function(type) {
+ return (type & (es3fShaderOperatorTests.ValueType.FLOAT | es3fShaderOperatorTests.ValueType.FLOAT_VEC | es3fShaderOperatorTests.ValueType.FLOAT_GENTYPE)) != 0;
+};
+
+/**
+ * @param {gluShaderProgram.shaderType} shaderType
+ * @param {gluShaderUtil.precision} uintPrecision
+ * @return {number}
+ */
+es3fShaderOperatorTests.getGLSLUintMaxAsFloat = function(shaderType, uintPrecision) {
+ switch (uintPrecision) {
+ case gluShaderUtil.precision.PRECISION_LOWP:
+ var intPrecisionGL = gl.LOW_INT;
+ break;
+ case gluShaderUtil.precision.PRECISION_MEDIUMP:
+ var intPrecisionGL = gl.MEDIUM_INT;
+ break;
+ case gluShaderUtil.precision.PRECISION_HIGHP:
+ var intPrecisionGL = gl.HIGH_INT;
+ break;
+ default:
+ assertMsgOptions(false, 'Invalid shader type', false, false);
+ var intPrecisionGL = 0;
+ }
+
+ switch (shaderType) {
+ case gluShaderProgram.shaderType.VERTEX:
+ var shaderTypeGL = gl.VERTEX_SHADER;
+ break;
+ case gluShaderProgram.shaderType.FRAGMENT:
+ var shaderTypeGL = gl.FRAGMENT_SHADER;
+ break;
+ default:
+ assertMsgOptions(false, 'Invalid shader type', false, false);
+ var shaderTypeGL = 0;
+ }
+
+ /** @type {WebGLShaderPrecisionFormat } */ var sPrecision = gl.getShaderPrecisionFormat(shaderTypeGL, intPrecisionGL);
+ assertMsgOptions(gl.getError() === gl.NO_ERROR, 'glGetShaderPrecisionFormat failed', false, true);
+
+ if (!deMath.deInBounds32(sPrecision.rangeMin, 8, 32))
+ throw new Error('Out of range');
+
+ var numBitsInType = sPrecision.rangeMin + 1;
+ return Math.pow(2, numBitsInType) - 1;
+};
+
+/**
+ * @enum
+ */
+es3fShaderOperatorTests.OperationType = {
+ FUNCTION: 0,
+ OPERATOR: 1,
+ SIDE_EFFECT_OPERATOR: 2 // Test the side-effect (as opposed to the result) of a side-effect operator.
+};
+
+/**
+ * swizzling indices for assigning the tested function output to the correct color channel
+ */
+es3fShaderOperatorTests.outIndices = [];
+es3fShaderOperatorTests.outIndices[1] = [0];
+es3fShaderOperatorTests.outIndices[2] = [1, 2];
+es3fShaderOperatorTests.outIndices[3] = [0, 1, 2];
+es3fShaderOperatorTests.outIndices[4] = [0, 1, 2, 3];
+
+var convert = function(input, dataType) {
+ switch (dataType) {
+ case gluShaderUtil.DataType.INT:
+ if (input instanceof Array) {
+ var ret = [];
+ for (var i = 0; i < input.length; i++)
+ ret[i] = deMath.intCast(input[i]);
+ return ret;
+ }
+ return deMath.intCast(input);
+ case gluShaderUtil.DataType.UINT:
+ if (input instanceof Array) {
+ var ret = [];
+ for (var i = 0; i < input.length; i++)
+ ret[i] = deMath.uintCast(input[i]);
+ return ret;
+ }
+ return deMath.uintCast(input);
+ case gluShaderUtil.DataType.BOOL:
+ if (input instanceof Array) {
+ var ret = [];
+ for (var i = 0; i < input.length; i++)
+ ret[i] = input[i] > 0 ? 1 : 0;
+ return ret;
+ }
+ return input > 0 ? 1 : 0;
+
+ }
+ return input;
+};
+
+/**
+ * Generate unary functions which have the same input and return type
+ * @param {function(number): number} func
+ * @param {gluShaderUtil.DataType=} dataTypeIn
+ * @param {gluShaderUtil.DataType=} dataTypeOut
+ */
+es3fShaderOperatorTests.unaryGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) {
+ var run = function(output, func, input) {
+ if (input instanceof Array) {
+ var len = input.length;
+ var indices = es3fShaderOperatorTests.outIndices[len];
+ for (var i = 0; i < input.length; i++)
+ output[indices[i]] = convert(func(convert(input[i], dataTypeIn)), dataTypeOut);
+ } else
+ output[0] = convert(func(convert(input, dataTypeIn)), dataTypeOut);
+ };
+
+ var functions = {};
+ functions.scalar = function(c) { run(c.color, func, c.in_[0][2]); };
+ functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1])); };
+ functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1])); };
+ functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0])); };
+ return functions;
+};
+
+/**
+ * Generate unary functions which have the same input and return type
+ * @param {function(Array<number>): Array<number>} func
+ * @param {gluShaderUtil.DataType=} dataTypeIn
+ * @param {gluShaderUtil.DataType=} dataTypeOut
+ */
+es3fShaderOperatorTests.unaryArrayFuncs = function(func, dataTypeOut, dataTypeIn) {
+ var run = function(output, func, input) {
+ var len = input.length;
+ var indices = es3fShaderOperatorTests.outIndices[len];
+ var value = convert(func(convert(input, dataTypeIn)), dataTypeOut);
+ for (var i = 0; i < input.length; i++)
+ output[indices[i]] = value[i];
+ };
+
+ var functions = {};
+ functions.scalar = function(c) { run(c.color, func, [c.in_[0][2]]); };
+ functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1])); };
+ functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1])); };
+ functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0])); };
+ return functions;
+};
+
+/**
+ * Generate unary functions which always have scalar return type
+ * @param {function(Array<number>): number} func
+ * @param {gluShaderUtil.DataType=} dataTypeIn
+ * @param {gluShaderUtil.DataType=} dataTypeOut
+ */
+es3fShaderOperatorTests.unaryScalarGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) {
+ var run = function(output, func, input) {
+ output[0] = convert(func(convert(input, dataTypeIn)), dataTypeOut);
+ };
+
+ var functions = {};
+ functions.scalar = function(c) { run(c.color, func, [c.in_[0][2]]); };
+ functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1])); };
+ functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1])); };
+ functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0])); };
+ return functions;
+};
+
+/**
+ * Generate unary functions which always have bolean return type
+ * @param {function(Array<number>): boolean} func
+ * @param {gluShaderUtil.DataType=} dataTypeIn
+ * @param {gluShaderUtil.DataType=} dataTypeOut
+ */
+es3fShaderOperatorTests.unaryBooleanGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) {
+ var run = function(output, func, input) {
+ output[0] = convert(func(convert(input, dataTypeIn)), dataTypeOut);
+ };
+
+ var functions = {};
+ functions.scalar = function(c) { run(c.color, func, [c.in_[0][2] > 0.0]); };
+ functions.vec2 = function(c) { run(c.color, func, greaterThanVec(deMath.swizzle(c.in_[0], [3, 1]), [0, 0])); };
+ functions.vec3 = function(c) { run(c.color, func, greaterThanVec(deMath.swizzle(c.in_[0], [2, 0, 1]), [0, 0, 0])); };
+ functions.vec4 = function(c) { run(c.color, func, greaterThanVec(deMath.swizzle(c.in_[0], [1, 2, 3, 0]), [0, 0, 0, 0])); };
+ return functions;
+};
+
+/**
+ * Generate binary functions which have the same input and return type
+ * @param {function(number, number): number} func
+ * @param {gluShaderUtil.DataType=} dataTypeIn
+ * @param {gluShaderUtil.DataType=} dataTypeOut
+ */
+es3fShaderOperatorTests.binaryGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) {
+ var run = function(output, func, input1, input2) {
+ if (input1 instanceof Array) {
+ var len = input1.length;
+ var indices = es3fShaderOperatorTests.outIndices[len];
+ for (var i = 0; i < input1.length; i++)
+ output[indices[i]] = convert(func(convert(input1[i], dataTypeIn), convert(input2[i], dataTypeIn)), dataTypeOut);
+ } else {
+ var value = convert(func(convert(input1, dataTypeIn), convert(input2, dataTypeIn)), dataTypeOut);
+ output[0] = value;
+ }
+ };
+
+ var functions = {};
+ functions.scalar = function(c) { run(c.color, func, c.in_[0][2], c.in_[1][0]); };
+ functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), deMath.swizzle(c.in_[1], [1, 0])); };
+ functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), deMath.swizzle(c.in_[1], [1, 2, 0])); };
+ functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), deMath.swizzle(c.in_[1], [3, 2, 1, 0])); };
+ return functions;
+};
+
+/**
+ * Generate binary functions which have the same input and return type
+ * @param {function(number, number, number): number} func
+ * @param {gluShaderUtil.DataType=} dataTypeIn
+ * @param {gluShaderUtil.DataType=} dataTypeOut
+ */
+es3fShaderOperatorTests.ternaryGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) {
+ var run = function(output, func, input1, input2, input3) {
+ if (input1 instanceof Array) {
+ var len = input1.length;
+ var indices = es3fShaderOperatorTests.outIndices[len];
+ for (var i = 0; i < input1.length; i++)
+ output[indices[i]] = convert(func(convert(input1[i], dataTypeIn), convert(input2[i], dataTypeIn), convert(input3[i], dataTypeIn)), dataTypeOut);
+ } else {
+ var value = convert(func(convert(input1, dataTypeIn), convert(input2, dataTypeIn), convert(input3, dataTypeIn)), dataTypeOut);
+ output[0] = value;
+ }
+ };
+
+ var functions = {};
+ functions.scalar = function(c) { run(c.color, func, c.in_[0][2], c.in_[1][0], c.in_[2][1]); };
+ functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), deMath.swizzle(c.in_[1], [1, 0]), deMath.swizzle(c.in_[2], [2, 1])); };
+ functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), deMath.swizzle(c.in_[1], [1, 2, 0]), deMath.swizzle(c.in_[2], [3, 1, 2])); };
+ functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), deMath.swizzle(c.in_[1], [3, 2, 1, 0]), deMath.swizzle(c.in_[2], [0, 3, 2, 1])); };
+ return functions;
+};
+
+/**
+ * Generate binary functions which have the same input and return type
+ * @param {function(Array<number>, Array<number>): number} func
+ * @param {gluShaderUtil.DataType=} dataTypeIn
+ * @param {gluShaderUtil.DataType=} dataTypeOut
+ */
+es3fShaderOperatorTests.binaryScalarGenTypeFuncs = function(func, dataTypeOut, dataTypeIn) {
+ var run = function(output, func, input1, input2) {
+ var value = convert(func(convert(input1, dataTypeIn), convert(input2, dataTypeIn)), dataTypeOut);
+ output[0] = value;
+ };
+
+ var functions = {};
+ functions.scalar = function(c) { run(c.color, func, [c.in_[0][2]], [c.in_[1][0]]); };
+ functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), deMath.swizzle(c.in_[1], [1, 0])); };
+ functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), deMath.swizzle(c.in_[1], [1, 2, 0])); };
+ functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), deMath.swizzle(c.in_[1], [3, 2, 1, 0])); };
+ return functions;
+};
+
+/**
+ * Generate (cond ? a : b) functions
+ * @param {gluShaderUtil.DataType} dataType
+ * Returns an array of functions, indexed by datatype size
+ */
+es3fShaderOperatorTests.selectionFuncs = function(dataType) {
+ var run = function(output, input0, input1, input2) {
+ var value = selection(input0, input1, input2);
+ value = convert(value, dataType);
+ if (value instanceof Array) {
+ var len = value.length;
+ var indices = es3fShaderOperatorTests.outIndices[len];
+ for (var i = 0; i < len; i++)
+ output[indices[i]] = value[i];
+ } else
+ output[0] = value;
+ };
+
+ var functions = [];
+ functions[1] = function(c) { run(c.color, c.in_[0][2] > 0, c.in_[1][0], c.in_[2][1]); };
+ functions[2] = function(c) { run(c.color, c.in_[0][2] > 0, deMath.swizzle(c.in_[1], [1, 0]), deMath.swizzle(c.in_[2], [2, 1])); };
+ functions[3] = function(c) { run(c.color, c.in_[0][2] > 0, deMath.swizzle(c.in_[1], [1, 2, 0]), deMath.swizzle(c.in_[2], [3, 1, 2])); };
+ functions[4] = function(c) { run(c.color, c.in_[0][2] > 0, deMath.swizzle(c.in_[1], [3, 2, 1, 0]), deMath.swizzle(c.in_[2], [0, 3, 2, 1])); };
+ return functions;
+};
+
+var cp = function(dst, src) {
+ var len = src.length;
+ var indices = es3fShaderOperatorTests.outIndices[len];
+ for (var i = 0; i < len; i++)
+ dst[indices[i]] = src[i];
+};
+
+/**
+ * Generate binary functions of form: vec = func(scalar, vec)
+ * @param {function(number, Array<number>): Array<number>} func
+ * @param {gluShaderUtil.DataType=} dataTypeIn
+ * @param {gluShaderUtil.DataType=} dataTypeOut
+ */
+es3fShaderOperatorTests.binaryScalarVecFuncs = function(func, dataTypeOut, dataTypeIn) {
+ /**
+ * @param {function(number, Array<number>): Array<number>} func
+ * @param {number} input1
+ * @param {Array<number>} input2
+ */
+ var run = function(output, func, input1, input2) {
+ var in1 = convert(input1, dataTypeIn);
+ var in2 = convert(input2, dataTypeIn);
+ var value = func(in1, in2);
+ value = convert(value, dataTypeOut);
+ cp(output, value);
+ };
+ var functions = {};
+ functions.vec2 = function(c) { run(c.color, func, c.in_[0][2], deMath.swizzle(c.in_[1], [1, 0])); };
+ functions.vec3 = function(c) { run(c.color, func, c.in_[0][2], deMath.swizzle(c.in_[1], [1, 2, 0])); };
+ functions.vec4 = function(c) { run(c.color, func, c.in_[0][2], deMath.swizzle(c.in_[1], [3, 2, 1, 0])); };
+ return functions;
+};
+
+/**
+ * Generate binary functions of form: vec = func(vec, scalar)
+ * @param {function(Array<number>, number): Array<number>} func
+ * @param {gluShaderUtil.DataType=} dataTypeIn
+ * @param {gluShaderUtil.DataType=} dataTypeOut
+ */
+es3fShaderOperatorTests.binaryVecScalarFuncs = function(func, dataTypeOut, dataTypeIn) {
+ /**
+ * @param {function(Array<number>, number): Array<number>} func
+ * @param {Array<number>} input1
+ * @param {number} input2
+ */
+ var run = function(output, func, input1, input2) {
+ var in1 = convert(input1, dataTypeIn);
+ var in2 = convert(input2, dataTypeIn);
+ var value = func(in1, in2);
+ value = convert(value, dataTypeOut);
+ cp(output, value);
+ };
+ var functions = {};
+ functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), c.in_[1][0]); };
+ functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), c.in_[1][0]); };
+ functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), c.in_[1][0]); };
+ return functions;
+};
+
+/**
+ * Generate binary functions of form: vec = func(vec, vec, scalar)
+ * @param {function(Array<number>, Array<number>, number): Array<number>} func
+ * @param {gluShaderUtil.DataType=} dataTypeIn
+ * @param {gluShaderUtil.DataType=} dataTypeOut
+ */
+es3fShaderOperatorTests.ternaryVecVecScalarFuncs = function(func, dataTypeOut, dataTypeIn) {
+ /**
+ * @param {function(Array<number>, Array<number>, number): Array<number>} func
+ * @param {Array<number>} input1
+ * @param {Array<number>} input2
+ * @param {number} input3
+ */
+ var run = function(output, func, input1, input2, input3) {
+ var in1 = convert(input1, dataTypeIn);
+ var in2 = convert(input2, dataTypeIn);
+ var in3 = convert(input3, dataTypeIn);
+ var value = func(in1, in2, in3);
+ value = convert(value, dataTypeOut);
+ cp(output, value);
+ };
+ var functions = {};
+ functions.scalar = function(c) { run(c.color, func, [c.in_[0][2]], [c.in_[1][0]], c.in_[2][1]); };
+ functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), deMath.swizzle(c.in_[1], [1, 0]), c.in_[2][1]); };
+ functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), deMath.swizzle(c.in_[1], [1, 2, 0]), c.in_[2][1]); };
+ functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), deMath.swizzle(c.in_[1], [3, 2, 1, 0]), c.in_[2][1]); };
+ return functions;
+};
+
+/**
+ * Generate binary functions of form: vec = func(vec, scalar, scalar)
+ * @param {function(Array<number>, number, number): Array<number>} func
+ * @param {gluShaderUtil.DataType=} dataTypeIn
+ * @param {gluShaderUtil.DataType=} dataTypeOut
+ */
+es3fShaderOperatorTests.ternaryVecScalarScalarFuncs = function(func, dataTypeOut, dataTypeIn) {
+ /**
+ * @param {function(Array<number>, number, number): Array<number>} func
+ * @param {Array<number>} input1
+ * @param {number} input2
+ * @param {number} input3
+ */
+ var run = function(output, func, input1, input2, input3) {
+ var in1 = convert(input1, dataTypeIn);
+ var in2 = convert(input2, dataTypeIn);
+ var in3 = convert(input3, dataTypeIn);
+ var value = func(in1, in2, in3);
+ value = convert(value, dataTypeOut);
+ cp(output, value);
+ };
+ var functions = {};
+ functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), c.in_[1][0], c.in_[2][1]); };
+ functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), c.in_[1][0], c.in_[2][1]); };
+ functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), c.in_[1][0], c.in_[2][1]); };
+ return functions;
+};
+
+/**
+ * Generate binary functions of form: vec = func(scalar, scalar, vec)
+ * @param {function(number, number, Array<number>): Array<number>} func
+ * @param {gluShaderUtil.DataType=} dataTypeIn
+ * @param {gluShaderUtil.DataType=} dataTypeOut
+ */
+es3fShaderOperatorTests.ternaryScalarScalarVecFuncs = function(func, dataTypeOut, dataTypeIn) {
+ /**
+ * @param {function(number, number, Array<number>): Array<number>} func
+ * @param {number} input1
+ * @param {number} input2
+ * @param {Array<number>} input3
+ */
+ var run = function(output, func, input1, input2, input3) {
+ var in1 = convert(input1, dataTypeIn);
+ var in2 = convert(input2, dataTypeIn);
+ var in3 = convert(input3, dataTypeIn);
+ var value = func(in1, in2, in3);
+ value = convert(value, dataTypeOut);
+ cp(output, value);
+ };
+ var functions = {};
+ functions.vec2 = function(c) { run(c.color, func, c.in_[0][2], c.in_[1][0], deMath.swizzle(c.in_[2], [2, 1])); };
+ functions.vec3 = function(c) { run(c.color, func, c.in_[0][2], c.in_[1][0], deMath.swizzle(c.in_[2], [3, 1, 2])); };
+ functions.vec4 = function(c) { run(c.color, func, c.in_[0][2], c.in_[1][0], deMath.swizzle(c.in_[2], [0, 3, 2, 1])); };
+ return functions;
+};
+
+/**
+ * Generate binary functions of form: vec = func(vec, vec, vec)
+ * @param {function(Array<number>, Array<number>, Array<number>): Array<number>} func
+ * @param {gluShaderUtil.DataType=} dataTypeIn
+ * @param {gluShaderUtil.DataType=} dataTypeOut
+ */
+es3fShaderOperatorTests.ternaryVecVecVecFuncs = function(func, dataTypeOut, dataTypeIn) {
+ /**
+ * @param {function(Array<number>, Array<number>, Array<number>): Array<number>} func
+ * @param {Array<number>} input1
+ * @param {Array<number>} input2
+ * @param {Array<number>} input3
+ */
+ var run = function(output, func, input1, input2, input3) {
+ var in1 = convert(input1, dataTypeIn);
+ var in2 = convert(input2, dataTypeIn);
+ var in3 = convert(input3, dataTypeIn);
+ var value = func(in1, in2, in3);
+ value = convert(value, dataTypeOut);
+ cp(output, value);
+ };
+ var functions = {};
+ functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), deMath.swizzle(c.in_[1], [1, 0]), deMath.swizzle(c.in_[2], [2, 1])); };
+ functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), deMath.swizzle(c.in_[1], [1, 2, 0]), deMath.swizzle(c.in_[2], [3, 1, 2])); };
+ functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), deMath.swizzle(c.in_[1], [3, 2, 1, 0]), deMath.swizzle(c.in_[2], [0, 3, 2, 1])); };
+ return functions;
+};
+
+/**
+ * Generate binary functions of form: vec = func(vec, vec)
+ * @param {function(Array<number>, Array<number>): Array<number>} func
+ * @param {gluShaderUtil.DataType=} dataTypeIn
+ * @param {gluShaderUtil.DataType=} dataTypeOut
+ */
+es3fShaderOperatorTests.binaryVecVecFuncs = function(func, dataTypeOut, dataTypeIn) {
+ /**
+ * @param {function(Array<number>, Array<number>): Array<number>} func
+ * @param {Array<number>} input1
+ * @param {Array<number>} input2
+ */
+ var run = function(output, func, input1, input2) {
+ var in1 = convert(input1, dataTypeIn);
+ var in2 = convert(input2, dataTypeIn);
+ var value = func(in1, in2);
+ value = convert(value, dataTypeOut);
+ cp(output, value);
+ };
+ var functions = {};
+ functions.vec2 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [3, 1]), deMath.swizzle(c.in_[1], [1, 0])); };
+ functions.vec3 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [2, 0, 1]), deMath.swizzle(c.in_[1], [1, 2, 0])); };
+ functions.vec4 = function(c) { run(c.color, func, deMath.swizzle(c.in_[0], [1, 2, 3, 0]), deMath.swizzle(c.in_[1], [3, 2, 1, 0])); };
+ return functions;
+};
+
+/**
+ * @constructor
+ * @param {es3fShaderOperatorTests.ValueType} valueType
+ * @param {es3fShaderOperatorTests.FloatScalar} rangeMin
+ * @param {es3fShaderOperatorTests.FloatScalar} rangeMax
+ */
+es3fShaderOperatorTests.Value = function(valueType, rangeMin, rangeMax) {
+ this.valueType = valueType;
+ this.rangeMin = rangeMin;
+ this.rangeMax = rangeMax;
+};
+
+/**
+ * @enum
+ */
+es3fShaderOperatorTests.Symbol = {
+ SYMBOL_LOWP_UINT_MAX: 0,
+ SYMBOL_MEDIUMP_UINT_MAX: 1,
+
+ SYMBOL_LOWP_UINT_MAX_RECIPROCAL: 2,
+ SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL: 3,
+
+ SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX: 4,
+ SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX: 5
+
+};
+
+/**
+ * @constructor
+ * @param {number|es3fShaderOperatorTests.Symbol} value
+ * @param {boolean=} isSymbol
+ */
+es3fShaderOperatorTests.FloatScalar = function(value, isSymbol) {
+ if (isSymbol)
+ this.symbol = /** @type {es3fShaderOperatorTests.Symbol} */ (value);
+ else
+ this.constant = /** @type {number} */ (value);
+};
+
+/**
+ * @param {gluShaderProgram.shaderType} shaderType
+ * @return {number}
+ */
+es3fShaderOperatorTests.FloatScalar.prototype.getValue = function(shaderType) {
+ if (this.constant !== undefined)
+ return this.constant;
+ else
+ switch (this.symbol) {
+ case es3fShaderOperatorTests.Symbol.SYMBOL_LOWP_UINT_MAX:
+ return es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_LOWP);
+ case es3fShaderOperatorTests.Symbol.SYMBOL_MEDIUMP_UINT_MAX:
+ return es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_MEDIUMP);
+
+ case es3fShaderOperatorTests.Symbol.SYMBOL_LOWP_UINT_MAX_RECIPROCAL:
+ return 1.0 / es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_LOWP);
+ case es3fShaderOperatorTests.Symbol.SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL:
+ return 1.0 / es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_MEDIUMP);
+
+ case es3fShaderOperatorTests.Symbol.SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX:
+ return 1.0 - 0xFFFFFFFF / es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_LOWP);
+ case es3fShaderOperatorTests.Symbol.SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX:
+ return 1.0 - 0xFFFFFFFF / es3fShaderOperatorTests.getGLSLUintMaxAsFloat(shaderType, gluShaderUtil.precision.PRECISION_MEDIUMP);
+
+ default:
+ assertMsgOptions(false, 'Invalid shader type', false, false);
+ return 0.0;
+ }
+};
+
+/**
+ * @constructor
+ * @param {gluShaderUtil.DataType=} type
+ * @param {es3fShaderOperatorTests.FloatScalar=} rangeMin
+ * @param {es3fShaderOperatorTests.FloatScalar=} rangeMax
+ */
+es3fShaderOperatorTests.ShaderValue = function(type, rangeMin, rangeMax) {
+ this.type = type || gluShaderUtil.DataType.INVALID;
+ this.rangeMin = rangeMin || new es3fShaderOperatorTests.FloatScalar(0);
+ this.rangeMax = rangeMax || new es3fShaderOperatorTests.FloatScalar(0);
+};
+
+/**
+ * @constructor
+ */
+es3fShaderOperatorTests.ShaderDataSpec = function() {
+ /** @type {es3fShaderOperatorTests.FloatScalar} */ this.resultScale = new es3fShaderOperatorTests.FloatScalar(1);
+ /** @type {es3fShaderOperatorTests.FloatScalar} */ this.resultBias = new es3fShaderOperatorTests.FloatScalar(0);
+ /** @type {es3fShaderOperatorTests.FloatScalar} */ this.referenceScale = new es3fShaderOperatorTests.FloatScalar(1);
+ /** @type {es3fShaderOperatorTests.FloatScalar} */ this.referenceBias = new es3fShaderOperatorTests.FloatScalar(0);
+ /** @type {es3fShaderOperatorTests.Precision} */ this.precision = es3fShaderOperatorTests.Precision.None;
+ /** @type {gluShaderUtil.DataType} */ this.output;
+ /** @type {number} */ this.numInputs = 0;
+ /** @type {Array<es3fShaderOperatorTests.ShaderValue>}*/ this.inputs = [];
+ for (var i = 0; i < es3fShaderOperatorTests.MAX_INPUTS; i++)
+ this.inputs[i] = new es3fShaderOperatorTests.ShaderValue();
+};
+
+/**
+ * @constructor
+ * @struct
+ * @param {string} caseName
+ * @param {string} shaderFuncName
+ * @param {es3fShaderOperatorTests.ValueType} outValue
+ * @param {Array<es3fShaderOperatorTests.Value>} inputs
+ * @param {es3fShaderOperatorTests.FloatScalar} resultScale
+ * @param {es3fShaderOperatorTests.FloatScalar} resultBias
+ * @param {es3fShaderOperatorTests.FloatScalar} referenceScale
+ * @param {es3fShaderOperatorTests.FloatScalar} referenceBias
+ * @param {gluShaderUtil.precision} precision
+ * @param {*} functions
+ * @param {es3fShaderOperatorTests.OperationType=} type
+ * @param {boolean=} isUnaryPrefix
+ */
+es3fShaderOperatorTests.BuiltinFuncInfo = function(caseName, shaderFuncName, outValue, inputs, resultScale, resultBias, referenceScale, referenceBias, precision, functions, type, isUnaryPrefix) {
+ this.caseName = caseName;
+ this.shaderFuncName = shaderFuncName;
+ this.outValue = outValue;
+ this.inputs = inputs;
+ this.resultScale = resultScale;
+ this.resultBias = resultBias;
+ this.referenceScale = referenceScale;
+ this.referenceBias = referenceBias;
+ this.precision = precision;
+ this.evalFunctions = functions;
+ this.type = type || es3fShaderOperatorTests.OperationType.FUNCTION;
+ this.isUnaryPrefix = isUnaryPrefix === undefined ? true : isUnaryPrefix;
+};
+
+es3fShaderOperatorTests.builtinOperInfo = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions) {
+ return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName,
+ shaderFuncName,
+ outValue,
+ inputs,
+ scale,
+ bias,
+ scale,
+ bias,
+ precision,
+ functions,
+ es3fShaderOperatorTests.OperationType.OPERATOR);
+};
+
+es3fShaderOperatorTests.builtinFunctionInfo = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions) {
+ return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName,
+ shaderFuncName,
+ outValue,
+ inputs,
+ scale,
+ bias,
+ scale,
+ bias,
+ precision,
+ functions,
+ es3fShaderOperatorTests.OperationType.FUNCTION);
+};
+
+es3fShaderOperatorTests.builtinSideEffOperInfo = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions) {
+ return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName,
+ shaderFuncName,
+ outValue,
+ inputs,
+ scale,
+ bias,
+ scale,
+ bias,
+ precision,
+ functions,
+ es3fShaderOperatorTests.OperationType.SIDE_EFFECT_OPERATOR);
+};
+
+es3fShaderOperatorTests.builtinOperInfoSeparateRefScaleBias = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions, referenceScale, referenceBias) {
+ return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName,
+ shaderFuncName,
+ outValue,
+ inputs,
+ scale,
+ bias,
+ referenceScale,
+ referenceBias,
+ precision,
+ functions,
+ es3fShaderOperatorTests.OperationType.OPERATOR);
+};
+
+es3fShaderOperatorTests.BuiltinPostSideEffOperInfo = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions) {
+ return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName,
+ shaderFuncName,
+ outValue,
+ inputs,
+ scale,
+ bias,
+ scale,
+ bias,
+ precision,
+ functions,
+ es3fShaderOperatorTests.OperationType.SIDE_EFFECT_OPERATOR,
+ false);
+};
+es3fShaderOperatorTests.BuiltinPostOperInfo = function(caseName, shaderFuncName, outValue, inputs, scale, bias, precision, functions) {
+ return new es3fShaderOperatorTests.BuiltinFuncInfo(caseName,
+ shaderFuncName,
+ outValue,
+ inputs,
+ scale,
+ bias,
+ scale,
+ bias,
+ precision,
+ functions,
+ es3fShaderOperatorTests.OperationType.OPERATOR,
+ false);
+};
+
+/**
+ * @constructor
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderOperatorTests.BuiltinFuncGroup = function(name, description) {
+ this.name = name;
+ this.description = description;
+ this.funcInfos = [];
+};
+
+es3fShaderOperatorTests.BuiltinFuncGroup.prototype.push = function(a) { this.funcInfos.push(a); };
+
+var s_inSwizzles = [
+
+ ['z', 'wy', 'zxy', 'yzwx'],
+ ['x', 'yx', 'yzx', 'wzyx'],
+ ['y', 'zy', 'wyz', 'xwzy']
+];
+
+var s_outSwizzles = ['x', 'yz', 'xyz', 'xyzw'];
+
+var s_outSwizzleChannelMasks = [
+ [true, false, false, false],
+ [false, true, true, false],
+ [true, true, true, false],
+ [true, true, true, true]
+];
+
+/**
+ * @constructor
+ * @extends {glsShaderRenderCase.ShaderEvaluator}
+ * @param {gluShaderProgram.shaderType} shaderType
+ * @param {glsShaderRenderCase.ShaderEvalFunc} evalFunc
+ * @param {es3fShaderOperatorTests.FloatScalar} scale
+ * @param {es3fShaderOperatorTests.FloatScalar} bias
+ * @param {number} resultScalarSize
+ */
+es3fShaderOperatorTests.OperatorShaderEvaluator = function(shaderType, evalFunc, scale, bias, resultScalarSize) {
+ glsShaderRenderCase.ShaderEvaluator.call(this, evalFunc);
+ this.m_shaderType = shaderType;
+ this.m_scale = scale;
+ this.m_bias = bias;
+ this.m_resultScalarSize = resultScalarSize;
+ this.m_areScaleAndBiasEvaluated = false;
+};
+
+setParentClass(es3fShaderOperatorTests.OperatorShaderEvaluator, glsShaderRenderCase.ShaderEvaluator);
+
+es3fShaderOperatorTests.OperatorShaderEvaluator.prototype.evaluate = function(ctx) {
+ this.m_evalFunc(ctx);
+
+ if (!this.m_areScaleAndBiasEvaluated) {
+ this.m_evaluatedScale = this.m_scale.getValue(this.m_shaderType);
+ this.m_evaluatedBias = this.m_bias.getValue(this.m_shaderType);
+ this.m_areScaleAndBiasEvaluated = true;
+ }
+
+ for (var i = 0; i < 4; i++)
+ if (s_outSwizzleChannelMasks[this.m_resultScalarSize - 1][i])
+ ctx.color[i] = ctx.color[i] * this.m_evaluatedScale + this.m_evaluatedBias;
+};
+
+/**
+ * @constructor
+ * @extends {glsShaderRenderCase.ShaderRenderCase}
+ * @param {string} caseName
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {glsShaderRenderCase.ShaderEvalFunc} evalFunc
+ * @param {string} shaderOp
+ * @param {es3fShaderOperatorTests.ShaderDataSpec} spec
+ */
+es3fShaderOperatorTests.ShaderOperatorCase = function(caseName, description, isVertexCase, evalFunc, shaderOp, spec) {
+ glsShaderRenderCase.ShaderRenderCase.call(this, caseName, description, isVertexCase, evalFunc);
+ this.m_spec = spec;
+ this.m_shaderOp = shaderOp;
+ var shaderType = isVertexCase ? gluShaderProgram.shaderType.VERTEX : gluShaderProgram.shaderType.FRAGMENT;
+ this.m_evaluator = new es3fShaderOperatorTests.OperatorShaderEvaluator(shaderType,
+ evalFunc,
+ spec.referenceScale,
+ spec.referenceBias,
+ gluShaderUtil.getDataTypeScalarSize(spec.output));
+};
+
+setParentClass(es3fShaderOperatorTests.ShaderOperatorCase, glsShaderRenderCase.ShaderRenderCase);
+
+es3fShaderOperatorTests.ShaderOperatorCase.prototype.setupShaderData = function() {
+ var shaderType = this.m_isVertexCase ? gluShaderProgram.shaderType.VERTEX : gluShaderProgram.shaderType.FRAGMENT;
+ var precision = this.m_spec.precision !== undefined ? gluShaderUtil.getPrecisionName(this.m_spec.precision) : null;
+ var inputPrecision = [];
+ var sources = [];
+ sources[0] = ''; //vertex
+ sources[1] = ''; //fragment
+ var vtx = 0;
+ var frag = 1;
+ var op = this.m_isVertexCase ? vtx : frag;
+
+ sources[vtx] += '#version 300 es\n';
+ sources[frag] += '#version 300 es\n';
+
+ // Compute precision for inputs.
+ for (var i = 0; i < this.m_spec.numInputs; i++) {
+ var isBoolVal = gluShaderUtil.isDataTypeBoolOrBVec(this.m_spec.inputs[i].type);
+ var isIntVal = gluShaderUtil.isDataTypeIntOrIVec(this.m_spec.inputs[i].type);
+ var isUintVal = gluShaderUtil.isDataTypeUintOrUVec(this.m_spec.inputs[i].type);
+ // \note Mediump interpolators are used for booleans, and highp for integers.
+ var prec = isBoolVal ? gluShaderUtil.precision.PRECISION_MEDIUMP :
+ isIntVal || isUintVal ? gluShaderUtil.precision.PRECISION_HIGHP :
+ this.m_spec.precision;
+ inputPrecision[i] = gluShaderUtil.getPrecisionName(prec);
+ }
+
+ // Attributes.
+ sources[vtx] += 'in highp vec4 a_position;\n';
+ for (var i = 0; i < this.m_spec.numInputs; i++)
+ sources[vtx] += 'in ' + inputPrecision[i] + ' vec4 a_in' + i + ';\n';
+
+ // Color output.
+ sources[frag] += 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ if (this.m_isVertexCase) {
+ sources[vtx] += 'out mediump vec4 v_color;\n';
+ sources[frag] += 'in mediump vec4 v_color;\n';
+ } else{
+ for (var i = 0; i < this.m_spec.numInputs; i++) {
+ sources[vtx] += 'out ' + inputPrecision[i] + ' vec4 v_in' + i + ';\n';
+ sources[frag] += 'in ' + inputPrecision[i] + ' vec4 v_in' + i + ';\n';
+ }
+ }
+
+ sources[vtx] += '\n';
+ sources[vtx] += 'void main()\n';
+ sources[vtx] += '{\n';
+ sources[vtx] += ' gl_Position = a_position;\n';
+
+ sources[frag] += '\n';
+ sources[frag] += 'void main()\n';
+ sources[frag] += '{\n';
+
+ // Expression inputs.
+ var prefix = this.m_isVertexCase ? 'a_' : 'v_';
+ for (var i = 0; i < this.m_spec.numInputs; i++) {
+ var inType = this.m_spec.inputs[i].type;
+ var inSize = gluShaderUtil.getDataTypeScalarSize(inType);
+ var isInt = gluShaderUtil.isDataTypeIntOrIVec(inType);
+ var isUint = gluShaderUtil.isDataTypeUintOrUVec(inType);
+ var isBool = gluShaderUtil.isDataTypeBoolOrBVec(inType);
+ var typeName = gluShaderUtil.getDataTypeName(inType);
+ var swizzle = s_inSwizzles[i][inSize - 1];
+
+ sources[op] += '\t';
+ if (precision && !isBool) sources[op] += precision + ' ';
+
+ sources[op] += typeName + ' in' + i + ' = ';
+
+ if (isBool) {
+ if (inSize == 1) sources[op] += '(';
+ else sources[op] += 'greaterThan(';
+ } else if (isInt || isUint)
+ sources[op] += typeName + '(';
+
+ sources[op] += prefix + 'in' + i + '.' + swizzle;
+
+ if (isBool) {
+ if (inSize == 1) sources[op] += ' > 0.0)';
+ else sources[op] += ', vec' + inSize + '(0.0))';
+ } else if (isInt || isUint)
+ sources[op] += ')';
+
+ sources[op] += ';\n';
+ }
+
+ // Result variable.
+ var outTypeName = gluShaderUtil.getDataTypeName(this.m_spec.output);
+ var isBoolOut = gluShaderUtil.isDataTypeBoolOrBVec(this.m_spec.output);
+
+ sources[op] += '\t';
+ if (precision && !isBoolOut) sources[op] += precision + ' ';
+ sources[op] += outTypeName + ' res = ' + outTypeName + '(0.0);\n\n';
+
+
+ // Expression.
+ sources[op] += '\t' + this.m_shaderOp + '\n\n';
+
+ // Convert to color.
+ var isResFloatVec = gluShaderUtil.isDataTypeFloatOrVec(this.m_spec.output);
+ var outScalarSize = gluShaderUtil.getDataTypeScalarSize(this.m_spec.output);
+
+ sources[op] += '\thighp vec4 color = vec4(0.0, 0.0, 0.0, 1.0);\n';
+ sources[op] += '\tcolor.' + s_outSwizzles[outScalarSize - 1] + ' = ';
+
+ if (!isResFloatVec && outScalarSize == 1)
+ sources[op] += 'float(res)';
+ else if (!isResFloatVec)
+ sources[op] += 'vec' + outScalarSize + '(res)';
+ else
+ sources[op] += 'res';
+
+ sources[op] += ';\n';
+
+ // Scale & bias.
+ var resultScale = this.m_spec.resultScale.getValue(shaderType);
+ var resultBias = this.m_spec.resultBias.getValue(shaderType);
+ if ((resultScale != 1.0) || (resultBias != 0.0)) {
+ sources[op] += '\tcolor = color';
+ if (resultScale != 1.0) sources[op] += ' * ' + es3fShaderOperatorTests.twoValuedVec4(resultScale.toString(10), '1.0', s_outSwizzleChannelMasks[outScalarSize - 1]);
+ if (resultBias != 0.0) sources[op] += ' + ' + es3fShaderOperatorTests.twoValuedVec4(resultBias.toString(10), '0.0', s_outSwizzleChannelMasks[outScalarSize - 1]);
+ sources[op] += ';\n';
+ }
+
+ // ..
+ if (this.m_isVertexCase) {
+ sources[vtx] += ' v_color = color;\n';
+ sources[frag] += ' o_color = v_color;\n';
+ } else{
+ for (var i = 0; i < this.m_spec.numInputs; i++)
+ sources[vtx] += ' v_in' + i + ' = a_in' + i + ';\n';
+ sources[frag] += ' o_color = color;\n';
+ }
+
+ sources[vtx] += '}\n';
+ sources[frag] += '}\n';
+
+ this.m_vertShaderSource = sources[vtx];
+ this.m_fragShaderSource = sources[frag];
+
+ // Setup the user attributes.
+ this.m_userAttribTransforms = [];
+ for (var inputNdx = 0; inputNdx < this.m_spec.numInputs; inputNdx++) {
+ var v = this.m_spec.inputs[inputNdx];
+
+ var rangeMin = v.rangeMin.getValue(shaderType);
+ var rangeMax = v.rangeMax.getValue(shaderType);
+ var scale = rangeMax - rangeMin;
+ var minBias = rangeMin;
+ var maxBias = rangeMax;
+ var attribMatrix = new tcuMatrix.Matrix(4, 4);
+
+ for (var rowNdx = 0; rowNdx < 4; rowNdx++) {
+ var row;
+
+ switch ((rowNdx + inputNdx) % 4) {
+ case 0: row = [scale, 0.0, 0.0, minBias]; break;
+ case 1: row = [0.0, scale, 0.0, minBias]; break;
+ case 2: row = [-scale, 0.0, 0.0, maxBias]; break;
+ case 3: row = [0.0, -scale, 0.0, maxBias]; break;
+ default: throw new Error('Invalid row index');
+ }
+
+ attribMatrix.setRow(rowNdx, row);
+ }
+
+ this.m_userAttribTransforms[inputNdx] = attribMatrix;
+ }
+
+};
+
+// Reference functions for specific sequence operations for the sequence operator tests.
+/**
+ * Reference for expression "in0, in2 + in1, in1 + in0"
+ * @param {Array<number>} in0 Vec4
+ * @param {Array<number>} in1 Vec4
+ * @param {Array<number>} in2 Vec4
+ * @return {Array<number>} Vec4
+ */
+es3fShaderOperatorTests.sequenceNoSideEffCase0 = function(in0, in1, in2) {
+ return deMath.add(in1, in0);
+};
+
+/**
+ * Reference for expression "in0, in2 + in1, in1 + in0"
+ * @param {number} in0 float
+ * @param {number} in1 deUint32
+ * @param {number} in2 float
+ * @return {number} deUint32
+ */
+es3fShaderOperatorTests.sequenceNoSideEffCase1 = function(in0, in1, in2) {
+ in1 = convert(in1, gluShaderUtil.DataType.UINT);
+ return convert(in1 + in1, gluShaderUtil.DataType.UINT);
+};
+
+/**
+ * Reference for expression "in0 && in1, in0, ivec2(vec2(in0) + in2)"
+ * @param {boolean} in0
+ * @param {boolean} in1
+ * @param {Array<number>} in2 Vec2
+ * @return {Array<number>} IVec2
+ */
+es3fShaderOperatorTests.sequenceNoSideEffCase2 = function(in0, in1, in2) {
+ in0 = convert(in0, gluShaderUtil.DataType.BOOL);
+ return convert([in0 + in2[0], in0 + in2[1]], gluShaderUtil.DataType.INT);
+};
+
+/**
+ * Reference for expression "in0 + vec4(in1), in2, in1"
+ * @param {Array<number>} in0 Vec4
+ * @param {Array<number>} in1 IVec4
+ * @param {Array<boolean>} in2 BVec4
+ * @return {Array<number>} IVec4
+ */
+es3fShaderOperatorTests.sequenceNoSideEffCase3 = function(in0, in1, in2) {
+ return convert(in1, gluShaderUtil.DataType.INT);
+};
+
+/**
+ * Reference for expression "in0++, in1 = in0 + in2, in2 = in1"
+ * @param {Array<number>} in0 Vec4
+ * @param {Array<number>} in1 Vec4
+ * @param {Array<number>} in2 Vec4
+ * @return {Array<number>} Vec4
+ */
+es3fShaderOperatorTests.sequenceSideEffCase0 = function(in0, in1, in2) {
+ return deMath.add(deMath.add(in0, [1.0, 1.0, 1.0, 1.0]), in2);
+};
+
+/**
+ * Reference for expression "in1++, in0 = float(in1), in1 = uint(in0 + in2)"
+ * @param {number} in0 float
+ * @param {number} in1 deUint32
+ * @param {number} in2 float
+ * @return {number} deUint32
+ */
+es3fShaderOperatorTests.sequenceSideEffCase1 = function(in0, in1, in2) {
+ in1 = convert(in1, gluShaderUtil.DataType.UINT);
+ return convert(in1 + 1.0 + in2, gluShaderUtil.DataType.UINT);
+};
+
+/**
+ * Reference for expression "in1 = in0, in2++, in2 = in2 + vec2(in1), ivec2(in2)"
+ * @param {boolean} in0
+ * @param {boolean} in1
+ * @param {Array<number>} in2 Vec2
+ * @return {Array<number>} IVec2
+ */
+es3fShaderOperatorTests.sequenceSideEffCase2 = function(in0, in1, in2) {
+ in0 = convert(in0, gluShaderUtil.DataType.BOOL);
+ return convert(deMath.add(deMath.add(in2, [1.0, 1.0]), [in0, in0]), gluShaderUtil.DataType.INT);
+};
+
+/**
+ * Reference for expression "in0 = in0 + vec4(in2), in1 = in1 + ivec4(in0), in1++"
+ * @param {Array<number>} in0 Vec4
+ * @param {Array<number>} in1 IVec4
+ * @param {Array<boolean>} in2 BVec4
+ * @return {Array<number>} IVec4
+ */
+es3fShaderOperatorTests.sequenceSideEffCase3 = function(in0, in1, in2) {
+ in1 = convert(in1, gluShaderUtil.DataType.INT);
+ in2 = convert(in2, gluShaderUtil.DataType.BOOL);
+ in0 = deMath.add(in0, in2);
+ in1 = deMath.add(in1, convert(in0, gluShaderUtil.DataType.INT));
+ return in1;
+};
+
+// ShaderEvalFunc-type wrappers for the above functions.
+
+/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
+es3fShaderOperatorTests.evalSequenceNoSideEffCase0 = function(ctx) {
+ ctx.color = es3fShaderOperatorTests.sequenceNoSideEffCase0(
+ deMath.swizzle(ctx.in_[0], [1, 2, 3, 0]),
+ deMath.swizzle(ctx.in_[1], [3, 2, 1, 0]),
+ deMath.swizzle(ctx.in_[2], [0, 3, 2, 1])
+ );
+};
+
+/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
+es3fShaderOperatorTests.evalSequenceNoSideEffCase1 = function(ctx) {
+ ctx.color[0] = es3fShaderOperatorTests.sequenceNoSideEffCase1(
+ ctx.in_[0][2],
+ ctx.in_[1][0],
+ ctx.in_[2][1]
+ );
+};
+
+/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
+es3fShaderOperatorTests.evalSequenceNoSideEffCase2 = function(ctx) {
+ /** @type {Array<number>} */ var result = es3fShaderOperatorTests.sequenceNoSideEffCase2(
+ ctx.in_[0][2] > 0.0,
+ ctx.in_[1][0] > 0.0,
+ deMath.swizzle(ctx.in_[2], [2, 1])
+ );
+ ctx.color[1] = result[0];
+ ctx.color[2] = result[1];
+};
+
+/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
+es3fShaderOperatorTests.evalSequenceNoSideEffCase3 = function(ctx) {
+ ctx.color = es3fShaderOperatorTests.sequenceNoSideEffCase3(
+ deMath.swizzle(ctx.in_[0], [1, 2, 3, 0]),
+ deMath.swizzle(ctx.in_[1], [3, 2, 1, 0]),
+ deMath.greaterThan(deMath.swizzle(ctx.in_[2], [0, 3, 2, 1]), [0.0, 0.0, 0.0, 0.0])
+ );
+};
+
+/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
+es3fShaderOperatorTests.evalSequenceSideEffCase0 = function(ctx) {
+ ctx.color = es3fShaderOperatorTests.sequenceSideEffCase0(
+ deMath.swizzle(ctx.in_[0], [1, 2, 3, 0]),
+ deMath.swizzle(ctx.in_[1], [3, 2, 1, 0]),
+ deMath.swizzle(ctx.in_[2], [0, 3, 2, 1])
+ );
+};
+
+/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
+es3fShaderOperatorTests.evalSequenceSideEffCase1 = function(ctx) {
+ ctx.color[0] = es3fShaderOperatorTests.sequenceSideEffCase1(
+ ctx.in_[0][2],
+ ctx.in_[1][0],
+ ctx.in_[2][1]
+ );
+};
+
+/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
+es3fShaderOperatorTests.evalSequenceSideEffCase2 = function(ctx) {
+ /** @type {Array<number>} */ var result = es3fShaderOperatorTests.sequenceSideEffCase2(
+ ctx.in_[0][2] > 0.0,
+ ctx.in_[1][0] > 0.0,
+ deMath.swizzle(ctx.in_[2], [2, 1])
+ );
+ ctx.color[1] = result[0];
+ ctx.color[2] = result[1];
+};
+
+/** @param {glsShaderRenderCase.ShaderEvalContext} ctx */
+es3fShaderOperatorTests.evalSequenceSideEffCase3 = function(ctx) {
+ ctx.color = es3fShaderOperatorTests.sequenceSideEffCase3(
+ deMath.swizzle(ctx.in_[0], [1, 2, 3, 0]),
+ deMath.swizzle(ctx.in_[1], [3, 2, 1, 0]),
+ deMath.greaterThan(deMath.swizzle(ctx.in_[2], [0, 3, 2, 1]), [0.0, 0.0, 0.0, 0.0])
+ );
+};
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+es3fShaderOperatorTests.ShaderOperatorTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'shaderop', 'Shader operators tests');
+};
+
+setParentClass(es3fShaderOperatorTests.ShaderOperatorTests, tcuTestCase.DeqpTest);
+
+es3fShaderOperatorTests.ShaderOperatorTests.prototype.init = function() {
+ var op = es3fShaderOperatorTests.builtinOperInfo;
+ var side = es3fShaderOperatorTests.builtinSideEffOperInfo;
+ var separate = es3fShaderOperatorTests.builtinOperInfoSeparateRefScaleBias;
+ var postSide = es3fShaderOperatorTests.BuiltinPostSideEffOperInfo;
+ var postOp = es3fShaderOperatorTests.BuiltinPostOperInfo;
+ var all = es3fShaderOperatorTests.Precision.All;
+ var highp = es3fShaderOperatorTests.Precision.High;
+ var mediump = es3fShaderOperatorTests.Precision.Medium;
+ var mediumhighp = es3fShaderOperatorTests.Precision.MediumHigh;
+ var lowp = es3fShaderOperatorTests.Precision.Low;
+ var na = es3fShaderOperatorTests.Precision.None;
+ var GT = es3fShaderOperatorTests.ValueType.FLOAT_GENTYPE;
+ var UGT = es3fShaderOperatorTests.ValueType.UINT_GENTYPE;
+ var IGT = es3fShaderOperatorTests.ValueType.INT_GENTYPE;
+ var BGT = es3fShaderOperatorTests.ValueType.BOOL_GENTYPE;
+ var F = es3fShaderOperatorTests.ValueType.FLOAT;
+ var I = es3fShaderOperatorTests.ValueType.INT;
+ var U = es3fShaderOperatorTests.ValueType.UINT;
+ var BV = es3fShaderOperatorTests.ValueType.BOOL_VEC;
+ var FV = es3fShaderOperatorTests.ValueType.FLOAT_VEC;
+ var IV = es3fShaderOperatorTests.ValueType.INT_VEC;
+ var UV = es3fShaderOperatorTests.ValueType.UINT_VEC;
+ var B = es3fShaderOperatorTests.ValueType.BOOL;
+ var V3 = es3fShaderOperatorTests.ValueType.VEC3;
+ var lUMax = es3fShaderOperatorTests.Symbol.SYMBOL_LOWP_UINT_MAX;
+ var mUMax = es3fShaderOperatorTests.Symbol.SYMBOL_MEDIUMP_UINT_MAX;
+ var lUMaxR = es3fShaderOperatorTests.Symbol.SYMBOL_LOWP_UINT_MAX_RECIPROCAL;
+ var mUMaxR = es3fShaderOperatorTests.Symbol.SYMBOL_MEDIUMP_UINT_MAX_RECIPROCAL;
+ var f = function(value) {
+ return new es3fShaderOperatorTests.FloatScalar(value);
+ };
+ var s = function(value) {
+ return new es3fShaderOperatorTests.FloatScalar(value, true);
+ };
+ var v = function(type, a, b) {
+ return new es3fShaderOperatorTests.Value(type, f(a), f(b));
+ };
+ var v2 = function(type, a, b) {
+ return new es3fShaderOperatorTests.Value(type, f(a), s(b));
+ };
+ var funcInfoGroups = [];
+ var unary = new es3fShaderOperatorTests.BuiltinFuncGroup('unary_operator', 'Unary operator tests');
+ funcInfoGroups.push(unary);
+
+ unary.push(op('plus', '+', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.5), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(nop)));
+ unary.push(op('plus', '+', IGT, [v(IGT, -5.0, 5.0)], f(0.1), f(0.5), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ unary.push(op('plus', '+', UGT, [v(UGT, 0.0, 2e2)], f(5e-3), f(0.0), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ unary.push(op('minus', '-', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.5), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(negate)));
+ unary.push(op('minus', '-', IGT, [v(IGT, -5.0, 5.0)], f(0.1), f(0.5), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(negate, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ unary.push(separate('minus', '-', UGT, [v2(UGT, 0.0, lUMax)], s(lUMaxR), f(0.0), lowp,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(negate, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT), s(lUMaxR),
+ s(es3fShaderOperatorTests.Symbol.SYMBOL_ONE_MINUS_UINT32MAX_DIV_LOWP_UINT_MAX)));
+ unary.push(separate('minus', '-', UGT, [v2(UGT, 0.0, mUMax)], s(mUMaxR), f(0.0), mediump,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(negate, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT), s(mUMaxR),
+ s(es3fShaderOperatorTests.Symbol.SYMBOL_ONE_MINUS_UINT32MAX_DIV_MEDIUMP_UINT_MAX)));
+ unary.push(op('minus', '-', UGT, [v(UGT, 0.0, 4e9)], f(2e-10), f(0.0), highp,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(negate, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ unary.push(op('not', '!', B, [v(B, -1.0, 1.0)], f(1.0), f(0.0), na,{'scalar': es3fShaderOperatorTests.unaryGenTypeFuncs(boolNot, gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL).scalar}));
+ unary.push(op('bitwise_not', '~', IGT, [v(IGT, -1e5, 1e5)], f(5e-5), f(0.5), highp,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(bitwiseNot, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ unary.push(op('bitwise_not', '~', UGT, [v(UGT, 0.0, 2e9)], f(2e-10), f(0.0), highp,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(bitwiseNot, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+
+ // Pre/post incr/decr side effect cases.
+ unary = new es3fShaderOperatorTests.BuiltinFuncGroup('unary_operator', 'Unary operator tests');
+ funcInfoGroups.push(unary);
+
+ unary.push(side('pre_increment_effect', '++', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.0), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(addOne)));
+ unary.push(side('pre_increment_effect', '++', IGT, [v(IGT, -6.0, 4.0)], f(0.1), f(0.5), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ unary.push(side('pre_increment_effect', '++', UGT, [v(UGT, 0.0, 9.0)], f(0.1), f(0.5), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ unary.push(side('pre_decrement_effect', '--', GT, [v(GT, -1.0, 1.0)], f(0.5), f(1.0), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(subOne)));
+ unary.push(side('pre_decrement_effect', '--', IGT, [v(IGT, -4.0, 6.0)], f(0.1), f(0.5), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ unary.push(side('pre_decrement_effect', '--', UGT, [v(UGT, 0.0, 10.0)], f(0.1), f(0.0), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ unary.push(postSide('post_increment_result', '++', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.0), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(addOne)));
+ unary.push(postSide('post_increment_result', '++', IGT, [v(IGT, -6.0, 4.0)], f(0.1), f(0.5), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ unary.push(postSide('post_increment_result', '++', UGT, [v(UGT, 0.0, 9.0)], f(0.1), f(0.0), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ unary.push(postSide('post_decrement_result', '--', GT, [v(GT, -1.0, 1.0)], f(0.5), f(1.0), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(subOne)));
+ unary.push(postSide('post_decrement_result', '--', IGT, [v(IGT, -4.0, 6.0)], f(0.1), f(0.5), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ unary.push(postSide('post_decrement_result', '--', UGT, [v(UGT, 1.0, 10.0)], f(0.1), f(0.0), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+
+ // Pre/post incr/decr result cases.
+ unary = new es3fShaderOperatorTests.BuiltinFuncGroup('unary_operator', 'Unary operator tests');
+ funcInfoGroups.push(unary);
+
+ unary.push(op('pre_increment_result', '++', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.0), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(addOne)));
+ unary.push(op('pre_increment_result', '++', IGT, [v(IGT, -6.0, 4.0)], f(0.1), f(0.5), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ unary.push(op('pre_increment_result', '++', UGT, [v(UGT, 0.0, 9.0)], f(0.1), f(0.0), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(addOne, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ unary.push(op('pre_dencrement_result', '--', GT, [v(GT, -1.0, 1.0)], f(0.5), f(1.0), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(subOne)));
+ unary.push(op('pre_decrement_result', '--', IGT, [v(IGT, -4.0, 6.0)], f(0.1), f(0.5), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ unary.push(op('pre_decrement_result', '--', UGT, [v(UGT, 0.0, 10.0)], f(0.1), f(0.0), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(subOne, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ unary.push(postOp('post_increment_result', '++', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.5), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(nop)));
+ unary.push(postOp('post_increment_result', '++', IGT, [v(IGT, -5.0, 5.0)], f(0.1), f(0.5), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ unary.push(postOp('post_increment_result', '++', UGT, [v(UGT, 0.0, 9.0)], f(0.1), f(0.0), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ unary.push(postOp('post_decrement_result', '--', GT, [v(GT, -1.0, 1.0)], f(0.5), f(0.5), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(nop)));
+ unary.push(postOp('post_decrement_result', '--', IGT, [v(IGT, -5.0, 5.0)], f(0.1), f(0.5), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ unary.push(postOp('post_decrement_result', '--', UGT, [v(UGT, 1.0, 10.0)], f(0.1), f(0.0), all,
+ es3fShaderOperatorTests.unaryGenTypeFuncs(nop, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+
+ var binary;
+
+ // Normal binary operations and their corresponding assignment operations have lots in common; generate both in the following loop.
+ // 0: normal op test, 1: assignment op side-effect test, 2: assignment op result test
+ for (var binaryOperatorType = 0; binaryOperatorType <= 2; binaryOperatorType++) {
+ var isNormalOp = binaryOperatorType == 0;
+ var isAssignEff = binaryOperatorType == 1;
+ var isAssignRes = binaryOperatorType == 2;
+
+ var addName = isNormalOp ? 'add' : isAssignEff ? 'add_assign_effect' : 'add_assign_result';
+ var subName = isNormalOp ? 'sub' : isAssignEff ? 'sub_assign_effect' : 'sub_assign_result';
+ var mulName = isNormalOp ? 'mul' : isAssignEff ? 'mul_assign_effect' : 'mul_assign_result';
+ var divName = isNormalOp ? 'div' : isAssignEff ? 'div_assign_effect' : 'div_assign_result';
+ var modName = isNormalOp ? 'mod' : isAssignEff ? 'mod_assign_effect' : 'mod_assign_result';
+ var andName = isNormalOp ? 'bitwise_and' : isAssignEff ? 'bitwise_and_assign_effect' : 'bitwise_and_assign_result';
+ var orName = isNormalOp ? 'bitwise_or' : isAssignEff ? 'bitwise_or_assign_effect' : 'bitwise_or_assign_result';
+ var xorName = isNormalOp ? 'bitwise_xor' : isAssignEff ? 'bitwise_xor_assign_effect' : 'bitwise_xor_assign_result';
+ var leftShiftName = isNormalOp ? 'left_shift' : isAssignEff ? 'left_shift_assign_effect' : 'left_shift_assign_result';
+ var rightShiftName = isNormalOp ? 'right_shift' : isAssignEff ? 'right_shift_assign_effect' : 'right_shift_assign_result';
+ var addOp = isNormalOp ? '+' : '+=';
+ var subOp = isNormalOp ? '-' : '-=';
+ var mulOp = isNormalOp ? '*' : '*=';
+ var divOp = isNormalOp ? '/' : '/=';
+ var modOp = isNormalOp ? '%' : '%=';
+ var andOp = isNormalOp ? '&' : '&=';
+ var orOp = isNormalOp ? '|' : '|=';
+ var xorOp = isNormalOp ? '^' : '^=';
+ var leftShiftOp = isNormalOp ? '<<' : '<<=';
+ var rightShiftOp = isNormalOp ? '>>' : '>>=';
+
+ op = isAssignEff ? es3fShaderOperatorTests.builtinSideEffOperInfo : es3fShaderOperatorTests.builtinOperInfo;
+
+ binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests');
+ funcInfoGroups.push(binary);
+
+ // The add operator.
+
+ binary.push(op(addName, addOp, GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryGenTypeFuncs(add)));
+ binary.push(op(addName, addOp, IGT, [v(IGT, -4.0, 6.0), v(IGT, -6.0, 5.0)], f(0.1), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(add, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(addName, addOp, IGT, [v(IGT, -2e9, 2e9), v(IGT, -2e9, 2e9)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(add, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(addName, addOp, UGT, [v(UGT, 0.0, 1e2), v(UGT, 0.0, 1e2)], f(5e-3), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(add, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(addName, addOp, UGT, [v(UGT, 0.0, 4e9), v(UGT, 0.0, 4e9)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(add, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+
+ binary.push(op(addName, addOp, FV, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.addScalar)));
+ binary.push(op(addName, addOp, IV, [v(IV, -4.0, 6.0), v(I, -6.0, 5.0)], f(0.1), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.addScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(addName, addOp, IV, [v(IV, -2e9, 2e9), v(I, -2e9, 2e9)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.addScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(addName, addOp, UV, [v(UV, 0.0, 1e2), v(U, 0.0, 1e2)], f(5e-3), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.addScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(addName, addOp, UV, [v(UV, 0.0, 4e9), v(U, 0.0, 4e9)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.addScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+
+ if (isNormalOp) {
+ binary.push(op(addName, addOp, FV, [v(F, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryScalarVecFuncs(addScalarVec)));
+ binary.push(op(addName, addOp, IV, [v(I, -4.0, 6.0), v(IV, -6.0, 5.0)], f(0.1), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(addScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(addName, addOp, IV, [v(I, -2e9, 2e9), v(IV, -2e9, 2e9)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(addScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(addName, addOp, UV, [v(U, 0.0, 1e2), v(UV, 0.0, 1e2)], f(5e-3), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(addScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(addName, addOp, UV, [v(U, 0.0, 4e9), v(UV, 0.0, 4e9)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(addScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ }
+
+ // The subtract operator.
+
+ binary.push(op(subName, subOp, GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryGenTypeFuncs(sub)));
+ binary.push(op(subName, subOp, IGT, [v(IGT, -4.0, 6.0), v(IGT, -6.0, 5.0)], f(0.1), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(sub, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(subName, subOp, IGT, [v(IGT, -2e9, 2e9), v(IGT, -2e9, 2e9)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(sub, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(subName, subOp, UGT, [v(UGT, 1e2, 2e2), v(UGT, 0.0, 1e2)], f(5e-3), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(sub, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(subName, subOp, UGT, [v(UGT, .5e9, 3.7e9), v(UGT, 0.0, 3.9e9)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(sub, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(subName, subOp, FV, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.subScalar)));
+ binary.push(op(subName, subOp, IV, [v(IV, -4.0, 6.0), v(I, -6.0, 5.0)], f(0.1), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.subScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(subName, subOp, IV, [v(IV, -2e9, 2e9), v(I, -2e9, 2e9)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.subScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(subName, subOp, UV, [v(UV, 1e2, 2e2), v(U, 0.0, 1e2)], f(5e-3), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.subScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(subName, subOp, UV, [v(UV, 0.0, 4e9), v(U, 0.0, 4e9)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.subScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+
+ if (isNormalOp) {
+ binary.push(op(subName, subOp, FV, [v(F, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryScalarVecFuncs(subScalarVec)));
+ binary.push(op(subName, subOp, IV, [v(I, -4.0, 6.0), v(IV, -6.0, 5.0)], f(0.1), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(subScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(subName, subOp, IV, [v(I, -2e9, 2e9), v(IV, -2e9, 2e9)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(subScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(subName, subOp, UV, [v(U, 1e2, 2e2), v(UV, 0.0, 1e2)], f(5e-3), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(subScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(subName, subOp, UV, [v(U, 0.0, 4e9), v(UV, 0.0, 4e9)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(subScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ }
+
+ binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests');
+ funcInfoGroups.push(binary);
+
+ // The multiply operator.
+
+ binary.push(op(mulName, mulOp, GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryGenTypeFuncs(mul)));
+ binary.push(op(mulName, mulOp, IGT, [v(IGT, -4.0, 6.0), v(IGT, -6.0, 5.0)], f(0.1), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(mul, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(mulName, mulOp, IGT, [v(IGT, -3e5, 3e5), v(IGT, -3e4, 3e4)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(mul, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(mulName, mulOp, UGT, [v(UGT, 0.0, 16.0), v(UGT, 0.0, 16.0)], f(4e-3), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(mul, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(mulName, mulOp, UGT, [v(UGT, 0.0, 6e5), v(UGT, 0.0, 6e4)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(mul, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(mulName, mulOp, FV, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.scale)));
+ binary.push(op(mulName, mulOp, IV, [v(IV, -4.0, 6.0), v(I, -6.0, 5.0)], f(0.1), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.scale, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(mulName, mulOp, IV, [v(IV, -3e5, 3e5), v(I, -3e4, 3e4)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.scale, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(mulName, mulOp, UV, [v(UV, 0.0, 16.0), v(U, 0.0, 16.0)], f(4e-3), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.scale, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(mulName, mulOp, UV, [v(UV, 0.0, 6e5), v(U, 0.0, 6e4)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.scale, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+
+ if (isNormalOp) {
+ binary.push(op(mulName, mulOp, FV, [v(F, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryScalarVecFuncs(mulScalarVec)));
+ binary.push(op(mulName, mulOp, IV, [v(I, -4.0, 6.0), v(IV, -6.0, 5.0)], f(0.1), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(mulScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(mulName, mulOp, IV, [v(I, -3e5, 3e5), v(IV, -3e4, 3e4)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(mulScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(mulName, mulOp, UV, [v(U, 0.0, 16.0), v(UV, 0.0, 16.0)], f(4e-3), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(mulScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(mulName, mulOp, UV, [v(U, 0.0, 6e5), v(UV, 0.0, 6e4)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(mulScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ }
+
+ // The divide operator.
+
+ binary.push(op(divName, divOp, GT, [v(GT, -1.0, 1.0), v(GT, -2.0, -0.5)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryGenTypeFuncs(div)));
+ binary.push(op(divName, divOp, IGT, [v(IGT, 24.0, 24.0), v(IGT, -4.0, -1.0)], f(0.04), f(1.0),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(div, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(divName, divOp, IGT, [v(IGT, 40320.0, 40320.0), v(IGT, -8.0, -1.0)], f(1e-5), f(0.5),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(div, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(divName, divOp, UGT, [v(UGT, 0.0, 24.0), v(UGT, 1.0, 4.0)], f(0.04), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(div, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(divName, divOp, UGT, [v(UGT, 0.0, 40320.0), v(UGT, 1.0, 8.0)], f(1e-5), f(0.0),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(div, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(divName, divOp, FV, [v(FV, -1.0, 1.0), v(F, -2.0, -0.5)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.divideScale)));
+ binary.push(op(divName, divOp, IV, [v(IV, 24.0, 24.0), v(I, -4.0, -1.0)], f(0.04), f(1.0),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.divideScale, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(divName, divOp, IV, [v(IV, 40320.0, 40320.0), v(I, -8.0, -1.0)], f(1e-5), f(0.5),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.divideScale, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(divName, divOp, UV, [v(UV, 0.0, 24.0), v(U, 1.0, 4.0)], f(0.04), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.divideScale, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(divName, divOp, UV, [v(UV, 0.0, 40320.0), v(U, 1.0, 8.0)], f(1e-5), f(0.0),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.divideScale, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+
+ if (isNormalOp) {
+ binary.push(op(divName, divOp, FV, [v(F, -1.0, 1.0), v(FV, -2.0, -0.5)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryScalarVecFuncs(divScalarVec)));
+ binary.push(op(divName, divOp, IV, [v(I, 24.0, 24.0), v(IV, -4.0, -1.0)], f(0.04), f(1.0),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(divScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(divName, divOp, IV, [v(I, 40320.0, 40320.0), v(IV, -8.0, -1.0)], f(1e-5), f(0.5),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(divScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(divName, divOp, UV, [v(U, 0.0, 24.0), v(UV, 1.0, 4.0)], f(0.04), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(divScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(divName, divOp, UV, [v(U, 0.0, 40320.0), v(UV, 1.0, 8.0)], f(1e-5), f(0.0),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(divScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ }
+
+ binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests');
+ funcInfoGroups.push(binary);
+
+ // The modulus operator.
+
+ binary.push(op(modName, modOp, IGT, [v(IGT, 0.0, 6.0), v(IGT, 1.1, 6.1)], f(0.25), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(modName, modOp, IGT, [v(IGT, 0.0, 14.0), v(IGT, 1.1, 11.1)], f(0.1), f(0.5),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(modName, modOp, UGT, [v(UGT, 0.0, 6.0), v(UGT, 1.1, 6.1)], f(0.25), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(modName, modOp, UGT, [v(UGT, 0.0, 24.0), v(UGT, 1.1, 11.1)], f(0.1), f(0.0),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(modName, modOp, IV, [v(IV, 0.0, 6.0), v(I, 1.1, 6.1)], f(0.25), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(modName, modOp, IV, [v(IV, 0.0, 6.0), v(I, 1.1, 11.1)], f(0.1), f(0.5),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(modName, modOp, UV, [v(UV, 0.0, 6.0), v(U, 1.1, 6.1)], f(0.25), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(modName, modOp, UV, [v(UV, 0.0, 24.0), v(U, 1.1, 11.1)], f(0.1), f(0.0),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+
+ if (isNormalOp) {
+ binary.push(op(modName, modOp, IV, [v(I, 0.0, 6.0), v(IV, 1.1, 6.1)], f(0.25), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(modScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(modName, modOp, IV, [v(I, 0.0, 6.0), v(IV, 1.1, 11.1)], f(0.1), f(0.5),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(modScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(modName, modOp, UV, [v(U, 0.0, 6.0), v(UV, 1.1, 6.1)], f(0.25), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(modScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(modName, modOp, UV, [v(U, 0.0, 24.0), v(UV, 1.1, 11.1)], f(0.1), f(0.0),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(modScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ }
+
+ // The bitwise and operator.
+
+ binary.push(op(andName, andOp, IGT, [v(IGT, -16.0, 16.0), v(IGT, -16.0, 16.0)], f(0.03), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryAnd, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(andName, andOp, IGT, [v(IGT, -2e9, 2e9), v(IGT, -2e9, 2e9)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryAnd, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(andName, andOp, UGT, [v(UGT, 0.0, 32.0), v(UGT, 0.0, 32.0)], f(0.03), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryAnd, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(andName, andOp, UGT, [v(UGT, 0.0, 4e9), v(UGT, 0.0, 4e9)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryAnd, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(andName, andOp, IV, [v(IV, -16.0, 16.0), v(I, -16.0, 16.0)], f(0.03), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryAndVecScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(andName, andOp, IV, [v(IV, -2e9, 2e9), v(I, -2e9, 2e9)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryAndVecScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(andName, andOp, UV, [v(UV, 0.0, 32.0), v(U, 0.0, 32.0)], f(0.03), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryAndVecScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(andName, andOp, UV, [v(UV, 0.0, 4e9), v(U, 0.0, 4e9)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryAndVecScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+
+ if (isNormalOp) {
+ binary.push(op(andName, andOp, IV, [v(I, -16.0, 16.0), v(IV, -16.0, 16.0)], f(0.03), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseAndScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(andName, andOp, IV, [v(I, -2e9, 2e9), v(IV, -2e9, 2e9)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseAndScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(andName, andOp, UV, [v(U, 0.0, 32.0), v(UV, 0.0, 32.0)], f(0.03), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseAndScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(andName, andOp, UV, [v(U, 0.0, 4e9), v(UV, 0.0, 4e9)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseAndScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ }
+
+ binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests');
+ funcInfoGroups.push(binary);
+
+ // The bitwise or operator.
+
+ binary.push(op(orName, orOp, IGT, [v(IGT, -16.0, 16.0), v(IGT, -16.0, 16.0)], f(0.03), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryOr, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(orName, orOp, IGT, [v(IGT, -2e9, 2e9), v(IGT, -2e9, 2e9)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryOr, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(orName, orOp, UGT, [v(UGT, 0.0, 32.0), v(UGT, 0.0, 32.0)], f(0.03), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryOr, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(orName, orOp, UGT, [v(UGT, 0.0, 4e9), v(UGT, 0.0, 4e9)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryOr, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(orName, orOp, IV, [v(IV, -16.0, 16.0), v(I, -16.0, 16.0)], f(0.03), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryOrVecScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(orName, orOp, IV, [v(IV, -2e9, 2e9), v(I, -2e9, 2e9)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryOrVecScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(orName, orOp, UV, [v(UV, 0.0, 32.0), v(U, 0.0, 32.0)], f(0.03), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryOrVecScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(orName, orOp, UV, [v(UV, 0.0, 4e9), v(U, 0.0, 4e9)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryOrVecScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+
+ if (isNormalOp) {
+ binary.push(op(orName, orOp, IV, [v(I, -16.0, 16.0), v(IV, -16.0, 16.0)], f(0.03), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseOrScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(orName, orOp, IV, [v(I, -2e9, 2e9), v(IV, -2e9, 2e9)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseOrScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(orName, orOp, UV, [v(U, 0.0, 32.0), v(UV, 0.0, 32.0)], f(0.03), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseOrScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(orName, orOp, UV, [v(U, 0.0, 4e9), v(UV, 0.0, 4e9)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseOrScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ }
+
+ // The bitwise xor operator.
+
+ binary.push(op(xorName, xorOp, IGT, [v(IGT, -16.0, 16.0), v(IGT, -16.0, 16.0)], f(0.03), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryXor, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(xorName, xorOp, IGT, [v(IGT, -2e9, 2e9), v(IGT, -2e9, 2e9)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryXor, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(xorName, xorOp, UGT, [v(UGT, 0.0, 32.0), v(UGT, 0.0, 32.0)], f(0.03), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryXor, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(xorName, xorOp, UGT, [v(UGT, 0.0, 4e9), v(UGT, 0.0, 4e9)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.binaryXor, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(xorName, xorOp, IV, [v(IV, -16.0, 16.0), v(I, -16.0, 16.0)], f(0.03), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryXorVecScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(xorName, xorOp, IV, [v(IV, -2e9, 2e9), v(I, -2e9, 2e9)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryXorVecScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(xorName, xorOp, UV, [v(UV, 0.0, 32.0), v(U, 0.0, 32.0)], f(0.03), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryXorVecScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(xorName, xorOp, UV, [v(UV, 0.0, 4e9), v(U, 0.0, 4e9)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.binaryXorVecScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+
+ if (isNormalOp) {
+ binary.push(op(xorName, xorOp, IV, [v(I, -16.0, 16.0), v(IV, -16.0, 16.0)], f(0.03), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseXorScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(xorName, xorOp, IV, [v(I, -2e9, 2e9), v(IV, -2e9, 2e9)], f(4e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseXorScalarVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(xorName, xorOp, UV, [v(U, 0.0, 32.0), v(UV, 0.0, 32.0)], f(0.03), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseXorScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(xorName, xorOp, UV, [v(U, 0.0, 4e9), v(UV, 0.0, 4e9)], f(2e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryScalarVecFuncs(bitwiseXorScalarVec, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ }
+
+ binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests');
+ funcInfoGroups.push(binary);
+
+ // The left shift operator. Second operand (shift amount) can be either int or uint, even for uint and int first operand, respectively.
+ for (var isSignedAmount = 0; isSignedAmount <= 1; isSignedAmount++) {
+ var gType = isSignedAmount == 0 ? UGT : IGT;
+ var sType = isSignedAmount == 0 ? U : I;
+ binary.push(op(leftShiftName, leftShiftOp, IGT, [v(IGT, -7.0, 7.0), v(gType, 0.0, 4.0)], f(4e-3), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftLeft, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(leftShiftName, leftShiftOp, IGT, [v(IGT, -7.0, 7.0), v(gType, 0.0, 27.0)], f(5e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftLeft, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(leftShiftName, leftShiftOp, UGT, [v(UGT, 0.0, 7.0), v(gType, 0.0, 5.0)], f(4e-3), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftLeft, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(leftShiftName, leftShiftOp, UGT, [v(UGT, 0.0, 7.0), v(gType, 0.0, 28.0)], f(5e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftLeft, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(leftShiftName, leftShiftOp, IV, [v(IV, -7.0, 7.0), v(sType, 0.0, 4.0)], f(4e-3), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftLeftVecScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(leftShiftName, leftShiftOp, IV, [v(IV, -7.0, 7.0), v(sType, 0.0, 27.0)], f(5e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftLeftVecScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(leftShiftName, leftShiftOp, UV, [v(UV, 0.0, 7.0), v(sType, 0.0, 5.0)], f(4e-3), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftLeftVecScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(leftShiftName, leftShiftOp, UV, [v(UV, 0.0, 7.0), v(sType, 0.0, 28.0)], f(5e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftLeftVecScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ }
+
+ // The right shift operator. Second operand (shift amount) can be either int or uint, even for uint and int first operand, respectively.
+
+ for (var isSignedAmount = 0; isSignedAmount <= 1; isSignedAmount++) {
+ gType = isSignedAmount == 0 ? UGT : IGT;
+ sType = isSignedAmount == 0 ? U : I;
+ binary.push(op(rightShiftName, rightShiftOp, IGT, [v(IGT, -127.0, 127.0), v(gType, 0.0, 8.0)], f(4e-3), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftRight, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(rightShiftName, rightShiftOp, IGT, [v(IGT, -2e9, 2e9), v(gType, 0.0, 31.0)], f(5e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftRight, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(rightShiftName, rightShiftOp, UGT, [v(UGT, 0.0, 255.0), v(gType, 0.0, 8.0)], f(4e-3), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftRight, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(rightShiftName, rightShiftOp, UGT, [v(UGT, 0.0, 4e9), v(gType, 0.0, 31.0)], f(5e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.shiftRight, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(rightShiftName, rightShiftOp, IV, [v(IV, -127.0, 127.0), v(sType, 0.0, 8.0)], f(4e-3), f(0.5),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftRightVecScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(rightShiftName, rightShiftOp, IV, [v(IV, -2e9, 2e9), v(sType, 0.0, 31.0)], f(5e-10), f(0.5),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftRightVecScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op(rightShiftName, rightShiftOp, UV, [v(UV, 0.0, 255.0), v(sType, 0.0, 8.0)], f(4e-3), f(0.0),
+ mediump, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftRightVecScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op(rightShiftName, rightShiftOp, UV, [v(UV, 0.0, 4e9), v(sType, 0.0, 31.0)], f(5e-10), f(0.0),
+ highp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.shiftRightVecScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ }
+ }
+
+ // Rest of binary operators.
+ // Scalar relational operators.
+ binary = new es3fShaderOperatorTests.BuiltinFuncGroup('binary_operator', 'Binary operator tests');
+ funcInfoGroups.push(binary);
+
+ binary.push(op('less', '<', B, [v(F, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0),
+ all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThan).scalar}));
+ binary.push(op('less', '<', B, [v(I, -5.0, 5.0), v(I, -5.0, 5.0)], f(1.0), f(0.0),
+ all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThan, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT).scalar}));
+ binary.push(op('less', '<', B, [v(U, 0.0, 16.0), v(U, 0.0, 16.0)], f(1.0), f(0.0),
+ all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThan, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT).scalar}));
+ binary.push(op('less_or_equal', '<=', B, [v(F, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0),
+ all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThanEqual).scalar}));
+ binary.push(op('less_or_equal', '<=', B, [v(I, -5.0, 5.0), v(I, -5.0, 5.0)], f(1.0), f(0.0),
+ all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThanEqual, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT).scalar}));
+ binary.push(op('less_or_equal', '<=', B, [v(U, 0.0, 16.0), v(U, 0.0, 16.0)], f(1.0), f(0.0),
+ all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(lessThanEqual, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT).scalar}));
+ binary.push(op('greater', '>', B, [v(F, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0),
+ all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThan).scalar}));
+ binary.push(op('greater', '>', B, [v(I, -5.0, 5.0), v(I, -5.0, 5.0)], f(1.0), f(0.0),
+ all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThan, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT).scalar}));
+ binary.push(op('greater', '>', B, [v(U, 0.0, 16.0), v(U, 0.0, 16.0)], f(1.0), f(0.0),
+ all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThan, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT).scalar}));
+ binary.push(op('greater_or_equal', '>=', B, [v(F, -1.0, 1.0), v(F, -1.0, 1.0)], f(1.0), f(0.0),
+ all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThanEqual).scalar}));
+ binary.push(op('greater_or_equal', '>=', B, [v(I, -5.0, 5.0), v(I, -5.0, 5.0)], f(1.0), f(0.0),
+ all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThanEqual, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT).scalar}));
+ binary.push(op('greater_or_equal', '>=', B, [v(U, 0.0, 16.0), v(U, 0.0, 16.0)], f(1.0), f(0.0),
+ all, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(greaterThanEqual, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT).scalar}));
+
+ binary.push(op('equal', '==', B, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(allEqual)));
+ binary.push(op('equal', '==', B, [v(IGT, -5.5, 4.7), v(IGT, -2.1, 0.1)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(allEqual, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op('equal', '==', B, [v(UGT, 0.0, 8.0), v(UGT, 3.5, 4.5)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(allEqual, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op('equal', '==', B, [v(BGT, -2.1, 2.1), v(BGT, -1.1, 3.0)], f(1.0), f(0.0),
+ na, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(allEqual, gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL)));
+ binary.push(op('not_equal', '!=', B, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(anyNotEqual)));
+ binary.push(op('not_equal', '!=', B, [v(IGT, -5.5, 4.7), v(IGT, -2.1, 0.1)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(anyNotEqual, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ binary.push(op('not_equal', '!=', B, [v(UGT, 0.0, 8.0), v(UGT, 3.5, 4.5)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(anyNotEqual, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ binary.push(op('not_equal', '!=', B, [v(BGT, -2.1, 2.1), v(BGT, -1.1, 3.0)], f(1.0), f(0.0),
+ na, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(anyNotEqual, gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL)));
+
+ // Logical operators.
+ binary.push(op('logical_and', '&&', B, [v(B, -1.0, 1.0), v(B, -1.0, 1.0)], f(1.0), f(0.0),
+ na, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(logicalAnd, gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL).scalar}));
+ binary.push(op('logical_or', '||', B, [v(B, -1.0, 1.0), v(B, -1.0, 1.0)], f(1.0), f(0.0),
+ na, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(logicalOr, gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL).scalar}));
+ binary.push(op('logical_xor', '^^', B, [v(B, -1.0, 1.0), v(B, -1.0, 1.0)], f(1.0), f(0.0),
+ na, {scalar: es3fShaderOperatorTests.binaryGenTypeFuncs(logicalXor, gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL).scalar}));
+
+ // 8.1 Angle and Trigonometry Functions.
+ var trig = new es3fShaderOperatorTests.BuiltinFuncGroup("angle_and_trigonometry", "Angle and trigonometry function tests.");
+ funcInfoGroups.push(trig);
+ op = es3fShaderOperatorTests.builtinFunctionInfo;
+ trig.push(op("radians", "radians", GT, [v(GT, -1.0, 1.0)], f(25.0), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(radians)));
+ trig.push(op("degrees", "degrees", GT, [v(GT, -1.0, 1.0)], f(0.04), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(degrees)));
+ trig.push(op("sin", "sin", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sin)));
+ trig.push(op("sin", "sin", GT, [v(GT, -1.5, 1.5)], f(0.5), f(0.5),
+ lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sin)));
+ trig.push(op("cos", "cos", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.cos)));
+ trig.push(op("cos", "cos", GT, [v(GT, -1.5, 1.5)], f(0.5), f(0.5),
+ lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.cos)));
+ trig.push(op("tan", "tan", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.tan)));
+ trig.push(op("tan", "tan", GT, [v(GT, -1.5, 5.5)], f(0.5), f(0.5),
+ lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.tan)));
+
+ trig = new es3fShaderOperatorTests.BuiltinFuncGroup("angle_and_trigonometry", "Angle and trigonometry function tests.");
+ funcInfoGroups.push(trig);
+ trig.push(op("asin", "asin", GT, [v(GT, -1.0, 1.0)], f(1.0), f(0.0),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.asin)));
+ trig.push(op("acos", "acos", GT, [v(GT, -1.0, 1.0)], f(1.0), f(0.0),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.acos)));
+ trig.push(op("atan", "atan", GT, [v(GT, -4.0, 4.0)], f(0.5), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.atan)));
+ trig.push(op("atan2", "atan", GT, [v(GT, -4.0, 4.0), v(GT, 0.5, 2.0)], f(0.5), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.atan2)));
+
+ trig = new es3fShaderOperatorTests.BuiltinFuncGroup("angle_and_trigonometry", "Angle and trigonometry function tests.");
+ funcInfoGroups.push(trig);
+ trig.push(op("sinh", "sinh", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sinh)));
+ trig.push(op("sinh", "sinh", GT, [v(GT, -1.5, 1.5)], f(0.5), f(0.5),
+ lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sinh)));
+ trig.push(op("cosh", "cosh", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.cosh)));
+ trig.push(op("cosh", "cosh", GT, [v(GT, -1.5, 1.5)], f(0.5), f(0.5),
+ lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.cosh)));
+ trig.push(op("tanh", "tanh", GT, [v(GT, -5.0, 5.0)], f(0.5), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.tanh)));
+ trig.push(op("tanh", "tanh", GT, [v(GT, -1.5, 5.5)], f(0.5), f(0.5),
+ lowp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.tanh)));
+
+ trig = new es3fShaderOperatorTests.BuiltinFuncGroup("angle_and_trigonometry", "Angle and trigonometry function tests.");
+ funcInfoGroups.push(trig);
+ trig.push(op("asinh", "asinh", GT, [v(GT, -1.0, 1.0)], f(1.0), f(0.0),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.asinh)));
+ trig.push(op("acosh", "acosh", GT, [v(GT, 1.0, 2.2)], f(1.0), f(0.0),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.acosh)));
+ // Results are undefined if |x| >= 1, so it diverses from C++ version here.
+ trig.push(op("atanh", "atanh", GT, [v(GT, -0.99, 0.99)], f(1.0), f(0.0),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.atanh)));
+
+ // 8.2 Exponential Functions.
+ var exps = new es3fShaderOperatorTests.BuiltinFuncGroup("exponential", "Exponential function tests");
+ exps.push(op("pow", "pow", GT, [v(GT, 0.1, 8.0), v(GT, -4.0, 2.0)], f(1.0), f(0.0),
+ mediumhighp, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.pow)));
+ exps.push(op("exp", "exp", GT, [v(GT, -6.0, 3.0)], f(0.5), f(0.0),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.exp)));
+ exps.push(op("log", "log", GT, [v(GT, 0.1, 10.0)], f(0.5), f(0.3),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.log)));
+ exps.push(op("exp2", "exp2", GT, [v(GT, -7.0, 2.0)], f(1.0), f(0.0),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(exp2)));
+ exps.push(op("log2", "log2", GT, [v(GT, 0.1, 10.0)], f(1.0), f(0.0),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.log2)));
+ exps.push(op("sqrt", "sqrt", GT, [v(GT, 0.0, 10.0)], f(0.3), f(0.0),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sqrt)));
+ exps.push(op("inversesqrt", "inversesqrt", GT, [v(GT, 0.5, 10.0)], f(1.0), f(0.0),
+ mediumhighp, es3fShaderOperatorTests.unaryGenTypeFuncs(inverseSqrt)));
+
+ funcInfoGroups.push(exps);
+
+ // 8.3 Common Functions.
+ var comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
+ funcInfoGroups.push(comm);
+ comm.push(op("abs", "abs", GT, [v(GT, -2.0, 2.0)], f(0.5), f(0.5),
+ all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.abs)));
+ comm.push(op("sign", "sign", GT, [v(GT, -1.5, 1.5)], f(0.3), f(0.5),
+ all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.sign)));
+ comm.push(op("floor", "floor", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.7),
+ all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.floor)));
+ comm.push(op("trunc", "trunc", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.7),
+ all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.trunc)));
+ comm.push(op("round", "round", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.7),
+ all, es3fShaderOperatorTests.unaryGenTypeFuncs(roundToEven)));
+
+ comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
+ funcInfoGroups.push(comm);
+
+ comm.push(op("roundEven", "roundEven", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.7),
+ all, es3fShaderOperatorTests.unaryGenTypeFuncs(roundToEven)));
+ comm.push(op("ceil", "ceil", GT, [v(GT, 2.5, 2.5)], f(0.2), f(0.5),
+ all, es3fShaderOperatorTests.unaryGenTypeFuncs(Math.ceil)));
+ comm.push(op("fract", "fract", GT, [v(GT, -1.5, 1.5)], f(0.8), f(0.1),
+ all, es3fShaderOperatorTests.unaryGenTypeFuncs(fract)));
+ comm.push(op("mod", "mod", GT, [v(GT, -2.0, 2.0), v(GT, 0.9, 6.0)], f(0.5), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.binaryGenTypeFuncs(deMath.mod)));
+ comm.push(op("mod", "mod", GT, [v(FV, -2.0, 2.0), v(F, 0.9, 6.0)], f(0.5), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.binaryVecScalarFuncs(deMath.modScale)));
+
+ comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
+ funcInfoGroups.push(comm);
+
+ comm.push(op("min", "min", GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(0.5), f(0.5),
+ all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.min)));
+ comm.push(op("min", "min", GT, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(0.5), f(0.5),
+ all, es3fShaderOperatorTests.binaryVecScalarFuncs(minVecScalar)));
+ comm.push(op("min", "min", IGT, [v(IGT, -4.0, 4.0), v(IGT, -4.0, 4.0)], f(0.125), f(0.5),
+ all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.min, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ comm.push(op("min", "min", IGT, [v(IV, -4.0, 4.0), v(I, -4.0, 4.0)], f(0.125), f(0.5),
+ all, es3fShaderOperatorTests.binaryVecScalarFuncs(minVecScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ comm.push(op("min", "min", UGT, [v(UGT, 0.0, 8.0), v(UGT, 0.0, 8.0)], f(0.125), f(0.0),
+ all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.min, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+
+ comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
+ funcInfoGroups.push(comm);
+
+ comm.push(op("min", "min", UGT, [v(UV, 0.0, 8.0), v(U, 0.0, 8.0)], f(0.125), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecScalarFuncs(minVecScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ comm.push(op("max", "max", GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0)], f(0.5), f(0.5),
+ all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.max)));
+ comm.push(op("max", "max", GT, [v(FV, -1.0, 1.0), v(F, -1.0, 1.0)], f(0.5), f(0.5),
+ all, es3fShaderOperatorTests.binaryVecScalarFuncs(maxVecScalar)));
+ comm.push(op("max", "max", IGT, [v(IGT, -4.0, 4.0), v(IGT, -4.0, 4.0)], f(0.125), f(0.5),
+ all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.max, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ comm.push(op("max", "max", IGT, [v(IV, -4.0, 4.0), v(I, -4.0, 4.0)], f(0.125), f(0.5),
+ all, es3fShaderOperatorTests.binaryVecScalarFuncs(maxVecScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+
+ comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
+ funcInfoGroups.push(comm);
+
+ comm.push(op("max", "max", UGT, [v(UGT, 0.0, 8.0), v(UGT, 0.0, 8.0)], f(0.125), f(0.0),
+ all, es3fShaderOperatorTests.binaryGenTypeFuncs(Math.max, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ comm.push(op("max", "max", UGT, [v(UV, 0.0, 8.0), v(U, 0.0, 8.0)], f(0.125), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecScalarFuncs(maxVecScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ comm.push(op("clamp", "clamp", GT, [v(GT, -1.0, 1.0), v(GT, -0.5, 0.5), v(GT, 0.5, 1.0)], f(0.5), f(0.5),
+ all, es3fShaderOperatorTests.ternaryGenTypeFuncs(deMath.clamp)));
+ comm.push(op("clamp", "clamp", GT, [v(FV, -1.0, 1.0), v(F, -0.5, 0.5), v(F, 0.5, 1.0)], f(0.5), f(0.5),
+ all, es3fShaderOperatorTests.ternaryVecScalarScalarFuncs(clampVecScalarScalar)));
+ comm.push(op("clamp", "clamp", IGT, [v(IGT, -4.0, 4.0), v(IGT, -2.0, 2.0), v(IGT, 2.0, 4.0)], f(0.125), f(0.5),
+ all, es3fShaderOperatorTests.ternaryGenTypeFuncs(deMath.clamp, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+
+ comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
+ funcInfoGroups.push(comm);
+
+ comm.push(op("clamp", "clamp", IGT, [v(IGT, -4.0, 4.0), v(I, -2.0, 2.0), v(I, 2.0, 4.0)], f(0.125), f(0.5),
+ all, es3fShaderOperatorTests.ternaryVecScalarScalarFuncs(clampVecScalarScalar, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ comm.push(op("clamp", "clamp", UGT, [v(UGT, 0.0, 8.0), v(UGT, 2.0, 6.0), v(UGT, 6.0, 8.0)], f(0.125), f(0.0),
+ all, es3fShaderOperatorTests.ternaryGenTypeFuncs(deMath.clamp, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ comm.push(op("clamp", "clamp", UGT, [v(UV, 0.0, 8.0), v(U, 2.0, 6.0), v(U, 6.0, 8.0)], f(0.125), f(0.0),
+ all, es3fShaderOperatorTests.ternaryVecScalarScalarFuncs(clampVecScalarScalar, gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT)));
+ comm.push(op("mix", "mix", GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 1.0), v(GT, 0.0, 1.0)], f(0.5), f(0.5),
+ all, es3fShaderOperatorTests.ternaryGenTypeFuncs(mix)));
+ comm.push(op("mix", "mix", GT, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0), v(F, 0.0, 1.0)], f(0.5), f(0.5),
+ all, es3fShaderOperatorTests.ternaryVecVecScalarFuncs(mixVecVecScalar)));
+
+ comm = new es3fShaderOperatorTests.BuiltinFuncGroup("common_functions", "Common function tests.");
+ funcInfoGroups.push(comm);
+
+ comm.push(op("step", "step", GT, [v(GT, -1.0, 1.0), v(GT, -1.0, 0.0)], f(0.5), f(0.25),
+ all, es3fShaderOperatorTests.binaryGenTypeFuncs(step)));
+ comm.push(op("step", "step", GT, [v(F, -1.0, 1.0), v(FV, -1.0, 0.0)], f(0.5), f(0.25),
+ all, es3fShaderOperatorTests.binaryScalarVecFuncs(stepScalarVec)));
+ comm.push(op("smoothstep", "smoothstep", GT, [v(GT, -0.5, 0.0), v(GT, 0.1, 1.0), v(GT, -1.0, 1.0)], f(0.5), f(0.5),
+ all, es3fShaderOperatorTests.ternaryGenTypeFuncs(smoothStep)));
+ comm.push(op("smoothstep", "smoothstep", GT, [v(F, -0.5, 0.0), v(F, 0.1, 1.0), v(FV, -1.0, 1.0)], f(0.5), f(0.5),
+ all, es3fShaderOperatorTests.ternaryScalarScalarVecFuncs(smoothStepScalarScalarVec)));
+
+ // 8.4 Geometric Functions.
+ var geom = new es3fShaderOperatorTests.BuiltinFuncGroup("geometric", "Geometric function tests.");
+ geom.push(op("length", "length", F, [v(GT, -5.0, 5.0)], f(0.1), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.unaryScalarGenTypeFuncs(length)));
+ geom.push(op("distance", "distance", F, [v(GT, -5.0, 5.0), v(GT, -5.0, 5.0)], f(0.1), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(distance)));
+ geom.push(op("dot", "dot", F, [v(GT, -5.0, 5.0), v(GT, -5.0, 5.0)], f(0.1), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.binaryScalarGenTypeFuncs(dot)));
+ geom.push(op("cross", "cross", V3, [v(GT, -5.0, 5.0), v(GT, -5.0, 5.0)], f(0.1), f(0.5),
+ mediumhighp, {vec3: es3fShaderOperatorTests.binaryVecVecFuncs(cross).vec3}));
+ geom.push(op("normalize", "normalize", GT, [v(GT, 0.1, 4.0)], f(0.5), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.unaryArrayFuncs(normalize)));
+ geom.push(op("faceforward", "faceforward", GT, [v(GT, -5.0, 5.0), v(GT, -5.0, 5.0), v(GT, -1.0, 1.0)], f(0.5), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.ternaryVecVecVecFuncs(faceforward)));
+ geom.push(op("reflect", "reflect", GT, [v(GT, -0.8, -0.5), v(GT, 0.5, 0.8)], f(0.5), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.binaryVecVecFuncs(reflect)));
+ geom.push(op("refract", "refract", GT, [v(GT, -0.8, 1.2), v(GT, -1.1, 0.5), v(F, 0.2, 1.5)], f(0.5), f(0.5),
+ mediumhighp, es3fShaderOperatorTests.ternaryVecVecScalarFuncs(refract)));
+
+ funcInfoGroups.push(geom);
+
+ // 8.6 Vector Relational Functions.
+ var floatComp = new es3fShaderOperatorTests.BuiltinFuncGroup("float_compare", "Floating point comparison tests.");
+ floatComp.push(op("lessThan", "lessThan", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecVecFuncs(lessThanVec)));
+ floatComp.push(op("lessThanEqual", "lessThanEqual", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecVecFuncs(lessThanEqualVec)));
+ floatComp.push(op("greaterThan", "greaterThan", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecVecFuncs(greaterThanVec)));
+ floatComp.push(op("greaterThanEqual", "greaterThanEqual", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecVecFuncs(greaterThanEqualVec)));
+ floatComp.push(op("equal", "equal", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecVecFuncs(allEqualVec)));
+ floatComp.push(op("notEqual", "notEqual", BV, [v(FV, -1.0, 1.0), v(FV, -1.0, 1.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecVecFuncs(anyNotEqualVec)));
+
+ funcInfoGroups.push(floatComp);
+
+ var intComp = new es3fShaderOperatorTests.BuiltinFuncGroup("int_compare", "Integer comparison tests.");
+ intComp.push(op("lessThan", "lessThan", BV, [v(IV, 5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecVecFuncs(lessThanVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ intComp.push(op("lessThanEqual", "lessThanEqual", BV, [v(IV, -5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecVecFuncs(lessThanEqualVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ intComp.push(op("greaterThan", "greaterThan", BV, [v(IV, -5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecVecFuncs(greaterThanVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ intComp.push(op("greaterThanEqual", "greaterThanEqual", BV, [v(IV, -5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecVecFuncs(greaterThanEqualVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ intComp.push(op("equal", "equal", BV, [v(IV, -5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecVecFuncs(allEqualVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+ intComp.push(op("notEqual", "notEqual", BV, [v(IV, -5.2, 4.9), v(IV, -5.0, 5.0)], f(1.0), f(0.0),
+ all, es3fShaderOperatorTests.binaryVecVecFuncs(anyNotEqualVec, gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT)));
+
+ funcInfoGroups.push(intComp);
+
+ var boolComp = new es3fShaderOperatorTests.BuiltinFuncGroup("bool_compare", "Boolean comparison tests.");
+ var evalBoolEqual = es3fShaderOperatorTests.binaryVecVecFuncs(allEqualVec, gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL);
+ var evalBoolNotEqual = es3fShaderOperatorTests.binaryVecVecFuncs(anyNotEqualVec, gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL);
+ var evalBoolAny = es3fShaderOperatorTests.unaryBooleanGenTypeFuncs(boolAny, gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL);
+ evalBoolAny.scalar = null;
+ var evalBoolAll = es3fShaderOperatorTests.unaryBooleanGenTypeFuncs(boolAll, gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL);
+ evalBoolAll.scalar = null;
+ var evalBoolNot = es3fShaderOperatorTests.unaryArrayFuncs(boolNotVec, gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL);
+ evalBoolNot.scalar = null;
+
+ boolComp.push(op("equal", "equal", BV, [v(BV, -5.2, 4.9), v(BV, -5.0, 5.0)], f(1.0), f(0.0),
+ na, evalBoolEqual));
+ boolComp.push(op("notEqual", "notEqual", BV, [v(BV, -5.2, 4.9), v(BV, -5.0, 5.0)], f(1.0), f(0.0),
+ na, evalBoolNotEqual));
+ boolComp.push(op("any", "any", B, [v(BV, -1.0, 0.3)], f(1.0), f(0.0),
+ na, evalBoolAny));
+ boolComp.push(op("all", "all", B, [v(BV, -0.3, 1.0)], f(1.0), f(0.0),
+ na, evalBoolAll));
+ boolComp.push(op("not", "not", BV, [v(BV, -1.0, 1.0)], f(1.0), f(0.0),
+ na, evalBoolNot));
+
+ funcInfoGroups.push(boolComp);
+
+ var s_shaderTypes = [
+ gluShaderProgram.shaderType.VERTEX,
+ gluShaderProgram.shaderType.FRAGMENT
+ ];
+
+ var s_floatTypes = [
+ gluShaderUtil.DataType.FLOAT,
+ gluShaderUtil.DataType.FLOAT_VEC2,
+ gluShaderUtil.DataType.FLOAT_VEC3,
+ gluShaderUtil.DataType.FLOAT_VEC4
+ ];
+
+ var s_intTypes = [
+ gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT_VEC2,
+ gluShaderUtil.DataType.INT_VEC3,
+ gluShaderUtil.DataType.INT_VEC4
+ ];
+
+ var s_uintTypes = [
+ gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT_VEC2,
+ gluShaderUtil.DataType.UINT_VEC3,
+ gluShaderUtil.DataType.UINT_VEC4
+ ];
+
+ var s_boolTypes = [
+ gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL_VEC2,
+ gluShaderUtil.DataType.BOOL_VEC3,
+ gluShaderUtil.DataType.BOOL_VEC4
+ ];
+
+ for (var outerGroupNdx = 0; outerGroupNdx < funcInfoGroups.length; outerGroupNdx++) {
+ // Create outer group.
+ var outerGroupInfo = funcInfoGroups[outerGroupNdx];
+ var outerGroup = new tcuTestCase.DeqpTest(outerGroupInfo.name, outerGroupInfo.description);
+ this.addChild(outerGroup);
+
+ // Only create new group if name differs from previous one.
+ var innerGroup = null;
+
+ for (var funcInfoNdx = 0; funcInfoNdx < outerGroupInfo.funcInfos.length; funcInfoNdx++) {
+ var funcInfo = outerGroupInfo.funcInfos[funcInfoNdx];
+ var shaderFuncName = funcInfo.shaderFuncName;
+ var isBoolCase = (funcInfo.precision == es3fShaderOperatorTests.Precision.None);
+ var isBoolOut = es3fShaderOperatorTests.isBoolType(funcInfo.outValue);
+ var isIntOut = es3fShaderOperatorTests.isIntType(funcInfo.outValue);
+ var isUintOut = es3fShaderOperatorTests.isUintType(funcInfo.outValue);
+ var isFloatOut = !isBoolOut && !isIntOut && !isUintOut;
+
+ if (!innerGroup || (innerGroup.name != funcInfo.caseName)) {
+ var groupDesc = 'Built-in function ' + shaderFuncName + '() tests.';
+ innerGroup = new tcuTestCase.DeqpTest(funcInfo.caseName, groupDesc);
+ outerGroup.addChild(innerGroup);
+ }
+
+ for (var inScalarSize = 1; inScalarSize <= 4; inScalarSize++) {
+ var outScalarSize = ((funcInfo.outValue == es3fShaderOperatorTests.ValueType.FLOAT) || (funcInfo.outValue == es3fShaderOperatorTests.ValueType.BOOL)) ? 1 : inScalarSize; // \todo [petri] Int.
+ var outDataType = isFloatOut ? s_floatTypes[outScalarSize - 1] :
+ isIntOut ? s_intTypes[outScalarSize - 1] :
+ isUintOut ? s_uintTypes[outScalarSize - 1] :
+ isBoolOut ? s_boolTypes[outScalarSize - 1] :
+ undefined;
+
+ var evalFunc = null;
+ if (inScalarSize == 1) evalFunc = funcInfo.evalFunctions.scalar;
+ else if (inScalarSize == 2) evalFunc = funcInfo.evalFunctions.vec2;
+ else if (inScalarSize == 3) evalFunc = funcInfo.evalFunctions.vec3;
+ else if (inScalarSize == 4) evalFunc = funcInfo.evalFunctions.vec4;
+ else throw new Error('Invalid scalar size ' + inScalarSize);
+
+ // Skip if no valid eval func.
+ // \todo [petri] Better check for V3 only etc. cases?
+ if (evalFunc == null)
+ continue;
+
+ var precisions = ['low', 'medium', 'high'];
+ for (var precId = 0; precId < precisions.length; precId++) {
+ var precision = precisions[precId];
+ if ((funcInfo.precision[precision]) ||
+ (funcInfo.precision == es3fShaderOperatorTests.Precision.None && precision === 'medium')) { // use mediump interpolators for booleans
+ var precisionPrefix = isBoolCase ? '' : precision + 'p_';
+
+ for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
+ var shaderType = s_shaderTypes[shaderTypeNdx];
+ var shaderSpec = new es3fShaderOperatorTests.ShaderDataSpec();
+ var shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
+ var isVertexCase = shaderType == gluShaderProgram.shaderType.VERTEX;
+ var isUnaryOp = (funcInfo.inputs.length == 1);
+
+ // \note Data type names will be added to description and name in a following loop.
+ var desc = 'Built-in function ' + shaderFuncName + '(';
+ var name = precisionPrefix;
+
+ // Generate shader op.
+ var shaderOp = 'res = ';
+
+ var precNames = [gluShaderUtil.precision.PRECISION_LOWP,
+ gluShaderUtil.precision.PRECISION_MEDIUMP,
+ gluShaderUtil.precision.PRECISION_HIGHP];
+ // Setup shader data info.
+ shaderSpec.numInputs = 0;
+ shaderSpec.precision = isBoolCase ? undefined : precNames[precId];
+ shaderSpec.output = outDataType;
+ shaderSpec.resultScale = funcInfo.resultScale;
+ shaderSpec.resultBias = funcInfo.resultBias;
+ shaderSpec.referenceScale = funcInfo.referenceScale;
+ shaderSpec.referenceBias = funcInfo.referenceBias;
+
+ if (funcInfo.type == es3fShaderOperatorTests.OperationType.OPERATOR) {
+ if (isUnaryOp && funcInfo.isUnaryPrefix)
+ shaderOp += shaderFuncName;
+ } else if (funcInfo.type == es3fShaderOperatorTests.OperationType.FUNCTION)
+ shaderOp += shaderFuncName + '(';
+ else // SIDE_EFFECT_OPERATOR
+ shaderOp += 'in0;\n\t';
+
+ for (var inputNdx = 0; inputNdx < funcInfo.inputs.length; inputNdx++) {
+ var prevNdx = inputNdx > 0 ? inputNdx - 1 : funcInfo.inputs.length - 1;
+ var prevValue = funcInfo.inputs[prevNdx];
+ var value = funcInfo.inputs[inputNdx];
+
+ if (value.valueType == es3fShaderOperatorTests.ValueType.NONE)
+ continue; // Skip unused input.
+
+ var prevInScalarSize = es3fShaderOperatorTests.isScalarType(prevValue.valueType) ? 1 : inScalarSize;
+ var prevInDataType = es3fShaderOperatorTests.isFloatType(prevValue.valueType) ? s_floatTypes[prevInScalarSize - 1] :
+ es3fShaderOperatorTests.isIntType(prevValue.valueType) ? s_intTypes[prevInScalarSize - 1] :
+ es3fShaderOperatorTests.isUintType(prevValue.valueType) ? s_uintTypes[prevInScalarSize - 1] :
+ es3fShaderOperatorTests.isBoolType(prevValue.valueType) ? s_boolTypes[prevInScalarSize - 1] :
+ undefined;
+
+ var curInScalarSize = es3fShaderOperatorTests.isScalarType(value.valueType) ? 1 : inScalarSize;
+ var curInDataType = es3fShaderOperatorTests.isFloatType(value.valueType) ? s_floatTypes[curInScalarSize - 1] :
+ es3fShaderOperatorTests.isIntType(value.valueType) ? s_intTypes[curInScalarSize - 1] :
+ es3fShaderOperatorTests.isUintType(value.valueType) ? s_uintTypes[curInScalarSize - 1] :
+ es3fShaderOperatorTests.isBoolType(value.valueType) ? s_boolTypes[curInScalarSize - 1] :
+ undefined;
+
+ // Write input type(s) to case description and name.
+
+ if (inputNdx > 0)
+ desc += ', ';
+
+ desc += gluShaderUtil.getDataTypeName(curInDataType);
+
+ if (inputNdx == 0 || prevInDataType != curInDataType) // \note Only write input type to case name if different from previous input type (avoid overly long names).
+ name += gluShaderUtil.getDataTypeName(curInDataType) + '_';
+
+ // Generate op input source.
+
+ if (funcInfo.type == es3fShaderOperatorTests.OperationType.OPERATOR || funcInfo.type == es3fShaderOperatorTests.OperationType.FUNCTION) {
+ if (inputNdx != 0) {
+ if (funcInfo.type == es3fShaderOperatorTests.OperationType.OPERATOR && !isUnaryOp)
+ shaderOp += ' ' + shaderFuncName + ' ';
+ else
+ shaderOp += ', ';
+ }
+
+ shaderOp += 'in' + inputNdx.toString(10);
+
+ if (funcInfo.type == es3fShaderOperatorTests.OperationType.OPERATOR && isUnaryOp && !funcInfo.isUnaryPrefix)
+ shaderOp += shaderFuncName;
+ } else{
+ if (inputNdx != 0 || (isUnaryOp && funcInfo.isUnaryPrefix))
+ shaderOp += (isUnaryOp ? '' : ' ') + shaderFuncName + (isUnaryOp ? '' : ' ');
+
+ shaderOp += inputNdx == 0 ? 'res' : 'in' + inputNdx.toString(10); // \note in0 has already been assigned to res, so start from in1.
+
+ if (isUnaryOp && !funcInfo.isUnaryPrefix)
+ shaderOp += shaderFuncName;
+ }
+
+ // Fill in shader info.
+ shaderSpec.inputs[shaderSpec.numInputs++] = new es3fShaderOperatorTests.ShaderValue(curInDataType, value.rangeMin, value.rangeMax);
+ }
+
+ if (funcInfo.type == es3fShaderOperatorTests.OperationType.FUNCTION)
+ shaderOp += ')';
+
+ shaderOp += ';';
+
+ desc += ').';
+ name += shaderTypeName;
+
+ // Create the test case.
+ innerGroup.addChild(new es3fShaderOperatorTests.ShaderOperatorCase(name, desc, isVertexCase, evalFunc, shaderOp, shaderSpec));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // The ?: selection operator.
+
+ var s_selectionInfo = [
+ gluShaderUtil.DataType.FLOAT,
+ gluShaderUtil.DataType.FLOAT_VEC2,
+ gluShaderUtil.DataType.FLOAT_VEC3,
+ gluShaderUtil.DataType.FLOAT_VEC4,
+ gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT_VEC2,
+ gluShaderUtil.DataType.INT_VEC3,
+ gluShaderUtil.DataType.INT_VEC4,
+ gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT_VEC2,
+ gluShaderUtil.DataType.UINT_VEC3,
+ gluShaderUtil.DataType.UINT_VEC4,
+ gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL_VEC2,
+ gluShaderUtil.DataType.BOOL_VEC3,
+ gluShaderUtil.DataType.BOOL_VEC4
+ ];
+
+ var selectionEvalFuncsFloat = es3fShaderOperatorTests.selectionFuncs(gluShaderUtil.DataType.FLOAT);
+ var selectionEvalFuncsInt = es3fShaderOperatorTests.selectionFuncs(gluShaderUtil.DataType.INT);
+ var selectionEvalFuncsUint = es3fShaderOperatorTests.selectionFuncs(gluShaderUtil.DataType.UINT);
+ var selectionEvalFuncsBool = es3fShaderOperatorTests.selectionFuncs(gluShaderUtil.DataType.BOOL);
+
+ var selectionGroup = new tcuTestCase.DeqpTest('selection', 'Selection operator tests');
+ this.addChild(selectionGroup);
+
+ for (var typeNdx = 0; typeNdx < s_selectionInfo.length; typeNdx++) {
+ var curType = s_selectionInfo[typeNdx];
+ var scalarSize = gluShaderUtil.getDataTypeScalarSize(curType);
+ var isBoolCase = gluShaderUtil.isDataTypeBoolOrBVec(curType);
+ var isFloatCase = gluShaderUtil.isDataTypeFloatOrVec(curType);
+ var isIntCase = gluShaderUtil.isDataTypeIntOrIVec(curType);
+ var isUintCase = gluShaderUtil.isDataTypeUintOrUVec(curType);
+ var dataTypeStr = gluShaderUtil.getDataTypeName(curType);
+
+ var evalFuncs = selectionEvalFuncsFloat;
+ if (isBoolCase)
+ evalFuncs = selectionEvalFuncsBool;
+ else if (isIntCase)
+ evalFuncs = selectionEvalFuncsInt;
+ else if (isUintCase)
+ evalFuncs = selectionEvalFuncsUint;
+
+ var evalFunc = evalFuncs[scalarSize];
+
+ for (var prec in gluShaderUtil.precision) {
+ var precision = gluShaderUtil.precision[prec];
+ if (isBoolCase && precision != gluShaderUtil.precision.PRECISION_MEDIUMP) // Use mediump interpolators for booleans.
+ continue;
+
+ var precisionStr = gluShaderUtil.getPrecisionName(precision);
+ var precisionPrefix = isBoolCase ? '' : (precisionStr + '_');
+
+ for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
+ var shaderType = s_shaderTypes[shaderTypeNdx];
+ var shaderSpec = new es3fShaderOperatorTests.ShaderDataSpec();
+ var shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
+ var isVertexCase = shaderType == gluShaderProgram.shaderType.VERTEX;
+
+ var name = precisionPrefix + dataTypeStr + '_' + shaderTypeName;
+
+ shaderSpec.numInputs = 3;
+ shaderSpec.precision = isBoolCase ? undefined : precision;
+ shaderSpec.output = curType;
+ shaderSpec.resultScale = isBoolCase ? f(1.0) : isFloatCase ? f(0.5) : isUintCase ? f(0.5) : f(0.1);
+ shaderSpec.resultBias = isBoolCase ? f(0.0) : isFloatCase ? f(0.5) : isUintCase ? f(0.0) : f(0.5);
+ shaderSpec.referenceScale = shaderSpec.resultScale;
+ shaderSpec.referenceBias = shaderSpec.resultBias;
+
+ var rangeMin = isBoolCase ? -1.0 : isFloatCase ? -1.0 : isUintCase ? 0.0 : -5.0;
+ var rangeMax = isBoolCase ? 1.0 : isFloatCase ? 1.0 : isUintCase ? 2.0 : 5.0;
+
+ shaderSpec.inputs[0] = new es3fShaderOperatorTests.ShaderValue(gluShaderUtil.DataType.BOOL, f(-1.0), f(1.0));
+ shaderSpec.inputs[1] = new es3fShaderOperatorTests.ShaderValue(curType, f(rangeMin), f(rangeMax));
+ shaderSpec.inputs[2] = new es3fShaderOperatorTests.ShaderValue(curType, f(rangeMin), f(rangeMax));
+
+ selectionGroup.addChild(new es3fShaderOperatorTests.ShaderOperatorCase(name, '', isVertexCase, evalFunc, 'res = in0 ? in1 : in2;', shaderSpec));
+ }
+ }
+ }
+
+ // The sequence operator (comma).
+ /** @type {tcuTestCase.DeqpTest} */ var sequenceGroup = new tcuTestCase.DeqpTest('sequence', 'sequence');
+ this.addChild(sequenceGroup);
+
+ /** @type {tcuTestCase.DeqpTest} */ var sequenceNoSideEffGroup = new tcuTestCase.DeqpTest('no_side_effects', 'Sequence tests without side-effects');
+ /** @type {tcuTestCase.DeqpTest} */ var sequenceSideEffGroup = new tcuTestCase.DeqpTest('side_effects', 'Sequence tests with side-effects');
+ sequenceGroup.addChild(sequenceNoSideEffGroup);
+ sequenceGroup.addChild(sequenceSideEffGroup);
+
+ /**
+ * @struct
+ * @constructor
+ * @param {boolean} containsSideEffects
+ * @param {string} caseName
+ * @param {string} expressionStr
+ * @param {number} numInputs
+ * @param {Array<gluShaderUtil.DataType>} inputTypes
+ * @param {gluShaderUtil.DataType} resultType
+ * @param {glsShaderRenderCase.ShaderEvalFunc} evalFunc
+ */
+ var SequenceCase = function(containsSideEffects, caseName, expressionStr, numInputs, inputTypes, resultType, evalFunc) {
+ /** @type {boolean} */ this.containsSideEffects = containsSideEffects;
+ /** @type {string} */ this.caseName = caseName;
+ /** @type {string} */ this.expressionStr = expressionStr;
+ /** @type {number} */ this.numInputs = numInputs;
+ /** @type {Array<gluShaderUtil.DataType>} */ this.inputTypes = inputTypes;
+ /** @type {gluShaderUtil.DataType} */ this.resultType = resultType;
+ /** @type {glsShaderRenderCase.ShaderEvalFunc} */ this.evalFunc = evalFunc;
+ };
+
+ /** @type {Array<SequenceCase>} */ var s_sequenceCases = [
+ new SequenceCase(false, 'vec4', 'in0, in2 + in1, in1 + in0', 3, [gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.DataType.FLOAT_VEC4], gluShaderUtil.DataType.FLOAT_VEC4, es3fShaderOperatorTests.evalSequenceNoSideEffCase0),
+ new SequenceCase(false, 'float_uint', 'in0 + in2, in1 + in1', 3, [gluShaderUtil.DataType.FLOAT, gluShaderUtil.DataType.UINT, gluShaderUtil.DataType.FLOAT], gluShaderUtil.DataType.UINT, es3fShaderOperatorTests.evalSequenceNoSideEffCase1),
+ new SequenceCase(false, 'bool_vec2', 'in0 && in1, in0, ivec2(vec2(in0) + in2)', 3, [gluShaderUtil.DataType.BOOL, gluShaderUtil.DataType.BOOL, gluShaderUtil.DataType.FLOAT_VEC2], gluShaderUtil.DataType.INT_VEC2, es3fShaderOperatorTests.evalSequenceNoSideEffCase2),
+ new SequenceCase(false, 'vec4_ivec4_bvec4', 'in0 + vec4(in1), in2, in1', 3, [gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.DataType.INT_VEC4, gluShaderUtil.DataType.BOOL_VEC4], gluShaderUtil.DataType.INT_VEC4, es3fShaderOperatorTests.evalSequenceNoSideEffCase3),
+
+ new SequenceCase(true, 'vec4', 'in0++, in1 = in0 + in2, in2 = in1', 3, [gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.DataType.FLOAT_VEC4], gluShaderUtil.DataType.FLOAT_VEC4, es3fShaderOperatorTests.evalSequenceSideEffCase0),
+ new SequenceCase(true, 'float_uint', 'in1++, in0 = float(in1), in1 = uint(in0 + in2)', 3, [gluShaderUtil.DataType.FLOAT, gluShaderUtil.DataType.UINT, gluShaderUtil.DataType.FLOAT], gluShaderUtil.DataType.UINT, es3fShaderOperatorTests.evalSequenceSideEffCase1),
+ new SequenceCase(true, 'bool_vec2', 'in1 = in0, in2++, in2 = in2 + vec2(in1), ivec2(in2)', 3, [gluShaderUtil.DataType.BOOL, gluShaderUtil.DataType.BOOL, gluShaderUtil.DataType.FLOAT_VEC2], gluShaderUtil.DataType.INT_VEC2, es3fShaderOperatorTests.evalSequenceSideEffCase2),
+ new SequenceCase(true, 'vec4_ivec4_bvec4', 'in0 = in0 + vec4(in2), in1 = in1 + ivec4(in0), in1++', 3, [gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.DataType.INT_VEC4, gluShaderUtil.DataType.BOOL_VEC4], gluShaderUtil.DataType.INT_VEC4, es3fShaderOperatorTests.evalSequenceSideEffCase3)
+ ];
+
+ for (var caseNdx = 0; caseNdx < s_sequenceCases.length; caseNdx++) {
+ for (var precision in gluShaderUtil.precision) {
+ for (var shaderTypeNdx = 0; shaderTypeNdx < s_shaderTypes.length; shaderTypeNdx++) {
+ /** @type {gluShaderProgram.shaderType} */ var shaderType = s_shaderTypes[shaderTypeNdx];
+ /** @type {es3fShaderOperatorTests.ShaderDataSpec} */ var shaderSpec = new es3fShaderOperatorTests.ShaderDataSpec();
+ /** @type {string} */ var shaderTypeName = gluShaderProgram.getShaderTypeName(shaderType);
+ /** @type {boolean} */ var isVertexCase = shaderType === gluShaderProgram.shaderType.VERTEX;
+
+ /** @type {string} */ var name = gluShaderUtil.getPrecisionName(gluShaderUtil.precision[precision]) + '_' + s_sequenceCases[caseNdx].caseName + '_' + shaderTypeName;
+
+ shaderSpec.numInputs = s_sequenceCases[caseNdx].numInputs;
+ shaderSpec.precision = gluShaderUtil.precision[precision];
+ shaderSpec.output = s_sequenceCases[caseNdx].resultType;
+ shaderSpec.resultScale = f(0.5);
+ shaderSpec.resultBias = f(0.0);
+ shaderSpec.referenceScale = shaderSpec.resultScale;
+ shaderSpec.referenceBias = shaderSpec.resultBias;
+
+ for (var inputNdx = 0; inputNdx < s_sequenceCases[caseNdx].numInputs; inputNdx++) {
+ /** @type {gluShaderUtil.DataType} */ var type = s_sequenceCases[caseNdx].inputTypes[inputNdx];
+ /** @type {es3fShaderOperatorTests.FloatScalar} */ var rangeMin = gluShaderUtil.isDataTypeFloatOrVec(type) ?
+ f(-0.5) : gluShaderUtil.isDataTypeIntOrIVec(type) ?
+ f(-2.0) : gluShaderUtil.isDataTypeUintOrUVec(type) ?
+ f(0.0) : f(-1.0);
+
+ /** @type {es3fShaderOperatorTests.FloatScalar} */ var rangeMax = gluShaderUtil.isDataTypeFloatOrVec(type) ?
+ f(0.5) : gluShaderUtil.isDataTypeIntOrIVec(type) ?
+ f(2.0) : gluShaderUtil.isDataTypeUintOrUVec(type) ?
+ f(2.0) : f(1.0);
+
+ shaderSpec.inputs[inputNdx] = new es3fShaderOperatorTests.ShaderValue(type, rangeMin, rangeMax);
+ }
+
+ /** @type {string} */ var expression = 'res = (' + s_sequenceCases[caseNdx].expressionStr + ');';
+
+ if (s_sequenceCases[caseNdx].containsSideEffects)
+ sequenceSideEffGroup.addChild(new es3fShaderOperatorTests.ShaderOperatorCase(name, '', isVertexCase, s_sequenceCases[caseNdx].evalFunc, expression, shaderSpec));
+ else
+ sequenceNoSideEffGroup.addChild(new es3fShaderOperatorTests.ShaderOperatorCase(name, '', isVertexCase, s_sequenceCases[caseNdx].evalFunc, expression, shaderSpec));
+ }
+ }
+ }
+
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fShaderOperatorTests.run = function(context, range) {
+ gl = context;
+
+ const canvas = gl.canvas;
+ canvas.width = canvasWH;
+ canvas.height = canvasWH;
+
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fShaderOperatorTests.ShaderOperatorTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fShaderOperatorTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderPackingFunctionTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderPackingFunctionTests.js
new file mode 100644
index 0000000000..3e4233db4c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderPackingFunctionTests.js
@@ -0,0 +1,791 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fShaderPackingFunctionTests');
+goog.require('framework.common.tcuFloat');
+goog.require('framework.common.tcuMatrixUtil');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluVarType');
+goog.require('modules.shared.glsShaderExecUtil');
+
+
+
+goog.scope(function() {
+ var es3fShaderPackingFunctionTests = functional.gles3.es3fShaderPackingFunctionTests;
+ var tcuFloat = framework.common.tcuFloat;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var deMath = framework.delibs.debase.deMath;
+ var deRandom = framework.delibs.debase.deRandom;
+ var deString = framework.delibs.debase.deString;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluVarType = framework.opengl.gluVarType;
+ var glsShaderExecUtil = modules.shared.glsShaderExecUtil;
+ var tcuMatrixUtil = framework.common.tcuMatrixUtil;
+ /**
+ * @param {number} a
+ * @param {number} b
+ * @return {number}
+ */
+ es3fShaderPackingFunctionTests.getUlpDiff = function(a, b) {
+ /** @type {number} */ var aBits = tcuFloat.newFloat32(a).bits();
+ /** @type {number} */ var bBits = tcuFloat.newFloat32(b).bits();
+ return aBits > bBits ? aBits - bBits : bBits - aBits;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderPackingFunctionTests.ShaderPackingFunctionCase = function(name, description, shaderType) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ /** @type {gluShaderProgram.shaderType} */ this.m_shaderType = shaderType;
+ /** @type {?glsShaderExecUtil.ShaderSpec} */ this.m_spec = new glsShaderExecUtil.ShaderSpec();
+ /** @type {?glsShaderExecUtil.ShaderExecutor} */ this.m_executor = null;
+ };
+
+ es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.prototype.constructor = es3fShaderPackingFunctionTests.ShaderPackingFunctionCase;
+
+ es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.prototype.init = function() {
+ assertMsgOptions(!this.m_executor, 'Error: Executor is not null.', false, true);
+ this.m_executor = glsShaderExecUtil.createExecutor(this.m_shaderType, this.m_spec);
+ if (!this.m_executor.isOk())
+ throw new Error('Compile failed');
+ };
+
+ es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.prototype.deinit = function() {
+ this.m_executor = null;
+ };
+
+ /**
+ * @param {gluShaderUtil.precision} precision
+ * @return {string}
+ */
+ es3fShaderPackingFunctionTests.getPrecisionPostfix = function(precision) {
+ /** @type {Array<string>} */ var s_postfix = [
+ '_lowp',
+ '_mediump',
+ '_highp'
+ ];
+ assertMsgOptions(0 <= precision && precision < s_postfix.length, 'Error: Out of range', false, true);
+ return s_postfix[precision];
+ };
+
+ /**
+ * @param {gluShaderProgram.shaderType} shaderType
+ * @return {string}
+ */
+ es3fShaderPackingFunctionTests.getShaderTypePostfix = function(shaderType) {
+ /** @type {Array<string>} */ var s_postfix = [
+ '_vertex',
+ '_fragment'
+ ];
+ assertMsgOptions(0 <= shaderType && shaderType < s_postfix.length, 'Error Out of range', false, true);
+ return s_postfix[shaderType];
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderPackingFunctionTests.ShaderPackingFunctionCase}
+ * @param {gluShaderProgram.shaderType} shaderType
+ * @param {gluShaderUtil.precision} precision
+ */
+ es3fShaderPackingFunctionTests.PackSnorm2x16Case = function(shaderType, precision) {
+ /** @const {string} */ var name = 'packsnorm2x16' +
+ es3fShaderPackingFunctionTests.getPrecisionPostfix(precision) +
+ es3fShaderPackingFunctionTests.getShaderTypePostfix(shaderType);
+ es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.call(this, name, 'packSnorm2x16', shaderType);
+ this.m_precision = precision;
+
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_VEC2, precision)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(gluShaderUtil.DataType.UINT, gluShaderUtil.precision.PRECISION_HIGHP)));
+ this.m_spec.source = 'out0 = packSnorm2x16(in0);';
+ };
+
+ es3fShaderPackingFunctionTests.PackSnorm2x16Case.prototype = Object.create(es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.prototype);
+ es3fShaderPackingFunctionTests.PackSnorm2x16Case.prototype.constructor = es3fShaderPackingFunctionTests.PackSnorm2x16Case;
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderPackingFunctionTests.PackSnorm2x16Case.prototype.iterate = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0x776002);
+ /** @type {Array<Array<number>>} */ var inputs = [];
+ /** @type {goog.TypedArray} */ var outputs; // deUint32
+ /** @type {goog.TypedArray} */ var shaderExecutorOutput;
+ /** @type {number} */ var maxDiff = this.m_precision == gluShaderUtil.precision.PRECISION_HIGHP ? 1 : // Rounding only.
+ this.m_precision == gluShaderUtil.precision.PRECISION_MEDIUMP ? 33 : // (2^-10) * (2^15) + 1
+ this.m_precision == gluShaderUtil.precision.PRECISION_LOWP ? 129 : 0; // (2^-8) * (2^15) + 1
+ /** @type {number} */ var x;
+ /** @type {number} */ var y;
+ // Special values to check.
+ inputs.push([0.0, 0.0]);
+ inputs.push([-1.0, 1.0]);
+ inputs.push([0.5, -0.5]);
+ inputs.push([-1.5, 1.5]);
+ inputs.push([0.25, -0.75]);
+
+ // Random values, mostly in range.
+ for (var ndx = 0; ndx < 15; ndx++) {
+ x = rnd.getFloat() * 2.5 - 1.25;
+ y = rnd.getFloat() * 2.5 - 1.25;
+ inputs.push([x, y]);
+ }
+
+ // Large random values.
+ for (var ndx = 0; ndx < 80; ndx++) {
+ x = rnd.getFloat() * 1e6 - 0.5e6;
+ y = rnd.getFloat() * 1e6 - 0.5e6;
+ inputs.push([x, y]);
+ }
+
+ bufferedLogToConsole('Executing shader for ' + inputs.length + ' input values');
+
+ this.m_executor.useProgram();
+ shaderExecutorOutput = this.m_executor.execute(inputs.length, [tcuMatrixUtil.flatten(inputs)])[0];
+
+ // Convert outputs if we get them as Uint8Array.
+ // - VertexShaderExecutor.execute() returns either an array of Uint8Array
+ // - FragmentShaderExecutor.execute() returns either an array of Uint8Array or Uint32Array
+ outputs = new Uint32Array(shaderExecutorOutput.buffer);
+
+ // Verify
+ /** @type {number} */ var numValues = inputs.length;
+ /** @type {number} */ var maxPrints = 10;
+ /** @type {number} */ var numFailed = 0;
+
+ for (var valNdx = 0; valNdx < numValues; valNdx++) {
+ /** @type {number} */ var ref0 = (deMath.clamp(Math.floor(deMath.clamp(inputs[valNdx][0], -1.0, 1.0) * 32767.0), -(1 << 15), (1 << 15) - 1)) & 0xFFFF;
+ /** @type {number} */ var ref1 = (deMath.clamp(Math.floor(deMath.clamp(inputs[valNdx][1], -1.0, 1.0) * 32767.0), -(1 << 15), (1 << 15) - 1)) & 0xFFFF;
+ /** @type {number} */ var ref = (ref1 << 16) | ref0;
+ /** @type {number} */ var res = outputs[valNdx];
+ /** @type {number} */ var res0 = (res & 0xffff);
+ /** @type {number} */ var res1 = deMath.shiftRight(res, 16);
+ /** @type {number} */ var diff0 = Math.abs(ref0 - res0);
+ /** @type {number} */ var diff1 = Math.abs(ref1 - res1);
+
+ if (diff0 > maxDiff || diff1 > maxDiff) {
+ if (numFailed < maxPrints) {
+ bufferedLogToConsole(
+ 'ERROR: Mismatch in value ' + valNdx +
+ ', expected packSnorm2x16(' + inputs[valNdx] + ') = ' + ref + //tcu::toHex(ref)
+ ', got ' + res + // tcu::toHex(res)
+ '\n diffs = (' + diff0 + ', ' + diff1 + '), max diff = ' + maxDiff);
+ }
+ else if (numFailed == maxPrints)
+ bufferedLogToConsole('...');
+
+ numFailed += 1;
+ }
+ }
+
+ bufferedLogToConsole((numValues - numFailed) + ' / ' + numValues + ' values passed');
+
+ /** @type {boolean} */ var isOk = numFailed === 0;
+ if (!isOk)
+ testFailedOptions('Result comparison failed', false);
+ else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+
+ /**
+ * @constructor
+ * @extends {es3fShaderPackingFunctionTests.ShaderPackingFunctionCase}
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderPackingFunctionTests.UnpackSnorm2x16Case = function(shaderType) {
+ /** @const {string} */ var name = 'unpacksnorm2x16' + es3fShaderPackingFunctionTests.getShaderTypePostfix(shaderType);
+ es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.call(this, name, 'unpackSnorm2x16', shaderType);
+
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(gluShaderUtil.DataType.UINT, gluShaderUtil.precision.PRECISION_HIGHP)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_VEC2, gluShaderUtil.precision.PRECISION_HIGHP)));
+ this.m_spec.source = 'out0 = unpackSnorm2x16(in0);';
+ };
+
+ es3fShaderPackingFunctionTests.UnpackSnorm2x16Case.prototype = Object.create(es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.prototype);
+ es3fShaderPackingFunctionTests.UnpackSnorm2x16Case.prototype.constructor = es3fShaderPackingFunctionTests.UnpackSnorm2x16Case;
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderPackingFunctionTests.UnpackSnorm2x16Case.prototype.iterate = function() {
+ /** @type {number} */ var maxDiff = 1; // Rounding error.
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0x776002);
+ /** @type {Array<number>} */ var inputs = [];
+ /** @type {goog.TypedArray} */ var shaderExecutorOutput; //vector<vec2<float>>
+ /** @type {goog.TypedArray} */ var outputs; //vector<vec2<float>>
+
+ inputs.push(0x00000000);
+ inputs.push(0x7fff8000);
+ inputs.push(0x80007fff);
+ inputs.push(0xffffffff);
+ inputs.push(0x0001fffe);
+
+ // Random values.
+ for (var ndx = 0; ndx < 95; ndx++)
+ inputs.push(rnd.getInt());
+
+ bufferedLogToConsole('Executing shader for ' + inputs.length + ' input values');
+
+ this.m_executor.useProgram();
+ shaderExecutorOutput = this.m_executor.execute(inputs.length, [inputs])[0]; // This test case only has one output
+
+ // Convert outputs if we get them as Uint8Array.
+ // - VertexShaderExecutor.execute() returns either an array of Uint8Array
+ // - FragmentShaderExecutor.execute() returns either an array of Uint8Array or Uint32Array
+ outputs = new Float32Array(shaderExecutorOutput.buffer);
+
+ // Verify
+ /** @type {number} */ var numValues = inputs.length;
+ /** @type {number} */ var maxPrints = 10;
+ /** @type {number} */ var numFailed = 0;
+
+ for (var valNdx = 0; valNdx < inputs.length; valNdx++) {
+ /** @type {number} */ var in0 = Math.floor(inputs[valNdx] & 0xffff);
+ // Convert 16-bit uint to 16-bit int
+ var view = new DataView(new ArrayBuffer(4));
+ view.setUint16(0, in0, true);
+ in0 = view.getInt16(0, true);
+ /** @type {number} */ var in1 = Math.floor(deMath.shiftRight(inputs[valNdx], 16));
+ // Convert 16-bit uint to 16-bit int
+ var view = new DataView(new ArrayBuffer(4));
+ view.setUint16(0, in1, true);
+ in1 = view.getInt16(0, true);
+ /** @type {number} */ var ref0 = deMath.clamp(in0 / 32767., -1.0, 1.0);
+ /** @type {number} */ var ref1 = deMath.clamp(in1 / 32767., -1.0, 1.0);
+ /** @type {number} */ var res0 = outputs[2 * valNdx];
+ /** @type {number} */ var res1 = outputs[2 * valNdx + 1];
+
+ /** @type {number} */ var diff0 = es3fShaderPackingFunctionTests.getUlpDiff(ref0, res0);
+ /** @type {number} */ var diff1 = es3fShaderPackingFunctionTests.getUlpDiff(ref1, res1);
+
+ if (diff0 > maxDiff || diff1 > maxDiff) {
+ if (numFailed < maxPrints)
+ bufferedLogToConsole('ERROR: Mismatch in value ' + valNdx + ',\n' +
+ ' expected unpackSnorm2x16(' + inputs[valNdx].toString(16) + ') = ' +
+ 'vec2(' + ref0.toString(16) + ', ' + ref1.toString(16) + ')' +
+ ', got vec2(' + res0.toString(16) + ', ' + res1.toString(16) + ')' +
+ '\n ULP diffs = (' + diff0 + ', ' + diff1 + '), max diff = ' + maxDiff);
+ else if (numFailed == maxPrints)
+ bufferedLogToConsole('...');
+
+ numFailed += 1;
+ }
+ }
+
+ bufferedLogToConsole((numValues - numFailed) + ' / ' + numValues + ' values passed');
+
+ /** @type {boolean} */ var isOk = numFailed === 0;
+ if (!isOk)
+ testFailedOptions('Result comparison failed', false);
+ else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderPackingFunctionTests.ShaderPackingFunctionCase}
+ * @param {gluShaderProgram.shaderType} shaderType
+ * @param {gluShaderUtil.precision} precision
+ */
+ es3fShaderPackingFunctionTests.PackUnorm2x16Case = function(shaderType, precision) {
+ /** @const {string} */ var name = 'packunorm2x16' +
+ es3fShaderPackingFunctionTests.getPrecisionPostfix(precision) +
+ es3fShaderPackingFunctionTests.getShaderTypePostfix(shaderType);
+ es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.call(this, name, 'packUnorm2x16', shaderType);
+ this.m_precision = precision;
+
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_VEC2, precision)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(gluShaderUtil.DataType.UINT, gluShaderUtil.precision.PRECISION_HIGHP)));
+ this.m_spec.source = 'out0 = packUnorm2x16(in0);';
+ };
+
+ es3fShaderPackingFunctionTests.PackUnorm2x16Case.prototype = Object.create(es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.prototype);
+ es3fShaderPackingFunctionTests.PackUnorm2x16Case.prototype.constructor = es3fShaderPackingFunctionTests.PackUnorm2x16Case;
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderPackingFunctionTests.PackUnorm2x16Case.prototype.iterate = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0x776002);
+ /** @type {Array<Array<number>>} */ var inputs = [];
+ /** @type {goog.TypedArray} */ var shaderExecutorOutput;
+ /** @type {goog.TypedArray} */ var outputs; // deUint32
+ /** @type {number} */ var maxDiff = this.m_precision == gluShaderUtil.precision.PRECISION_HIGHP ? 1 : // Rounding only.
+ this.m_precision == gluShaderUtil.precision.PRECISION_MEDIUMP ? 65 : // (2^-10) * (2^16) + 1
+ this.m_precision == gluShaderUtil.precision.PRECISION_LOWP ? 257 : 0; // (2^-8) * (2^16) + 1
+ /** @type {number} */ var x;
+ /** @type {number} */ var y;
+ // Special values to check.
+ inputs.push([0.0, 0.0]);
+ inputs.push([0.5, 1.0]);
+ inputs.push([1.0, 0.5]);
+ inputs.push([-0.5, 1.5]);
+ inputs.push([0.25, 0.75]);
+
+ // Random values, mostly in range.
+ for (var ndx = 0; ndx < 15; ndx++) {
+ x = rnd.getFloat() * 1.25;
+ y = rnd.getFloat() * 1.25;
+ inputs.push([x, y]);
+ }
+
+ // Large random values.
+ for (var ndx = 0; ndx < 80; ndx++) {
+ x = rnd.getFloat() * 1e6 - 1e5;
+ y = rnd.getFloat() * 1e6 - 1e5;
+ inputs.push([x, y]);
+ }
+
+ bufferedLogToConsole('Executing shader for ' + inputs.length + ' input values');
+
+ this.m_executor.useProgram();
+ shaderExecutorOutput = this.m_executor.execute(inputs.length, [tcuMatrixUtil.flatten(inputs)])[0];
+
+ // Convert outputs if we get them as Uint8Array.
+ // - VertexShaderExecutor.execute() returns either an array of Uint8Array
+ // - FragmentShaderExecutor.execute() returns either an array of Uint8Array or Uint32Array
+ outputs = new Uint32Array(shaderExecutorOutput.buffer);
+
+ // Verify
+ /** @type {number} */ var numValues = inputs.length;
+ /** @type {number} */ var maxPrints = 10;
+ /** @type {number} */ var numFailed = 0;
+
+ for (var valNdx = 0; valNdx < inputs.length; valNdx++) {
+ /** @type {number} */ var ref0 = deMath.clamp(Math.floor(deMath.clamp(inputs[valNdx][0], 0.0, 1.0) * 65535.0), 0, (1 << 16) - 1) & 0xFFFF;
+ /** @type {number} */ var ref1 = deMath.clamp(Math.floor(deMath.clamp(inputs[valNdx][1], 0.0, 1.0) * 65535.0), 0, (1 << 16) - 1) & 0xFFFF;
+ /** @type {number} */ var ref = (ref1 << 16) | ref0;
+ /** @type {number} */ var res = outputs[valNdx];
+ /** @type {number} */ var res0 = (res & 0xffff);
+ /** @type {number} */ var res1 = deMath.shiftRight(res, 16);
+ /** @type {number} */ var diff0 = Math.abs(ref0 - res0);
+ /** @type {number} */ var diff1 = Math.abs(ref1 - res1);
+
+ if (diff0 > maxDiff || diff1 > maxDiff) {
+ if (numFailed < maxPrints)
+ bufferedLogToConsole('ERROR: Mismatch in value ' + valNdx +
+ ', expected packUnorm2x16(' + inputs[valNdx] + ') = ' + ref /*tcu::toHex(ref)*/ +
+ ', got ' + res /*tcu::toHex(res)*/ +
+ '\n diffs = (' + diff0 + ', ' + diff1 + '), max diff = ' + maxDiff);
+ else if (numFailed === maxPrints)
+ bufferedLogToConsole('...');
+
+ numFailed += 1;
+ }
+ }
+
+ bufferedLogToConsole((numValues - numFailed) + ' / ' + numValues + ' values passed');
+
+ /** @type {boolean} */ var isOk = numFailed === 0;
+ if (!isOk)
+ testFailedOptions('Result comparison failed', false);
+ else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderPackingFunctionTests.ShaderPackingFunctionCase}
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderPackingFunctionTests.UnpackUnorm2x16Case = function(shaderType) {
+ /** @const {string} */ var name = 'unpackunorm2x16' +
+ es3fShaderPackingFunctionTests.getShaderTypePostfix(shaderType);
+ es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.call(this, name, 'unpackUnorm2x16', shaderType);
+
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(gluShaderUtil.DataType.UINT, gluShaderUtil.precision.PRECISION_HIGHP)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_VEC2, gluShaderUtil.precision.PRECISION_HIGHP)));
+ this.m_spec.source = 'out0 = unpackUnorm2x16(in0);';
+ };
+
+ es3fShaderPackingFunctionTests.UnpackUnorm2x16Case.prototype = Object.create(es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.prototype);
+ es3fShaderPackingFunctionTests.UnpackUnorm2x16Case.prototype.constructor = es3fShaderPackingFunctionTests.UnpackUnorm2x16Case;
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderPackingFunctionTests.UnpackUnorm2x16Case.prototype.iterate = function() {
+ /** @type {number} */ var maxDiff = 1; // Rounding error.
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0x776002);
+ /** @type {Array<number>} */ var inputs = [];
+ /** @type {goog.TypedArray} */ var shaderExecutorOutput;
+ /** @type {goog.TypedArray} */ var outputs; //vector<vec2>
+
+ inputs.push(0x00000000);
+ inputs.push(0x7fff8000);
+ inputs.push(0x80007fff);
+ inputs.push(0xffffffff);
+ inputs.push(0x0001fffe);
+
+ // Random values.
+ for (var ndx = 0; ndx < 95; ndx++)
+ inputs.push(rnd.getInt());
+
+ bufferedLogToConsole('Executing shader for ' + inputs.length + ' input values');
+
+ this.m_executor.useProgram();
+ shaderExecutorOutput = this.m_executor.execute(inputs.length, [inputs])[0];
+
+ // Convert outputs if we get them as Uint8Array.
+ // - VertexShaderExecutor.execute() returns either an array of Uint8Array
+ // - FragmentShaderExecutor.execute() returns either an array of Uint8Array or Uint32Array
+ outputs = new Float32Array(shaderExecutorOutput.buffer);
+
+ // Verify
+ /** @type {number} */ var numValues = inputs.length;
+ /** @type {number} */ var maxPrints = 10;
+ /** @type {number} */ var numFailed = 0;
+
+ for (var valNdx = 0; valNdx < inputs.length; valNdx++) {
+ /** @type {number} */ var in0 = Math.floor(inputs[valNdx] & 0xffff);
+ /** @type {number} */ var in1 = Math.floor(deMath.shiftRight(inputs[valNdx], 16));
+ /** @type {number} */ var ref0 = in0 / 65535.0;
+ /** @type {number} */ var ref1 = in1 / 65535.0;
+ /** @type {number} */ var res0 = outputs[2 * valNdx];
+ /** @type {number} */ var res1 = outputs[2 * valNdx + 1];
+
+ /** @type {number} */ var diff0 = es3fShaderPackingFunctionTests.getUlpDiff(ref0, res0);
+ /** @type {number} */ var diff1 = es3fShaderPackingFunctionTests.getUlpDiff(ref1, res1);
+
+ if (diff0 > maxDiff || diff1 > maxDiff) {
+ if (numFailed < maxPrints)
+ bufferedLogToConsole('ERROR: Mismatch in value ' + valNdx + ',\n' +
+ ' expected unpackUnorm2x16(' + inputs[valNdx].toString(16) + ') = ' +
+ 'vec2(' + ref0.toString(16) + ', ' + ref1.toString(16) + ')' +
+ ', got vec2(' + res0.toString(16) + ', ' + res1.toString(16) + ')' +
+ '\n ULP diffs = (' + diff0 + ', ' + diff1 + '), max diff = ' + maxDiff);
+ else if (numFailed === maxPrints)
+ bufferedLogToConsole('...');
+
+ numFailed += 1;
+ }
+ }
+
+ bufferedLogToConsole((numValues - numFailed) + ' / ' + numValues + ' values passed');
+
+ /** @type {boolean} */ var isOk = numFailed === 0;
+ if (!isOk)
+ testFailedOptions('Result comparison failed', false);
+ else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderPackingFunctionTests.ShaderPackingFunctionCase}
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderPackingFunctionTests.PackHalf2x16Case = function(shaderType) {
+ /** @const {string} */ var name = 'packhalf2x16' +
+ es3fShaderPackingFunctionTests.getShaderTypePostfix(shaderType);
+ es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.call(this, name, 'packHalf2x16', shaderType);
+
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_VEC2, gluShaderUtil.precision.PRECISION_HIGHP)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(gluShaderUtil.DataType.UINT, gluShaderUtil.precision.PRECISION_HIGHP)));
+ this.m_spec.source = 'out0 = packHalf2x16(in0);';
+ };
+
+ es3fShaderPackingFunctionTests.PackHalf2x16Case.prototype = Object.create(es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.prototype);
+ es3fShaderPackingFunctionTests.PackHalf2x16Case.prototype.constructor = es3fShaderPackingFunctionTests.PackHalf2x16Case;
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderPackingFunctionTests.PackHalf2x16Case.prototype.iterate = function() {
+ /** @type {number} */ var maxDiff = 0; // Values can be represented exactly in mediump.
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0x776002);
+ /** @type {Array<Array<number>>} */ var inputs = [];
+ /** @type {goog.TypedArray} */ var shaderExecutorOutput;
+ /** @type {goog.TypedArray} */ var outputs; // deUint32
+
+ // Special values to check.
+ inputs.push([0.0, 0.0]);
+ inputs.push([0.5, 1.0]);
+ inputs.push([1.0, 0.5]);
+ inputs.push([-0.5, 1.5]);
+ inputs.push([0.25, 0.75]);
+
+ // Random values.
+ /** @type {number} */ var minExp = -14;
+ /** @type {number} */ var maxExp = 15;
+
+ /** @type {Array<number>} */ var v = [];
+ for (var ndx = 0; ndx < 95; ndx++) {
+ for (var c = 0; c < 2; c++) {
+ /** @type {number} */ var s = rnd.getBool() ? 1 : -1;
+ /** @type {number} */ var exp = rnd.getInt(minExp, maxExp);
+ /** @type {number} */ var mantissa = rnd.getInt(0) & ((1 << 23) - 1);
+
+ v[c] = (new tcuFloat.deFloat()).construct(s, exp ? exp : 1 /* avoid denormals */, (1 << 23) | mantissa).getValue();
+ }
+ inputs.push(v);
+ }
+
+ // Convert input values to fp16 and back to make sure they can be represented exactly in mediump.
+ for (var inVal in inputs)
+ inputs[inVal] = [tcuFloat.newFloat16(inputs[inVal][0]).getValue(), tcuFloat.newFloat16(inputs[inVal][1]).getValue()];
+
+ bufferedLogToConsole('Executing shader for ' + inputs.length + ' input values');
+
+ this.m_executor.useProgram();
+ shaderExecutorOutput = this.m_executor.execute(inputs.length, [tcuMatrixUtil.flatten(inputs)])[0];
+
+ // Convert outputs if we get them as Uint8Array.
+ // - VertexShaderExecutor.execute() returns either an array of Uint8Array
+ // - FragmentShaderExecutor.execute() returns either an array of Uint8Array or Uint32Array
+ outputs = new Uint32Array(shaderExecutorOutput.buffer);
+
+ // Verify
+ /** @type {number} */ var numValues = inputs.length;
+ /** @type {number} */ var maxPrints = 10;
+ /** @type {number} */ var numFailed = 0;
+
+ for (var valNdx = 0; valNdx < inputs.length; valNdx++) {
+ /** @type {number} */ var ref0 = tcuFloat.newFloat16(inputs[valNdx][0]).bits();
+ /** @type {number} */ var ref1 = tcuFloat.newFloat16(inputs[valNdx][1]).bits();
+ /** @type {number} */ var ref = (ref1 << 16) | ref0;
+ /** @type {number} */ var res = outputs[valNdx];
+ /** @type {number} */ var res0 = (res & 0xffff);
+ /** @type {number} */ var res1 = deMath.shiftRight(res, 16);
+ /** @type {number} */ var diff0 = Math.abs(ref0 - res0);
+ /** @type {number} */ var diff1 = Math.abs(ref1 - res1);
+
+ if (diff0 > maxDiff || diff1 > maxDiff) {
+ if (numFailed < maxPrints)
+ bufferedLogToConsole('ERROR: Mismatch in value ' + valNdx +
+ ', expected packHalf2x16(' + inputs[valNdx] + ') = ' + ref /*tcu::toHex(ref)*/ +
+ ', got ' + res /*tcu::toHex(res)*/ +
+ '\n diffs = (' + diff0 + ', ' + diff1 + '), max diff = ' + maxDiff);
+ else if (numFailed == maxPrints)
+ bufferedLogToConsole('...');
+
+ numFailed += 1;
+ }
+ }
+
+ bufferedLogToConsole((numValues - numFailed) + ' / ' + numValues + ' values passed');
+
+ /** @type {boolean} */ var isOk = numFailed === 0;
+ if (!isOk)
+ testFailedOptions('Result comparison failed', false);
+ else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.STOP;
+
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fShaderPackingFunctionTests.ShaderPackingFunctionCase}
+ * @param {gluShaderProgram.shaderType} shaderType
+ */
+ es3fShaderPackingFunctionTests.UnpackHalf2x16Case = function(shaderType) {
+ /** @const {string} */ var name = 'unpackhalf2x16' +
+ es3fShaderPackingFunctionTests.getShaderTypePostfix(shaderType);
+ es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.call(this, name, 'unpackHalf2x16', shaderType);
+
+ this.m_spec.inputs.push(new glsShaderExecUtil.Symbol('in0', gluVarType.newTypeBasic(gluShaderUtil.DataType.UINT, gluShaderUtil.precision.PRECISION_HIGHP)));
+ this.m_spec.outputs.push(new glsShaderExecUtil.Symbol('out0', gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_VEC2, gluShaderUtil.precision.PRECISION_MEDIUMP)));
+ this.m_spec.source = 'out0 = unpackHalf2x16(in0);';
+ };
+
+ es3fShaderPackingFunctionTests.UnpackHalf2x16Case.prototype = Object.create(es3fShaderPackingFunctionTests.ShaderPackingFunctionCase.prototype);
+ es3fShaderPackingFunctionTests.UnpackHalf2x16Case.prototype.constructor = es3fShaderPackingFunctionTests.UnpackHalf2x16Case;
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderPackingFunctionTests.UnpackHalf2x16Case.prototype.iterate = function() {
+ /** @type {number} */ var maxDiff = 0; // All bits must be accurate.
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ 0x776002);
+ /** @type {Array<number>} */ var inputs = [];
+ /** @type {goog.TypedArray} */ var outputs; // vector<vec2<float>>
+ /** @type {goog.TypedArray} */ var shaderExecutorOutput;
+
+ // Special values.
+ inputs.push((tcuFloat.newFloat16(0.0).bits() << 16) | tcuFloat.newFloat16(1.0).bits());
+ inputs.push((tcuFloat.newFloat16(1.0).bits() << 16) | tcuFloat.newFloat16(0.0).bits());
+ inputs.push((tcuFloat.newFloat16(-1.0).bits() << 16) | tcuFloat.newFloat16(0.5).bits());
+ inputs.push((tcuFloat.newFloat16(0.5).bits() << 16) | tcuFloat.newFloat16(-0.5).bits());
+
+ // Construct random values.
+ /** @type {number} */ var minExp = -14;
+ /** @type {number} */ var maxExp = 15;
+ /** @type {number} */ var mantBits = 10;
+
+ /** @type {number} */ var inVal = 0;
+ for (var ndx = 0; ndx < 96; ndx++) {
+ for (var c = 0; c < 2; c++) {
+ /** @type {number} */ var s = rnd.getBool() ? 1 : -1;
+ /** @type {number} */ var exp = rnd.getInt(minExp, maxExp);
+ /** @type {number} */ var mantissa = rnd.getInt(0) & ((1 << mantBits) - 1);
+ /** @type {number} */ var value = tcuFloat.newFloat16(0).construct(s, exp ? exp : 1 /* avoid denorm */, (1 << 10) | mantissa).bits();
+
+ inVal |= value << (16 * c);
+ }
+ inputs.push(inVal);
+ }
+
+ bufferedLogToConsole('Executing shader for ' + inputs.length + ' input values');
+
+ this.m_executor.useProgram();
+ shaderExecutorOutput = this.m_executor.execute(inputs.length, [inputs])[0];
+
+ // Convert outputs if we get them as Uint8Array.
+ // - VertexShaderExecutor.execute() returns either an array of Uint8Array
+ // - FragmentShaderExecutor.execute() returns either an array of Uint8Array or Uint32Array
+ outputs = new Float32Array(shaderExecutorOutput.buffer);
+
+ // Verify
+ /** @type {number} */ var numValues = inputs.length
+ /** @type {number} */ var maxPrints = 10;
+ /** @type {number} */ var numFailed = 0;
+
+ for (var valNdx = 0; valNdx < inputs.length; valNdx++) {
+ /** @type {number} */ var in0 = (inputs[valNdx] & 0xffff);
+ /** @type {number} */ var in1 = deMath.shiftRight(inputs[valNdx], 16);
+ /** @type {number} */ var ref0 = tcuFloat.halfFloatToNumber(in0);
+ /** @type {number} */ var ref1 = tcuFloat.halfFloatToNumber(in1);
+ /** @type {number} */ var res0 = outputs[2 * valNdx];
+ /** @type {number} */ var res1 = outputs[2 * valNdx + 1];
+ /** @type {number} */ var refBits0 = tcuFloat.newFloat32(ref0).bits();
+ /** @type {number} */ var refBits1 = tcuFloat.newFloat32(ref1).bits();
+ /** @type {number} */ var resBits0 = tcuFloat.newFloat32(res0).bits();
+ /** @type {number} */ var resBits1 = tcuFloat.newFloat32(res1).bits();
+
+ /** @type {number} */ var diff0 = Math.abs(refBits0 - resBits0);
+ /** @type {number} */ var diff1 = Math.abs(refBits1 - resBits1);
+
+ if (isNaN(ref0) && isNaN(res0))
+ diff0 = 0;
+ if (isNaN(ref1) && isNaN(res1))
+ diff1 = 0;
+
+ if (diff0 > maxDiff || diff1 > maxDiff) {
+ if (numFailed < maxPrints)
+ bufferedLogToConsole('ERROR: Mismatch in value ' + valNdx + ',\n' +
+ ' expected unpackHalf2x16(' + inputs[valNdx] /*tcu::toHex(inputs[valNdx])*/ + ') = ' +
+ 'vec2(' + ref0 + ' / ' + refBits0 /*tcu::toHex(refBits0)*/ + ', ' + ref1 + ' / ' + refBits1 /*tcu::toHex(refBits1)*/ + ')' +
+ ', got vec2(' + res0 + ' / ' + resBits0 /*tcu::toHex(resBits0)*/ + ', ' + res1 + ' / ' + resBits1 /*tcu::toHex(resBits1)*/ + ')' +
+ '\n ULP diffs = (' + diff0 + ', ' + diff1 + '), max diff = ' + maxDiff);
+ else if (numFailed == maxPrints)
+ bufferedLogToConsole('...');
+
+ numFailed += 1;
+ }
+ }
+
+ bufferedLogToConsole((numValues - numFailed) + ' / ' + numValues + ' values passed');
+
+ /** @type {boolean} */ var isOk = numFailed === 0;
+ if (!isOk)
+ testFailedOptions('Result comparison failed', false);
+ else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderPackingFunctionTests.ShaderPackingFunctionTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'pack_unpack', 'Floating-point pack and unpack function tests');
+ };
+
+ es3fShaderPackingFunctionTests.ShaderPackingFunctionTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderPackingFunctionTests.ShaderPackingFunctionTests.prototype.constructor = es3fShaderPackingFunctionTests.ShaderPackingFunctionTests;
+
+ es3fShaderPackingFunctionTests.ShaderPackingFunctionTests.prototype.init = function() {
+ var testGroup = tcuTestCase.runner.testCases;
+ testGroup.addChild(new es3fShaderPackingFunctionTests.PackSnorm2x16Case(gluShaderProgram.shaderType.VERTEX, gluShaderUtil.precision.PRECISION_LOWP));
+ testGroup.addChild(new es3fShaderPackingFunctionTests.PackSnorm2x16Case(gluShaderProgram.shaderType.FRAGMENT, gluShaderUtil.precision.PRECISION_LOWP));
+ testGroup.addChild(new es3fShaderPackingFunctionTests.PackSnorm2x16Case(gluShaderProgram.shaderType.VERTEX, gluShaderUtil.precision.PRECISION_MEDIUMP));
+ testGroup.addChild(new es3fShaderPackingFunctionTests.PackSnorm2x16Case(gluShaderProgram.shaderType.FRAGMENT, gluShaderUtil.precision.PRECISION_MEDIUMP));
+ testGroup.addChild(new es3fShaderPackingFunctionTests.PackSnorm2x16Case(gluShaderProgram.shaderType.VERTEX, gluShaderUtil.precision.PRECISION_HIGHP));
+ testGroup.addChild(new es3fShaderPackingFunctionTests.PackSnorm2x16Case(gluShaderProgram.shaderType.FRAGMENT, gluShaderUtil.precision.PRECISION_HIGHP));
+
+ testGroup.addChild(new es3fShaderPackingFunctionTests.UnpackSnorm2x16Case(gluShaderProgram.shaderType.VERTEX));
+ testGroup.addChild(new es3fShaderPackingFunctionTests.UnpackSnorm2x16Case(gluShaderProgram.shaderType.FRAGMENT));
+
+ testGroup.addChild(new es3fShaderPackingFunctionTests.PackUnorm2x16Case(gluShaderProgram.shaderType.VERTEX, gluShaderUtil.precision.PRECISION_LOWP));
+ testGroup.addChild(new es3fShaderPackingFunctionTests.PackUnorm2x16Case(gluShaderProgram.shaderType.FRAGMENT, gluShaderUtil.precision.PRECISION_LOWP));
+ testGroup.addChild(new es3fShaderPackingFunctionTests.PackUnorm2x16Case(gluShaderProgram.shaderType.VERTEX, gluShaderUtil.precision.PRECISION_MEDIUMP));
+ testGroup.addChild(new es3fShaderPackingFunctionTests.PackUnorm2x16Case(gluShaderProgram.shaderType.FRAGMENT, gluShaderUtil.precision.PRECISION_MEDIUMP));
+ testGroup.addChild(new es3fShaderPackingFunctionTests.PackUnorm2x16Case(gluShaderProgram.shaderType.VERTEX, gluShaderUtil.precision.PRECISION_HIGHP));
+ testGroup.addChild(new es3fShaderPackingFunctionTests.PackUnorm2x16Case(gluShaderProgram.shaderType.FRAGMENT, gluShaderUtil.precision.PRECISION_HIGHP));
+
+ testGroup.addChild(new es3fShaderPackingFunctionTests.UnpackUnorm2x16Case(gluShaderProgram.shaderType.VERTEX));
+ testGroup.addChild(new es3fShaderPackingFunctionTests.UnpackUnorm2x16Case(gluShaderProgram.shaderType.FRAGMENT));
+
+ testGroup.addChild(new es3fShaderPackingFunctionTests.PackHalf2x16Case(gluShaderProgram.shaderType.VERTEX));
+ testGroup.addChild(new es3fShaderPackingFunctionTests.PackHalf2x16Case(gluShaderProgram.shaderType.FRAGMENT));
+
+ testGroup.addChild(new es3fShaderPackingFunctionTests.UnpackHalf2x16Case(gluShaderProgram.shaderType.VERTEX));
+ testGroup.addChild(new es3fShaderPackingFunctionTests.UnpackHalf2x16Case(gluShaderProgram.shaderType.FRAGMENT));
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fShaderPackingFunctionTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fShaderPackingFunctionTests.ShaderPackingFunctionTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fShaderPackingFunctionTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderPrecisionTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderPrecisionTests.js
new file mode 100644
index 0000000000..28a697397c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderPrecisionTests.js
@@ -0,0 +1,947 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fShaderPrecisionTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuFloat');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluDrawUtil');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluShaderUtil');
+
+goog.scope(function() {
+ var es3fShaderPrecisionTests = functional.gles3.es3fShaderPrecisionTests;
+ var deMath = framework.delibs.debase.deMath;
+ var deRandom = framework.delibs.debase.deRandom;
+ var deString = framework.delibs.debase.deString;
+ var tcuFloat = framework.common.tcuFloat;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var gluDrawUtil = framework.opengl.gluDrawUtil;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+
+ /** @const {number} */ es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH = 32;
+ /** @const {number} */ es3fShaderPrecisionTests.FRAMEBUFFER_HEIGHT = 32;
+
+ es3fShaderPrecisionTests.add = function(a, b) { return a + b; };
+ es3fShaderPrecisionTests.sub = function(a, b) { return a - b; };
+ es3fShaderPrecisionTests.mul = function(a, b) { return a * b; };
+ // a * b = (a1 * 2^16 + a0) * (b1 * 2^16 + b0) = a1 * b1 * 2^32 + (a0 * b1 + a1 * b0) * 2^16 + a0 * b0
+ // 32bit integer multiplication may overflow in JavaScript. Only return low 32bit of the result.
+ es3fShaderPrecisionTests.mul32 = function(a, b) {
+ var sign = Math.sign(a) * Math.sign(b);
+ a = Math.abs(a);
+ b = Math.abs(b);
+ var a1 = deMath.split16(a)[1];
+ var a0 = deMath.split16(a)[0];
+ var b1 = deMath.split16(b)[1];
+ var b0 = deMath.split16(b)[0];
+ return sign * ((a0 * b1 + a1 * b0) * 0x10000 + a0 * b0);
+ }
+ es3fShaderPrecisionTests.div = function(a, b) { if (b !== 0) return a / b; else throw new Error('division by zero.')};
+
+ /**
+ * @param {gluShaderUtil.precision} precision
+ * @param {string} evalOp
+ * @param {boolean} isVertexCase
+ * @return {gluShaderProgram.ShaderProgram}
+ */
+ es3fShaderPrecisionTests.createFloatPrecisionEvalProgram = function(precision, evalOp, isVertexCase) {
+ /** @type {gluShaderUtil.DataType} */ var type = gluShaderUtil.DataType.FLOAT;
+ /** @type {gluShaderUtil.DataType} */ var outType = gluShaderUtil.DataType.UINT;
+ /** @type {string} */ var typeName = gluShaderUtil.getDataTypeName(type);
+ /** @type {string} */ var outTypeName = gluShaderUtil.getDataTypeName(outType);
+ /** @type {string} */ var precName = gluShaderUtil.getPrecisionName(precision);
+ /** @type {string} */ var vtx = '';
+ /** @type {string} */ var frag = '';
+ /** @type {string} */ var op = '';
+
+ vtx += '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in ' + precName + ' ' + typeName + ' a_in0;\n' +
+ 'in ' + precName + ' ' + typeName + ' a_in1;\n';
+ frag += '#version 300 es\n' +
+ 'layout(location = 0) out highp ' + outTypeName + ' o_out;\n';
+
+ if (isVertexCase) {
+ vtx += 'flat out ' + precName + ' ' + typeName + ' v_out;\n';
+ frag += 'flat in ' + precName + ' ' + typeName + ' v_out;\n';
+ } else {
+ vtx += 'flat out ' + precName + ' ' + typeName + ' v_in0;\n' +
+ 'flat out ' + precName + ' ' + typeName + ' v_in1;\n';
+ frag += 'flat in ' + precName + ' ' + typeName + ' v_in0;\n' +
+ 'flat in ' + precName + ' ' + typeName + ' v_in1;\n';
+ }
+
+ vtx += '\nvoid main (void)\n{\n' +
+ ' gl_Position = a_position;\n';
+ frag += '\nvoid main (void)\n{\n';
+
+ op += '\t' + precName + ' ' + typeName + ' in0 = ' + (isVertexCase ? 'a_' : 'v_') + 'in0;\n' +
+ '\t' + precName + ' ' + typeName + ' in1 = ' + (isVertexCase ? 'a_' : 'v_') + 'in1;\n';
+
+ if (!isVertexCase)
+ op += '\t' + precName + ' ' + typeName + ' res;\n';
+
+ op += '\t' + (isVertexCase ? 'v_out' : 'res') + ' = ' + evalOp + ';\n';
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ if (isVertexCase) {
+ frag += ' o_out = floatBitsToUint(v_out);\n';
+ } else {
+ vtx += ' v_in0 = a_in0;\n' +
+ ' v_in1 = a_in1;\n';
+ frag += ' o_out = floatBitsToUint(res);\n';
+ }
+
+ vtx += '}\n';
+ frag += '}\n';
+
+ return new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vtx, frag));
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} type
+ * @param {gluShaderUtil.precision} precision
+ * @param {string} evalOp
+ * @param {boolean} isVertexCase
+ * @return {gluShaderProgram.ShaderProgram}
+ */
+ es3fShaderPrecisionTests.createIntUintPrecisionEvalProgram = function(type, precision, evalOp, isVertexCase) {
+ /** @type {string} */ var typeName = gluShaderUtil.getDataTypeName(type);
+ /** @type {string} */ var precName = gluShaderUtil.getPrecisionName(precision);
+ /** @type {string} */ var vtx = '';
+ /** @type {string} */ var frag = '';
+ /** @type {string} */ var op = '';
+
+ vtx += '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in ' + precName + ' ' + typeName + ' a_in0;\n' +
+ 'in ' + precName + ' ' + typeName + ' a_in1;\n';
+ frag += '#version 300 es\n' +
+ 'layout(location = 0) out ' + precName + ' ' + typeName + ' o_out;\n';
+
+ if (isVertexCase) {
+ vtx += 'flat out ' + precName + ' ' + typeName + ' v_out;\n';
+ frag += 'flat in ' + precName + ' ' + typeName + ' v_out;\n';
+ } else {
+ vtx += 'flat out ' + precName + ' ' + typeName + ' v_in0;\n' +
+ 'flat out ' + precName + ' ' + typeName + ' v_in1;\n';
+ frag += 'flat in ' + precName + ' ' + typeName + ' v_in0;\n' +
+ 'flat in ' + precName + ' ' + typeName + ' v_in1;\n';
+ }
+
+ vtx += '\nvoid main (void)\n{\n'+
+ ' gl_Position = a_position;\n';
+ frag += '\nvoid main (void)\n{\n';
+
+ op += '\t' + precName + ' ' + typeName + ' in0 = ' + (isVertexCase ? 'a_' : 'v_') + 'in0;\n' +
+ '\t' + precName + ' ' + typeName + ' in1 = ' + (isVertexCase ? 'a_' : 'v_') + 'in1;\n';
+
+ op += '\t' + (isVertexCase ? 'v_' : 'o_') + 'out = ' + evalOp + ';\n';
+
+ vtx += isVertexCase ? op : '';
+ frag += isVertexCase ? '' : op;
+ op = '';
+
+ if (isVertexCase) {
+ frag += ' o_out = v_out;\n';
+ } else {
+ vtx += ' v_in0 = a_in0;\n' +
+ ' v_in1 = a_in1;\n';
+ }
+
+ vtx += '}\n';
+ frag += '}\n';
+
+ return new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vtx, frag));
+ };
+
+ /** @typedef {function(number, number)} */ es3fShaderPrecisionTests.EvalFunc;
+
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * @param {string} op
+ * @param {es3fShaderPrecisionTests.EvalFunc} evalFunc
+ * @param {gluShaderUtil.precision} precision
+ * @param {Array<number>} rangeA
+ * @param {Array<number>} rangeB
+ * @param {boolean} isVertexCase
+ */
+ es3fShaderPrecisionTests.ShaderFloatPrecisionCase = function(name, desc, op, evalFunc, precision, rangeA, rangeB, isVertexCase) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ // Case parameters.
+ /** @type {string} */ this.m_op = op;
+ /** @type {es3fShaderPrecisionTests.EvalFunc} */ this.m_evalFunc = evalFunc;
+ /** @type {gluShaderUtil.precision} */ this.m_precision = precision;
+ /** @type {Array<number>} */ this.m_rangeA = rangeA;
+ /** @type {Array<number>} */ this.m_rangeB = rangeB;
+ /** @type {boolean} */ this.m_isVertexCase = isVertexCase;
+
+ /** @type {number} */ this.m_numTestsPerIter = 32;
+ /** @type {number} */ this.m_numIters = 4;
+ /** @type {deRandom.Random} */ this.m_rnd = new deRandom.Random(deString.deStringHash(this.name));
+
+ // Iteration state.
+ /** @type {?gluShaderProgram.ShaderProgram} */ this.m_program = null;
+ /** @type {?WebGLFramebuffer} */ this.m_framebuffer = null;
+ /** @type {?WebGLRenderbuffer} */ this.m_renderbuffer = null;
+ /** @type {number} */ this.m_iterNdx = 0;
+ /** @type {Array<boolean>} */ this.m_iterPass = [];
+ };
+
+ es3fShaderPrecisionTests.ShaderFloatPrecisionCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderPrecisionTests.ShaderFloatPrecisionCase.prototype.constructor = es3fShaderPrecisionTests.ShaderFloatPrecisionCase;
+
+ es3fShaderPrecisionTests.ShaderFloatPrecisionCase.prototype.init = function() {
+ assertMsgOptions(!this.m_program && !this.m_framebuffer && !this.m_renderbuffer, 'Program/Framebuffer/Renderbuffer should be null at this point.', false, true);
+
+ // Create program.
+ this.m_program = es3fShaderPrecisionTests.createFloatPrecisionEvalProgram(this.m_precision, this.m_op, this.m_isVertexCase);
+
+ if (!this.m_program.isOk())
+ assertMsgOptions(false, 'Compile failed', false, true);
+
+ // Create framebuffer.
+ this.m_framebuffer = gl.createFramebuffer();
+ this.m_renderbuffer = gl.createRenderbuffer();
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, this.m_renderbuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.R32UI, es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH, es3fShaderPrecisionTests.FRAMEBUFFER_HEIGHT);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.m_framebuffer);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this.m_renderbuffer);
+
+ assertMsgOptions(gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE, 'Framebuffer is incomplete', false, true);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ this.m_iterNdx = 0;
+ };
+
+ es3fShaderPrecisionTests.ShaderFloatPrecisionCase.prototype.deinit = function() {
+ if(this.m_framebuffer)
+ gl.deleteFramebuffer(this.m_framebuffer);
+ if(this.m_renderbuffer)
+ gl.deleteRenderbuffer(this.m_renderbuffer);
+ this.m_program = null;
+ this.m_framebuffer = null;
+ this.m_renderbuffer = null;
+ };
+
+ /**
+ * @param {number} in0
+ * @param {number} in1
+ * @param {number} reference
+ * @param {number} result
+ */
+
+ es3fShaderPrecisionTests.ShaderFloatPrecisionCase.prototype.compare = function(in0, in1, reference, result) {
+ // Comparison is done using 64-bit reference value to accurately evaluate rounding mode error.
+ // If 32-bit reference value is used, 2 bits of rounding error must be allowed.
+
+ // For mediump and lowp types the comparison currently allows 3 bits of rounding error:
+ // two bits from conversions and one from actual operation.
+
+ // \todo [2013-09-30 pyry] Make this more strict: determine if rounding can actually happen.
+
+ /** @type {number} */ var mantissaBits = this.m_precision == gluShaderUtil.precision.PRECISION_HIGHP ? 23 : 10;
+ /** @type {number} */ var numPrecBits = 52 - mantissaBits;
+
+ /** @type {number} */ var in0Exp = tcuFloat.newFloat32(in0).exponent();
+ /** @type {number} */ var in1Exp = tcuFloat.newFloat32(in1).exponent();
+ /** @type {number} */ var resExp = tcuFloat.newFloat32(result).exponent();
+ /** @type {number} */ var numLostBits = Math.max(in0Exp - resExp, in1Exp - resExp, 0); // Lost due to mantissa shift.
+
+ /** @type {number} */ var roundingUlpError = this.m_precision == gluShaderUtil.precision.PRECISION_HIGHP ? 1 : 3;
+ /** @type {number} */ var maskBits = numLostBits + numPrecBits;
+
+ bufferedLogToConsole("Assuming " + mantissaBits + " mantissa bits, " + numLostBits + " bits lost in operation, and " + roundingUlpError + " ULP rounding error.")
+
+ // These numbers should never be larger than 52 bits. An assertion in getBitRange verifies this.
+ /** @type {number} */ var accurateRefBits = tcuFloat.newFloat64(reference).getBitRange(maskBits, 64);
+ /** @type {number} */ var accurateResBits = tcuFloat.newFloat64(result).getBitRange(maskBits, 64);
+ /** @type {number} */ var ulpDiff = Math.abs(accurateRefBits - accurateResBits);
+
+ if (ulpDiff > roundingUlpError) {
+ bufferedLogToConsole("ERROR: comparison failed! ULP diff (ignoring lost/undefined bits) = " + ulpDiff );
+ return false;
+ }
+ else
+ return true;
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderPrecisionTests.ShaderFloatPrecisionCase.prototype.iterate = function() {
+ var testPassed = true;
+ var testPassedMsg = 'Pass';
+
+ // Constant data.
+ /** @type {Array<number>} */ var position =[
+ -1.0, -1.0, 0.0, 1.0,
+ -1.0, 1.0, 0.0, 1.0,
+ 1.0, -1.0, 0.0, 1.0,
+ 1.0, 1.0, 0.0, 1.0
+ ];
+
+ /** @type {Array<number>} */ var indices = [0, 1, 2, 2, 1, 3];
+ /** @type {number} */ var numVertices = 4;
+ /** @type {Array<number>} */ var in0Arr = [0.0, 0.0, 0.0, 0.0];
+ /** @type {Array<number>} */ var in1Arr = [0.0, 0.0, 0.0, 0.0];
+
+ /** @type {Array<gluDrawUtil.VertexArrayBinding>} */ var vertexArrays = [];
+
+ // Image read from GL.
+ /** @type {goog.TypedArray} */ var pixels_uint = new Uint32Array(es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH * es3fShaderPrecisionTests.FRAMEBUFFER_HEIGHT * 4);
+
+ // \todo [2012-05-03 pyry] Could be cached.
+ /** @type {WebGLProgram} */ var prog = this.m_program.getProgram();
+
+ gl.useProgram(prog);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.m_framebuffer);
+
+ vertexArrays[0] = gluDrawUtil.newFloatVertexArrayBinding("a_position", 4, numVertices, 0, position);
+
+
+ // Compute values and reference.
+ for (var testNdx = 0; testNdx < this.m_numTestsPerIter; testNdx++) {
+ /** @type {number} */ var in0 = this.m_rnd.getFloat(this.m_rangeA[0], this.m_rangeA[1]);
+ /** @type {number} */ var in1 = this.m_rnd.getFloat(this.m_rangeB[0], this.m_rangeB[1]);
+
+ // These random numbers are used in the reference computation. But
+ // highp is only 32 bits, so these float64s must be rounded to
+ // float32 first for correctness. This is needed for highp_mul_* on
+ // one Linux/NVIDIA machine.
+ in0 = tcuFloat.newFloat32(in0).getValue();
+ in1 = tcuFloat.newFloat32(in1).getValue();
+
+ /** @type {number} */ var refD = this.m_evalFunc(in0, in1);
+
+ bufferedLogToConsole("iter " + this.m_iterNdx + ", test " + testNdx + ": "+
+ "in0 = " + in0 + " / " + tcuFloat.newFloat32(in0).bits() +
+ ", in1 = " + in1 + " / " + tcuFloat.newFloat32(in1).bits() +
+ " reference = " + refD + " / " + tcuFloat.newFloat32(refD).bits());
+
+ in0Arr = [in0, in0, in0, in0];
+ in1Arr = [in1, in1, in1, in1];
+ vertexArrays[1] = gluDrawUtil.newFloatVertexArrayBinding("a_in0", 1, numVertices, 0, in0Arr);
+ vertexArrays[2] = gluDrawUtil.newFloatVertexArrayBinding("a_in1", 1, numVertices, 0, in1Arr);
+
+ gluDrawUtil.draw(gl, prog, vertexArrays, gluDrawUtil.triangles(indices));
+
+ gl.readPixels(0, 0, es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH,
+ es3fShaderPrecisionTests.FRAMEBUFFER_HEIGHT, gl.RGBA_INTEGER, gl.UNSIGNED_INT, pixels_uint);
+
+ var pixels = new Float32Array(pixels_uint.buffer);
+ bufferedLogToConsole(" result = " + pixels[0] + " / " + tcuFloat.newFloat32(pixels[0]).bits());
+
+ // Verify results
+ /** @type {boolean} */ var firstPixelOk = this.compare(in0, in1, refD, pixels[0]);
+
+ if (firstPixelOk) {
+ // Check that rest of pixels match to first one.
+ /** @type {number} */ var firstPixelBits = tcuFloat.newFloat32(pixels[0]).bits();
+ /** @type {boolean} */ var allPixelsOk = true;
+
+ for (var y = 0; y < es3fShaderPrecisionTests.FRAMEBUFFER_HEIGHT; y++) {
+ for (var x = 0; x < es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH; x++) {
+ /** @type {number} */ var pixelBits = tcuFloat.newFloat32(pixels[(y * es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH + x) * 4]).bits();
+
+ if (pixelBits != firstPixelBits) {
+ bufferedLogToConsole("ERROR: Inconsistent results, got " + pixelBits + " at (" + x + ", " + y + ")")
+ allPixelsOk = false;
+ }
+ }
+
+ if (!allPixelsOk)
+ break;
+ }
+
+ if (!allPixelsOk){
+ bufferedLogToConsole("iter " + this.m_iterNdx + ", test " + testNdx + "Inconsistent values in framebuffer");
+ testPassed = false;
+ testPassedMsg = 'Inconsistent values in framebuffer';
+ }
+ }
+ else{
+ bufferedLogToConsole("iter " + this.m_iterNdx + ", test " + testNdx + "Result comparison failed");
+ testPassed = false;
+ testPassedMsg = 'Result comparison failed'
+ }
+ }
+
+ // [dag] Aggregating test results to make the test less verbose.
+ this.m_iterPass[this.m_iterNdx] = testPassed;
+
+ // [dag] Show test results after the last iteration is done.
+ if (this.m_iterPass.length === this.m_numIters) {
+ if (!deMath.boolAll(this.m_iterPass))
+ testFailedOptions(testPassedMsg, false);
+ else
+ testPassedOptions(testPassedMsg, true);
+ }
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ this.m_iterNdx += 1;
+ return (this.m_iterNdx < this.m_numIters) ? tcuTestCase.IterateResult.CONTINUE : tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * @param {string} op
+ * @param {es3fShaderPrecisionTests.EvalFunc} evalFunc
+ * @param {gluShaderUtil.precision} precision
+ * @param {number} bits
+ * @param {Array<number>} rangeA
+ * @param {Array<number>} rangeB
+ * @param {boolean} isVertexCase
+ */
+ es3fShaderPrecisionTests.ShaderIntPrecisionCase = function(name, desc, op, evalFunc, precision, bits, rangeA, rangeB, isVertexCase) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ // Case parameters.
+ /** @type {string} */ this.m_op = op;
+ /** @type {es3fShaderPrecisionTests.EvalFunc} */ this.m_evalFunc = evalFunc;
+ /** @type {gluShaderUtil.precision} */ this.m_precision = precision;
+ /** @type {number} */ this.m_bits = bits;
+ /** @type {Array<number>} */ this.m_rangeA = rangeA;
+ /** @type {Array<number>} */ this.m_rangeB = rangeB;
+ /** @type {boolean} */ this.m_isVertexCase = isVertexCase;
+
+ /** @type {number} */ this.m_numTestsPerIter = 32;
+ /** @type {number} */ this.m_numIters = 4;
+ /** @type {deRandom.Random} */ this.m_rnd = new deRandom.Random(deString.deStringHash(this.name));
+
+ // Iteration state.
+ /** @type {gluShaderProgram.ShaderProgram} */ this.m_program = null;
+ /** @type {WebGLFramebuffer} */ this.m_framebuffer = null;
+ /** @type {WebGLRenderbuffer} */ this.m_renderbuffer = null;
+ /** @type {number} */ this.m_iterNdx = 0;
+ };
+
+ es3fShaderPrecisionTests.ShaderIntPrecisionCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderPrecisionTests.ShaderIntPrecisionCase.prototype.constructor = es3fShaderPrecisionTests.ShaderIntPrecisionCase;
+
+ es3fShaderPrecisionTests.ShaderIntPrecisionCase.prototype.init = function() {
+ assertMsgOptions(!this.m_program && !this.m_framebuffer && !this.m_renderbuffer, 'Program/Framebuffer/Renderbuffer should be null at this point.', false, true);
+ // Create program.
+ this.m_program = es3fShaderPrecisionTests.createIntUintPrecisionEvalProgram(gluShaderUtil.DataType.INT, this.m_precision, this.m_op, this.m_isVertexCase);
+
+ if (!this.m_program.isOk())
+ assertMsgOptions(false, 'Compile failed', false, true);
+
+ // Create framebuffer.
+ this.m_framebuffer = gl.createFramebuffer();
+ this.m_renderbuffer = gl.createRenderbuffer();
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, this.m_renderbuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.R32I, es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH, es3fShaderPrecisionTests.FRAMEBUFFER_HEIGHT);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.m_framebuffer);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this.m_renderbuffer);
+
+ assertMsgOptions(gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE, 'Framebuffer is incomplete', false, true);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ this.m_iterNdx = 0;
+
+ bufferedLogToConsole("Number of accurate bits assumed = " + this.m_bits);
+ };
+
+ es3fShaderPrecisionTests.ShaderIntPrecisionCase.prototype.deinit = function() {
+ if(this.m_framebuffer)
+ gl.deleteFramebuffer(this.m_framebuffer);
+ if(this.m_renderbuffer)
+ gl.deleteRenderbuffer(this.m_renderbuffer);
+ this.m_program = null;
+ this.m_framebuffer = null;
+ this.m_renderbuffer = null;
+ };
+
+ /**
+ * @param {number} value
+ * @param {number} bits
+ * @return {number}
+ */
+
+ es3fShaderPrecisionTests.extendTo32Bit = function(value, bits) {
+ return (value & ((1 << (bits - 1)) - 1)) | ((value & (1 << (bits - 1))) << (32 - bits)) >> (32 - bits);
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderPrecisionTests.ShaderIntPrecisionCase.prototype.iterate = function() {
+ var testPassed = true;
+ var testPassedMsg = 'Pass';
+ // Constant data.
+ /** @type {Array<number>} */ var position = [
+ -1.0, -1.0, 0.0, 1.0,
+ -1.0, 1.0, 0.0, 1.0,
+ 1.0, -1.0, 0.0, 1.0,
+ 1.0, 1.0, 0.0, 1.0
+ ]
+ /** @type {Array<number>} */ var indices = [0, 1, 2, 2, 1, 3];
+
+ /** @type {number} */ var numVertices = 4;
+ /** @type {Array<number>} */ var in0Arr = [0, 0, 0, 0];
+ /** @type {Array<number>} */ var in1Arr = [0, 0, 0, 0];
+
+ /** @type {number} */ var mask = this.m_bits === 32 ? 0xffffffff : ((1 << this.m_bits) - 1);
+ /** @type {goog.TypedArray} */ var pixels = new Int32Array(es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH * es3fShaderPrecisionTests.FRAMEBUFFER_HEIGHT * 4);
+ /** @type {Array<gluDrawUtil.VertexArrayBinding>} */ var vertexArrays = [];
+
+ /** @type {WebGLProgram} */ var prog = this.m_program.getProgram();
+
+ // \todo [2012-05-03 pyry] A bit hacky. getInt() should work fine with ranges like this.
+ /** @type {boolean} */ var isMaxRangeA = this.m_rangeA[0] === 0x80000000 && this.m_rangeA[1] === 0x7fffffff;
+ /** @type {boolean} */ var isMaxRangeB = this.m_rangeB[0] === 0x80000000 && this.m_rangeB[1] === 0x7fffffff;
+
+ gl.useProgram(prog);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.m_framebuffer);
+
+ vertexArrays[0] = gluDrawUtil.newFloatVertexArrayBinding("a_position", 4, numVertices, 0, position);
+
+ // Compute values and reference.
+ for (var testNdx = 0; testNdx < this.m_numTestsPerIter; testNdx++) {
+ /** @type {number} */ var in0 = this.m_rnd.getInt(this.m_rangeA[0], this.m_rangeA[1]); //es3fShaderPrecisionTests.extendTo32Bit(((isMaxRangeA ? Math.abs(this.m_rnd.getInt()) : this.m_rnd.getInt(this.m_rangeA[0], this.m_rangeA[1])) & mask), this.m_bits);
+ /** @type {number} */ var in1 = this.m_rnd.getInt(this.m_rangeB[0], this.m_rangeB[1]); //es3fShaderPrecisionTests.extendTo32Bit(((isMaxRangeB ? Math.abs(this.m_rnd.getInt()) : this.m_rnd.getInt(this.m_rangeB[0], this.m_rangeB[1])) & mask), this.m_bits);
+ /** @type {number} */ var refMasked = this.m_evalFunc(in0, in1) & mask;
+ /** @type {number} */ var refOut = es3fShaderPrecisionTests.extendTo32Bit(refMasked, this.m_bits);
+
+ bufferedLogToConsole("iter " + this.m_iterNdx + ", test " + testNdx + ": " +
+ "in0 = " + in0 + ", in1 = " + in1 + ", ref out = " + refOut + " / " + refMasked);
+
+ in0Arr = [in0, in0, in0, in0];
+ in1Arr = [in1, in1, in1, in1];
+
+ vertexArrays[1] = gluDrawUtil.newInt32VertexArrayBinding("a_in0", 1, numVertices, 0, in0Arr);
+ vertexArrays[2] = gluDrawUtil.newInt32VertexArrayBinding("a_in1", 1, numVertices, 0, in1Arr);
+
+ gluDrawUtil.draw(gl, prog, vertexArrays, gluDrawUtil.triangles(indices));
+
+ gl.readPixels(0, 0, es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH,
+ es3fShaderPrecisionTests.FRAMEBUFFER_HEIGHT,
+ gl.RGBA_INTEGER, gl.INT, pixels);
+
+ // Compare pixels.
+ for (var y = 0; y < es3fShaderPrecisionTests.FRAMEBUFFER_HEIGHT; y++) {
+ for (var x = 0; x < es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH; x++) {
+ /** @type {number} */ var cmpOut = pixels[(y * es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH + x) * 4];
+ /** @type {number} */ var cmpMasked = cmpOut & mask;
+
+ if (cmpMasked != refMasked) {
+ bufferedLogToConsole("Comparison failed (at " + x + ", " + y + "): " +
+ + "got " + cmpOut + " / " + cmpOut);
+ testPassed = false;
+ testPassedMsg = 'Comparison failed';
+ }
+ }
+ }
+ }
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ this.m_iterNdx += 1;
+ if (!testPassed) {
+ testFailedOptions(testPassedMsg, false);
+ return tcuTestCase.IterateResult.STOP;
+ } else if (testPassed && this.m_iterNdx < this.m_numIters) {
+ return tcuTestCase.IterateResult.CONTINUE;
+ } else {
+ testPassedOptions(testPassedMsg, true);
+ return tcuTestCase.IterateResult.STOP;
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * @param {string} op
+ * @param {es3fShaderPrecisionTests.EvalFunc} evalFunc
+ * @param {gluShaderUtil.precision} precision
+ * @param {number} bits
+ * @param {Array<number>} rangeA
+ * @param {Array<number>} rangeB
+ * @param {boolean} isVertexCase
+ */
+ es3fShaderPrecisionTests.ShaderUintPrecisionCase = function(name, desc, op, evalFunc, precision, bits, rangeA, rangeB, isVertexCase) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ // Case parameters.
+ /** @type {string} */ this.m_op = op;
+ /** @type {es3fShaderPrecisionTests.EvalFunc} */ this.m_evalFunc = evalFunc;
+ /** @type {gluShaderUtil.precision} */ this.m_precision = precision;
+ /** @type {number} */ this.m_bits = bits;
+ /** @type {Array<number>} */ this.m_rangeA = rangeA;
+ /** @type {Array<number>} */ this.m_rangeB = rangeB;
+ /** @type {boolean} */ this.m_isVertexCase = isVertexCase;
+
+ /** @type {number} */ this.m_numTestsPerIter = 32;
+ /** @type {number} */ this.m_numIters = 4;
+ /** @type {deRandom.Random} */ this.m_rnd = new deRandom.Random(deString.deStringHash(this.name));
+
+ // Iteration state.
+ /** @type {gluShaderProgram.ShaderProgram} */ this.m_program = null;
+ /** @type {WebGLFramebuffer} */ this.m_framebuffer = null;
+ /** @type {WebGLRenderbuffer} */ this.m_renderbuffer = null;
+ /** @type {number} */ this.m_iterNdx = 0;
+ };
+
+ es3fShaderPrecisionTests.ShaderUintPrecisionCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderPrecisionTests.ShaderUintPrecisionCase.prototype.constructor = es3fShaderPrecisionTests.ShaderUintPrecisionCase;
+
+ es3fShaderPrecisionTests.ShaderUintPrecisionCase.prototype.init = function() {
+ assertMsgOptions(!this.m_program && !this.m_framebuffer && !this.m_renderbuffer, 'Program/Framebuffer/Renderbuffer should be null at this point.', false, true);
+ // Create program.
+ this.m_program = es3fShaderPrecisionTests.createIntUintPrecisionEvalProgram(gluShaderUtil.DataType.UINT, this.m_precision, this.m_op, this.m_isVertexCase);
+
+ if (!this.m_program.isOk())
+ assertMsgOptions(false, 'Compile failed', false, true);
+
+ // Create framebuffer.
+ this.m_framebuffer = gl.createFramebuffer();
+ this.m_renderbuffer = gl.createRenderbuffer();
+
+ gl.bindRenderbuffer(gl.RENDERBUFFER, this.m_renderbuffer);
+ gl.renderbufferStorage(gl.RENDERBUFFER, gl.R32UI, es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH, es3fShaderPrecisionTests.FRAMEBUFFER_HEIGHT);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.m_framebuffer);
+ gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, this.m_renderbuffer);
+
+ assertMsgOptions(gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE, 'Framebuffer is incomplete', false, true);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ this.m_iterNdx = 0;
+
+ bufferedLogToConsole("Number of accurate bits assumed = " + this.m_bits);
+ };
+
+ es3fShaderPrecisionTests.ShaderUintPrecisionCase.prototype.deinit = function() {
+ if(this.m_framebuffer)
+ gl.deleteFramebuffer(this.m_framebuffer);
+ if(this.m_renderbuffer)
+ gl.deleteRenderbuffer(this.m_renderbuffer);
+ this.m_program = null;
+ this.m_framebuffer = null;
+ this.m_renderbuffer = null;
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderPrecisionTests.ShaderUintPrecisionCase.prototype.iterate = function() {
+ var testPassed = true;
+ var testPassedMsg = 'Pass';
+
+ // Constant data.
+ /** @type {Array<number>} */ var position = [
+ -1.0, -1.0, 0.0, 1.0,
+ -1.0, 1.0, 0.0, 1.0,
+ 1.0, -1.0, 0.0, 1.0,
+ 1.0, 1.0, 0.0, 1.0
+ ];
+ /** @type {Array<number>} */ var indices = [0, 1, 2, 2, 1, 3];
+
+ /** @type {number} */ var numVertices = 4;
+ /** @type {Array<number>} */ var in0Arr = [0, 0, 0, 0];
+ /** @type {Array<number>} */ var in1Arr = [0, 0, 0, 0];
+
+ /** @type {number} */ var mask = this.m_bits === 32 ? 0xffffffff : ((1 << this.m_bits) - 1);
+ /** @type {goog.TypedArray} */ var pixels = new Uint32Array(es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH * es3fShaderPrecisionTests.FRAMEBUFFER_HEIGHT * 4);
+ /** @type {Array<gluDrawUtil.VertexArrayBinding>} */ var vertexArrays = [];
+
+ /** @type {WebGLProgram} */ var prog = this.m_program.getProgram();
+
+ // \todo [2012-05-03 pyry] A bit hacky.
+ /** @type {boolean} */ var isMaxRangeA = this.m_rangeA[0] === 0 && this.m_rangeA[1] === 0xffffffff;
+ /** @type {boolean} */ var isMaxRangeB = this.m_rangeB[0] === 0 && this.m_rangeB[1] === 0xffffffff;
+
+ gl.useProgram(prog);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.m_framebuffer);
+
+ vertexArrays[0] = gluDrawUtil.newFloatVertexArrayBinding("a_position", 4, numVertices, 0, position);
+
+ // Compute values and reference.
+ for (var testNdx = 0; testNdx < this.m_numTestsPerIter; testNdx++) {
+ /** @type {number} */ var in0 = (isMaxRangeA ? Math.abs(this.m_rnd.getInt()) : (this.m_rangeA[0] + Math.abs(this.m_rnd.getInt()) % (this.m_rangeA[1] - this.m_rangeA[0] + 1))) & mask;
+ /** @type {number} */ var in1 = (isMaxRangeB ? Math.abs(this.m_rnd.getInt()) : (this.m_rangeB[0] + Math.abs(this.m_rnd.getInt()) % (this.m_rangeB[1] - this.m_rangeB[0] + 1))) & mask;
+ /** @type {number} */ var refOut = this.m_evalFunc(in0, in1) & mask;
+
+ bufferedLogToConsole("iter " + this.m_iterNdx + ", test " + testNdx + ": " +
+ + "in0 = " + in0 + ", in1 = " + in1 + ", ref out = " + refOut)
+
+ in0Arr = [in0, in0, in0, in0];
+ in1Arr = [in1, in1, in1, in1];
+ vertexArrays[1] = gluDrawUtil.newUint32VertexArrayBinding("a_in0", 1, numVertices, 0, in0Arr);
+ vertexArrays[2] = gluDrawUtil.newUint32VertexArrayBinding("a_in1", 1, numVertices, 0, in1Arr);
+
+ gluDrawUtil.draw(gl, prog, vertexArrays, gluDrawUtil.triangles(indices));
+
+ gl.readPixels(0, 0, es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH,
+ es3fShaderPrecisionTests.FRAMEBUFFER_HEIGHT, gl.RGBA_INTEGER, gl.UNSIGNED_INT, pixels);
+
+ // Compare pixels.
+ for (var y = 0; y < es3fShaderPrecisionTests.FRAMEBUFFER_HEIGHT; y++) {
+ for (var x = 0; x < es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH; x++) {
+ /** @type {number} */ var cmpOut = pixels[(y*es3fShaderPrecisionTests.FRAMEBUFFER_WIDTH + x) * 4];
+ /** @type {number} */ var cmpMasked = cmpOut & mask;
+
+ if (cmpMasked != refOut) {
+ bufferedLogToConsole("Comparison failed (at " + x + ", " + y + "): " + "got " + cmpOut)
+ testPassed = false;
+ testPassedMsg = 'Comparison failed';
+ }
+ }
+ }
+ }
+
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+
+ this.m_iterNdx += 1;
+ if (!testPassed) {
+ testFailedOptions(testPassedMsg, false);
+ return tcuTestCase.IterateResult.STOP;
+ } else if (testPassed && this.m_iterNdx < this.m_numIters) {
+ return tcuTestCase.IterateResult.CONTINUE;
+ } else {
+ testPassedOptions(testPassedMsg, true);
+ return tcuTestCase.IterateResult.STOP;
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderPrecisionTests.ShaderPrecisionTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'precision', 'Shader precision requirements validation tests');
+ };
+
+ es3fShaderPrecisionTests.ShaderPrecisionTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderPrecisionTests.ShaderPrecisionTests.prototype.constructor = es3fShaderPrecisionTests.ShaderPrecisionTests;
+
+ es3fShaderPrecisionTests.ShaderPrecisionTests.prototype.init = function() {
+ var testGroup = tcuTestCase.runner.testCases;
+ // Exp = Emax-2, Mantissa = 0
+ // /** @type {number} */ var minF32 = tcuFloat.newFloat32((1 << 31) | (0xfd << 23) | 0x0).getValue();
+ // /** @type {number} */ var maxF32 = tcuFloat.newFloat32((0 << 31) | (0xfd << 23) | 0x0).getValue();
+ // [dag] Workaround for float32 numbers
+ /** @type {number} */ var minF32 = new Float32Array(new Uint32Array([1<<31|0xfd<<23|0x0]).buffer)[0];
+ /** @type {number} */ var maxF32 = new Float32Array(new Uint32Array([0<<31|0xfd<<23|0x0]).buffer)[0];
+
+ // /** @type {number} */ var minF16 = tcuFloat.newFloat16(((1 << 15) | (0x1d << 10) | 0x0)).getValue();
+ // /** @type {number} */ var maxF16 = tcuFloat.newFloat16(((0 << 15) | (0x1d << 10) | 0x0)).getValue();
+ /** @type {number} */ var minF16 = -16384; //-1 << 14; // 1 << 15 | 0x1d | 0x0 == 0b1111010000000000; -1 * (2**(29-15)) * 1
+ /** @type {number} */ var maxF16 = 16384; //1 << 14; // 0 << 15 | 0x1d | 0x0 == 0b0111010000000000; +1 * (2**(29-15)) * 1
+
+ /** @type {Array<number>} */ var fullRange32F = [minF32, maxF32];
+ /** @type {Array<number>} */ var fullRange16F = [minF16, maxF16];
+ /** @type {Array<number>} */ var fullRange32I = [-2147483648, 2147483647]; // [0x80000000|0, 0x7fffffff|0]; // |0 to force the number as a 32-bit integer
+ /** @type {Array<number>} */ var fullRange16I = [minF16, maxF16 - 1]; //[-(1 << 15), (1 << 15) - 1]; // Added the negative sign to index 0
+ /** @type {Array<number>} */ var fullRange8I = [-128, 127]; //[-(1 << 7), (1 << 7) - 1]; // Added the negative sign to index 0
+ /** @type {Array<number>} */ var fullRange32U = [0, 0xffffffff];
+ /** @type {Array<number>} */ var fullRange16U = [0, 0xffff];
+ /** @type {Array<number>} */ var fullRange8U = [0, 0xff];
+
+ // \note Right now it is not programmatically verified that the results shouldn't end up being inf/nan but
+ // actual values used are ok.
+
+ /**
+ * @constructor
+ * @struct
+ * @param {string} name
+ * @param {string} op
+ * @param {es3fShaderPrecisionTests.EvalFunc} evalFunc
+ * @param {gluShaderUtil.precision} precision
+ * @param {Array<number>} rangeA
+ * @param {Array<number>} rangeB
+ */
+ var FloatCase = function(name, op, evalFunc, precision, rangeA, rangeB) {
+ /** @type {string} */ this.name = name;
+ /** @type {string} */ this.op = op;
+ /** @type {es3fShaderPrecisionTests.EvalFunc} */ this.evalFunc = evalFunc;
+ /** @type {gluShaderUtil.precision} */ this.precision = precision;
+ /** @type {Array<number>} */ this.rangeA = rangeA;
+ /** @type {Array<number>} */ this.rangeB = rangeB;
+ };
+
+ /** @type {Array<FloatCase>} */ var floatCases = [
+ new FloatCase('highp_add', 'in0 + in1', es3fShaderPrecisionTests.add, gluShaderUtil.precision.PRECISION_HIGHP, fullRange32F, fullRange32F),
+ new FloatCase('highp_sub', 'in0 - in1', es3fShaderPrecisionTests.sub, gluShaderUtil.precision.PRECISION_HIGHP, fullRange32F, fullRange32F),
+ new FloatCase('highp_mul', 'in0 * in1', es3fShaderPrecisionTests.mul, gluShaderUtil.precision.PRECISION_HIGHP, [-1e5, 1e5], [-1e5, 1e5]),
+ new FloatCase('highp_div', 'in0 / in1', es3fShaderPrecisionTests.div, gluShaderUtil.precision.PRECISION_HIGHP, [-1e5, 1e5], [-1e5, 1e5]),
+ new FloatCase('mediump_add', 'in0 + in1', es3fShaderPrecisionTests.add, gluShaderUtil.precision.PRECISION_MEDIUMP, fullRange16F, fullRange16F),
+ new FloatCase('mediump_sub', 'in0 - in1', es3fShaderPrecisionTests.sub, gluShaderUtil.precision.PRECISION_MEDIUMP, fullRange16F, fullRange16F),
+ new FloatCase('mediump_mul', 'in0 * in1', es3fShaderPrecisionTests.mul, gluShaderUtil.precision.PRECISION_MEDIUMP, [-1e2, 1e2], [-1e2, 1e2]),
+ new FloatCase('mediump_div', 'in0 / in1', es3fShaderPrecisionTests.div, gluShaderUtil.precision.PRECISION_MEDIUMP, [-1e2, 1e2], [-1e2, 1e2])
+ ];
+
+ /**
+ * @constructor
+ * @struct
+ * @param {string} name
+ * @param {string} op
+ * @param {es3fShaderPrecisionTests.EvalFunc} evalFunc
+ * @param {gluShaderUtil.precision} precision
+ * @param {number} bits
+ * @param {Array<number>} rangeA
+ * @param {Array<number>} rangeB
+ */
+ var IntCase = function(name, op, evalFunc, precision, bits, rangeA, rangeB) {
+ /** @type {string} */ this.name = name;
+ /** @type {string} */ this.op = op;
+ /** @type {es3fShaderPrecisionTests.EvalFunc} */ this.evalFunc = evalFunc;
+ /** @type {gluShaderUtil.precision} */ this.precision = precision;
+ /** @type {number} */ this.bits = bits;
+ /** @type {Array<number>} */ this.rangeA = rangeA;
+ /** @type {Array<number>} */ this.rangeB = rangeB;
+ };
+
+ /** @type {Array<IntCase>} */ var intCases = [
+ new IntCase('highp_add', 'in0 + in1', es3fShaderPrecisionTests.add, gluShaderUtil.precision.PRECISION_HIGHP, 32, fullRange32I, fullRange32I),
+ new IntCase('highp_sub', 'in0 - in1', es3fShaderPrecisionTests.sub, gluShaderUtil.precision.PRECISION_HIGHP, 32, fullRange32I, fullRange32I),
+ new IntCase('highp_mul', 'in0 * in1', es3fShaderPrecisionTests.mul32, gluShaderUtil.precision.PRECISION_HIGHP, 32, fullRange32I, fullRange32I),
+ new IntCase('highp_div', 'in0 / in1', es3fShaderPrecisionTests.div, gluShaderUtil.precision.PRECISION_HIGHP, 32, fullRange32I, [-10000, -1]),
+ new IntCase('mediump_add', 'in0 + in1', es3fShaderPrecisionTests.add, gluShaderUtil.precision.PRECISION_MEDIUMP, 16, fullRange16I, fullRange16I),
+ new IntCase('mediump_sub', 'in0 - in1', es3fShaderPrecisionTests.sub, gluShaderUtil.precision.PRECISION_MEDIUMP, 16, fullRange16I, fullRange16I),
+ new IntCase('mediump_mul', 'in0 * in1', es3fShaderPrecisionTests.mul, gluShaderUtil.precision.PRECISION_MEDIUMP, 16, fullRange16I, fullRange16I),
+ new IntCase('mediump_div', 'in0 / in1', es3fShaderPrecisionTests.div, gluShaderUtil.precision.PRECISION_MEDIUMP, 16, fullRange16I, [1, 1000]),
+ new IntCase('lowp_add', 'in0 + in1', es3fShaderPrecisionTests.add, gluShaderUtil.precision.PRECISION_LOWP, 8, fullRange8I, fullRange8I),
+ new IntCase('lowp_sub', 'in0 - in1', es3fShaderPrecisionTests.sub, gluShaderUtil.precision.PRECISION_LOWP, 8, fullRange8I, fullRange8I),
+ new IntCase('lowp_mul', 'in0 * in1', es3fShaderPrecisionTests.mul, gluShaderUtil.precision.PRECISION_LOWP, 8, fullRange8I, fullRange8I),
+ new IntCase('lowp_div', 'in0 / in1', es3fShaderPrecisionTests.div, gluShaderUtil.precision.PRECISION_LOWP, 8, fullRange8I, [-50, -1])
+ ];
+
+ /**
+ * @constructor
+ * @struct
+ * @param {string} name
+ * @param {string} op
+ * @param {es3fShaderPrecisionTests.EvalFunc} evalFunc
+ * @param {gluShaderUtil.precision} precision
+ * @param {number} bits
+ * @param {Array<number>} rangeA
+ * @param {Array<number>} rangeB
+ */
+ var UintCase = function(name, op, evalFunc, precision, bits, rangeA, rangeB) {
+ /** @type {string} */ this.name = name;
+ /** @type {string} */ this.op = op;
+ /** @type {es3fShaderPrecisionTests.EvalFunc} */ this.evalFunc = evalFunc;
+ /** @type {gluShaderUtil.precision} */ this.precision = precision;
+ /** @type {number} */ this.bits = bits;
+ /** @type {Array<number>} */ this.rangeA = rangeA;
+ /** @type {Array<number>} */ this.rangeB = rangeB;
+ };
+
+ /** @type {Array<UintCase>} */ var uintCases = [
+ new UintCase('highp_add', 'in0 + in1', es3fShaderPrecisionTests.add, gluShaderUtil.precision.PRECISION_HIGHP, 32, fullRange32U, fullRange32U),
+ new UintCase('highp_sub', 'in0 - in1', es3fShaderPrecisionTests.sub, gluShaderUtil.precision.PRECISION_HIGHP, 32, fullRange32U, fullRange32U),
+ new UintCase('highp_mul', 'in0 * in1', es3fShaderPrecisionTests.mul32, gluShaderUtil.precision.PRECISION_HIGHP, 32, fullRange32U, fullRange32U),
+ new UintCase('highp_div', 'in0 / in1', es3fShaderPrecisionTests.div, gluShaderUtil.precision.PRECISION_HIGHP, 32, fullRange32U, [1, 10000]),
+ new UintCase('mediump_add', 'in0 + in1', es3fShaderPrecisionTests.add, gluShaderUtil.precision.PRECISION_MEDIUMP, 16, fullRange16U, fullRange16U),
+ new UintCase('mediump_sub', 'in0 - in1', es3fShaderPrecisionTests.sub, gluShaderUtil.precision.PRECISION_MEDIUMP, 16, fullRange16U, fullRange16U),
+ new UintCase('mediump_mul', 'in0 * in1', es3fShaderPrecisionTests.mul, gluShaderUtil.precision.PRECISION_MEDIUMP, 16, fullRange16U, fullRange16U),
+ new UintCase('mediump_div', 'in0 / in1', es3fShaderPrecisionTests.div, gluShaderUtil.precision.PRECISION_MEDIUMP, 16, fullRange16U, [1, 1000]),
+ new UintCase('lowp_add', 'in0 + in1', es3fShaderPrecisionTests.add, gluShaderUtil.precision.PRECISION_LOWP, 8, fullRange8U, fullRange8U),
+ new UintCase('lowp_sub', 'in0 - in1', es3fShaderPrecisionTests.sub, gluShaderUtil.precision.PRECISION_LOWP, 8, fullRange8U, fullRange8U),
+ new UintCase('lowp_mul', 'in0 * in1', es3fShaderPrecisionTests.mul, gluShaderUtil.precision.PRECISION_LOWP, 8, fullRange8U, fullRange8U),
+ new UintCase('lowp_div', 'in0 / in1', es3fShaderPrecisionTests.div, gluShaderUtil.precision.PRECISION_LOWP, 8, fullRange8U, [1, 50])
+ ];
+
+ /** @type {tcuTestCase.DeqpTest} */ var floatGroup = tcuTestCase.newTest('float', 'Floating-point precision tests');
+ testGroup.addChild(floatGroup);
+ for (var ndx = 0; ndx < floatCases.length; ndx++) {
+ floatGroup.addChild(new es3fShaderPrecisionTests.ShaderFloatPrecisionCase(
+ floatCases[ndx].name + '_vertex', '', floatCases[ndx].op, floatCases[ndx].evalFunc,
+ floatCases[ndx].precision, floatCases[ndx].rangeA, floatCases[ndx].rangeB, true));
+ floatGroup.addChild(new es3fShaderPrecisionTests.ShaderFloatPrecisionCase(
+ floatCases[ndx].name + '_fragment', '', floatCases[ndx].op, floatCases[ndx].evalFunc,
+ floatCases[ndx].precision, floatCases[ndx].rangeA, floatCases[ndx].rangeB, false));
+ }
+
+ /** @type {tcuTestCase.DeqpTest} */ var intGroup = tcuTestCase.newTest('int', 'Integer precision tests');
+ testGroup.addChild(intGroup);
+ for (var ndx = 0; ndx < intCases.length; ndx++) {
+ intGroup.addChild(new es3fShaderPrecisionTests.ShaderIntPrecisionCase(
+ intCases[ndx].name + '_vertex', '', intCases[ndx].op, intCases[ndx].evalFunc,
+ intCases[ndx].precision, intCases[ndx].bits, intCases[ndx].rangeA, intCases[ndx].rangeB, true));
+ intGroup.addChild(new es3fShaderPrecisionTests.ShaderIntPrecisionCase(
+ intCases[ndx].name + '_fragment', '', intCases[ndx].op, intCases[ndx].evalFunc,
+ intCases[ndx].precision, intCases[ndx].bits, intCases[ndx].rangeA, intCases[ndx].rangeB, false));
+ }
+
+ /** @type {tcuTestCase.DeqpTest} */ var uintGroup = tcuTestCase.newTest('uint', 'Unsigned integer precision tests');
+ testGroup.addChild(uintGroup);
+ for (var ndx = 0; ndx < uintCases.length; ndx++) {
+ uintGroup.addChild(new es3fShaderPrecisionTests.ShaderUintPrecisionCase(
+ uintCases[ndx].name + '_vertex', '', uintCases[ndx].op, uintCases[ndx].evalFunc,
+ uintCases[ndx].precision, uintCases[ndx].bits, uintCases[ndx].rangeA, uintCases[ndx].rangeB, true));
+ uintGroup.addChild(new es3fShaderPrecisionTests.ShaderUintPrecisionCase(
+ uintCases[ndx].name + '_fragment', '', uintCases[ndx].op, uintCases[ndx].evalFunc,
+ uintCases[ndx].precision, uintCases[ndx].bits, uintCases[ndx].rangeA, uintCases[ndx].rangeB, false));
+ }
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fShaderPrecisionTests.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fShaderPrecisionTests.ShaderPrecisionTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fShaderPrecisionTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderStateQueryTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderStateQueryTests.js
new file mode 100644
index 0000000000..1a2859f249
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderStateQueryTests.js
@@ -0,0 +1,2205 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fShaderStateQueryTests');
+goog.require('framework.common.tcuMatrix');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('functional.gles3.es3fApiCase');
+goog.require('modules.shared.glsStateQuery');
+
+goog.scope(function() {
+var es3fShaderStateQueryTests = functional.gles3.es3fShaderStateQueryTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var glsStateQuery = modules.shared.glsStateQuery;
+var es3fApiCase = functional.gles3.es3fApiCase;
+var deRandom = framework.delibs.debase.deRandom;
+var tcuMatrix = framework.common.tcuMatrix;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+var commonTestVertSource = '#version 300 es\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(0.0);\n' +
+ '}\n';
+var commonTestFragSource = '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+var brokenShader = '#version 300 es\n' +
+ 'broken, this should not compile!\n' +
+ '\n';
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.ShaderTypeCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.ShaderTypeCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.ShaderTypeCase.prototype.test = function() {
+ var shaderTypes = [gl.VERTEX_SHADER, gl.FRAGMENT_SHADER];
+ for (var ndx = 0; ndx < shaderTypes.length; ++ndx) {
+ var shader = gl.createShader(shaderTypes[ndx]);
+ var result = glsStateQuery.verifyShader(shader, gl.SHADER_TYPE, shaderTypes[ndx]);
+ this.check(result, 'Incorrect shader type');
+ gl.deleteShader(shader);
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.ShaderCompileStatusCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.ShaderCompileStatusCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.ShaderCompileStatusCase.prototype.test = function() {
+ var result;
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ result = glsStateQuery.verifyShader(shaderVert, gl.COMPILE_STATUS, false);
+ this.check(result, 'Vertex shader compilation status should be false');
+ result = glsStateQuery.verifyShader(shaderFrag, gl.COMPILE_STATUS, false);
+ this.check(result, 'Fragment shader compilation status should be false');
+
+ gl.shaderSource(shaderVert, commonTestVertSource);
+ gl.shaderSource(shaderFrag, commonTestFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ result = glsStateQuery.verifyShader(shaderVert, gl.COMPILE_STATUS, true);
+ this.check(result, 'Vertex shader compilation status should be true');
+ result = glsStateQuery.verifyShader(shaderFrag, gl.COMPILE_STATUS, true);
+ this.check(result, 'Fragment shader compilation status should be true');
+
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.ShaderInfoLogCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.ShaderInfoLogCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.ShaderInfoLogCase.prototype.test = function() {
+ var shader = gl.createShader(gl.VERTEX_SHADER);
+ var log = gl.getShaderInfoLog(shader);
+ this.check(log === '');
+
+ gl.shaderSource(shader, brokenShader);
+ gl.compileShader(shader);
+
+ log = gl.getShaderInfoLog(shader);
+ this.check(log === null || typeof log === 'string');
+
+ gl.deleteShader(shader);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.ShaderSourceCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.ShaderSourceCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.ShaderSourceCase.prototype.test = function() {
+ var shader = gl.createShader(gl.VERTEX_SHADER);
+ this.check(gl.getShaderSource(shader) === '');
+
+ gl.shaderSource(shader, brokenShader);
+ this.check(gl.getShaderSource(shader) === brokenShader);
+
+ gl.deleteShader(shader);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.DeleteStatusCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.DeleteStatusCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.DeleteStatusCase.prototype.test = function() {
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, commonTestVertSource);
+ gl.shaderSource(shaderFrag, commonTestFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ this.check(glsStateQuery.verifyShader(shaderVert, gl.COMPILE_STATUS, true));
+ this.check(glsStateQuery.verifyShader(shaderFrag, gl.COMPILE_STATUS, true));
+
+ var shaderProg = gl.createProgram();
+ gl.attachShader(shaderProg, shaderVert);
+ gl.attachShader(shaderProg, shaderFrag);
+ gl.linkProgram(shaderProg);
+
+ this.check(glsStateQuery.verifyProgram(shaderProg, gl.LINK_STATUS, true));
+
+ this.check(glsStateQuery.verifyShader(shaderVert, gl.DELETE_STATUS, false));
+ this.check(glsStateQuery.verifyShader(shaderFrag, gl.DELETE_STATUS, false));
+ this.check(glsStateQuery.verifyProgram(shaderProg, gl.DELETE_STATUS, false));
+
+ gl.useProgram(shaderProg);
+
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(shaderProg);
+
+ this.check(glsStateQuery.verifyShader(shaderVert, gl.DELETE_STATUS, true));
+ this.check(glsStateQuery.verifyShader(shaderFrag, gl.DELETE_STATUS, true));
+ this.check(glsStateQuery.verifyProgram(shaderProg, gl.DELETE_STATUS, true));
+
+ gl.useProgram(null);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.CurrentVertexAttribInitialCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.CurrentVertexAttribInitialCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.CurrentVertexAttribInitialCase.prototype.test = function() {
+ var attribute_count = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ var initial = new Float32Array([0, 0, 0, 1]);
+ // initial
+
+ for (var index = 0; index < attribute_count; ++index) {
+ var attrib = gl.getVertexAttrib(index, gl.CURRENT_VERTEX_ATTRIB);
+ this.check(glsStateQuery.compare(attrib, initial), 'Initial attrib value should be [0, 0, 0, 1]');
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.CurrentVertexAttribFloatCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.CurrentVertexAttribFloatCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.CurrentVertexAttribFloatCase.prototype.test = function() {
+ var rnd = new deRandom.Random(0xabcdef);
+
+ var attribute_count = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+
+ // test write float/read float
+
+ for (var index = 0; index < attribute_count; ++index) {
+ var x = rnd.getFloat(-64000, 64000);
+ var y = rnd.getFloat(-64000, 64000);
+ var z = rnd.getFloat(-64000, 64000);
+ var w = rnd.getFloat(-64000, 64000);
+
+ gl.vertexAttrib4f(index, x, y, z, w);
+ this.check(glsStateQuery.verifyCurrentVertexAttrib(index, new Float32Array([x, y, z, w])));
+ }
+ for (var index = 0; index < attribute_count; ++index) {
+ var x = rnd.getFloat(-64000, 64000);
+ var y = rnd.getFloat(-64000, 64000);
+ var z = rnd.getFloat(-64000, 64000);
+ var w = 1.0;
+
+ gl.vertexAttrib3f(index, x, y, z);
+ this.check(glsStateQuery.verifyCurrentVertexAttrib(index, new Float32Array([x, y, z, w])));
+ }
+ for (var index = 0; index < attribute_count; ++index) {
+ var x = rnd.getFloat(-64000, 64000);
+ var y = rnd.getFloat(-64000, 64000);
+ var z = 0.0;
+ var w = 1.0;
+
+ gl.vertexAttrib2f(index, x, y);
+ this.check(glsStateQuery.verifyCurrentVertexAttrib(index, new Float32Array([x, y, z, w])));
+ }
+ for (var index = 0; index < attribute_count; ++index) {
+ var x = rnd.getFloat(-64000, 64000);
+ var y = 0.0;
+ var z = 0.0;
+ var w = 1.0;
+
+ gl.vertexAttrib1f(index, x);
+ this.check(glsStateQuery.verifyCurrentVertexAttrib(index, new Float32Array([x, y, z, w])));
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.CurrentVertexAttribIntCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.CurrentVertexAttribIntCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.CurrentVertexAttribIntCase.prototype.test = function() {
+ var rnd = new deRandom.Random(0xabcdef);
+
+ var attribute_count = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+
+ // test write float/read float
+
+ for (var index = 0; index < attribute_count; ++index) {
+ var x = rnd.getInt(-64000, 64000);
+ var y = rnd.getInt(-64000, 64000);
+ var z = rnd.getInt(-64000, 64000);
+ var w = rnd.getInt(-64000, 64000);
+
+ gl.vertexAttribI4i(index, x, y, z, w);
+ this.check(glsStateQuery.verifyCurrentVertexAttrib(index, new Int32Array([x, y, z, w])));
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.CurrentVertexAttribUintCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.CurrentVertexAttribUintCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.CurrentVertexAttribUintCase.prototype.test = function() {
+ var rnd = new deRandom.Random(0xabcdef);
+
+ var attribute_count = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+
+ // test write float/read float
+
+ for (var index = 0; index < attribute_count; ++index) {
+ var x = rnd.getInt(0, 64000);
+ var y = rnd.getInt(0, 64000);
+ var z = rnd.getInt(0, 64000);
+ var w = rnd.getInt(0, 64000);
+
+ gl.vertexAttribI4ui(index, x, y, z, w);
+ this.check(glsStateQuery.verifyCurrentVertexAttrib(index, new Uint32Array([x, y, z, w])));
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.ProgramInfoLogCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.ProgramInfoLogCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.ProgramInfoLogCase.prototype.test = function() {
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, brokenShader);
+ gl.compileShader(shaderVert);
+ gl.shaderSource(shaderFrag, brokenShader);
+ gl.compileShader(shaderFrag);
+
+ var program = gl.createProgram();
+ gl.attachShader(program, shaderVert);
+ gl.attachShader(program, shaderFrag);
+ gl.linkProgram(program);
+
+ var log = gl.getProgramInfoLog(program);
+ this.check(log === null || typeof log === 'string');
+
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(program);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.ProgramValidateStatusCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.ProgramValidateStatusCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.ProgramValidateStatusCase.prototype.test = function() {
+ // test validate ok
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, commonTestVertSource);
+ gl.shaderSource(shaderFrag, commonTestFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ var program = gl.createProgram();
+ gl.attachShader(program, shaderVert);
+ gl.attachShader(program, shaderFrag);
+ gl.linkProgram(program);
+
+ this.check(glsStateQuery.verifyShader(shaderVert, gl.COMPILE_STATUS, true));
+ this.check(glsStateQuery.verifyShader(shaderFrag, gl.COMPILE_STATUS, true));
+ this.check(glsStateQuery.verifyProgram(program, gl.LINK_STATUS, true));
+
+ gl.validateProgram(program);
+ this.check(glsStateQuery.verifyProgram(program, gl.VALIDATE_STATUS, true));
+
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(program);
+
+ // test with broken shader
+ shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, commonTestVertSource);
+ gl.shaderSource(shaderFrag, brokenShader);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ program = gl.createProgram();
+ gl.attachShader(program, shaderVert);
+ gl.attachShader(program, shaderFrag);
+ gl.linkProgram(program);
+
+ this.check(glsStateQuery.verifyShader(shaderVert, gl.COMPILE_STATUS, true));
+ this.check(glsStateQuery.verifyShader(shaderFrag, gl.COMPILE_STATUS, false));
+ this.check(glsStateQuery.verifyProgram(program, gl.LINK_STATUS, false));
+
+ gl.validateProgram(program);
+ this.check(glsStateQuery.verifyProgram(program, gl.VALIDATE_STATUS, false));
+
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(program);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.ProgramAttachedShadersCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.ProgramAttachedShadersCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.ProgramAttachedShadersCase.prototype.test = function() {
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, commonTestVertSource);
+ gl.shaderSource(shaderFrag, commonTestFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ // check ATTACHED_SHADERS
+
+ var program = gl.createProgram();
+ this.check(glsStateQuery.verifyProgram(program, gl.ATTACHED_SHADERS, 0));
+
+ gl.attachShader(program, shaderVert);
+ this.check(glsStateQuery.verifyProgram(program, gl.ATTACHED_SHADERS, 1));
+
+ gl.attachShader(program, shaderFrag);
+ this.check(glsStateQuery.verifyProgram(program, gl.ATTACHED_SHADERS, 2));
+
+ // check GetAttachedShaders
+ var shaders = gl.getAttachedShaders(program);
+ this.check(glsStateQuery.compare(shaders, [shaderVert, shaderFrag]));
+
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(program);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.ProgramActiveUniformNameCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.ProgramActiveUniformNameCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.ProgramActiveUniformNameCase.prototype.test = function() {
+ var testVertSource =
+ '#version 300 es\n' +
+ 'uniform highp float uniformNameWithLength23;\n' +
+ 'uniform highp vec2 uniformVec2;\n' +
+ 'uniform highp mat4 uniformMat4;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(0.0) + vec4(uniformNameWithLength23) + vec4(uniformVec2.x) + vec4(uniformMat4[2][3]);\n' +
+ '}\n';
+ var testFragSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, testVertSource);
+ gl.shaderSource(shaderFrag, testFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ var program = gl.createProgram();
+ gl.attachShader(program, shaderVert);
+ gl.attachShader(program, shaderFrag);
+ gl.linkProgram(program);
+
+ this.check(glsStateQuery.verifyProgram(program, gl.ACTIVE_UNIFORMS, 3));
+
+ var uniformNames = [
+ 'uniformNameWithLength23',
+ 'uniformVec2',
+ 'uniformMat4'
+ ];
+
+ var indices = gl.getUniformIndices(program, uniformNames);
+
+ // check names
+ for (var ndx = 0; ndx < uniformNames.length; ++ndx) {
+ var index = indices[ndx];
+ var uniform = gl.getActiveUniform(program, index);
+
+ this.check(glsStateQuery.compare(uniform.name, uniformNames[ndx]));
+ }
+
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(program);
+
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.ProgramUniformCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.ProgramUniformCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.ProgramUniformCase.prototype.test = function() {
+ var uniformTypes = [
+ ['float', '', 'highp', '', 'uniformValue', gl.FLOAT, 1, false],
+ ['float[2]', '', 'highp', '', 'uniformValue[1]', gl.FLOAT, 2, false],
+ ['vec2', '', 'highp', '', 'uniformValue.x', gl.FLOAT_VEC2, 1, false],
+ ['vec3', '', 'highp', '', 'uniformValue.x', gl.FLOAT_VEC3, 1, false],
+ ['vec4', '', 'highp', '', 'uniformValue.x', gl.FLOAT_VEC4, 1, false],
+ ['int', '', 'highp', '', 'float(uniformValue)', gl.INT, 1, false],
+ ['ivec2', '', 'highp', '', 'float(uniformValue.x)', gl.INT_VEC2, 1, false],
+ ['ivec3', '', 'highp', '', 'float(uniformValue.x)', gl.INT_VEC3, 1, false],
+ ['ivec4', '', 'highp', '', 'float(uniformValue.x)', gl.INT_VEC4, 1, false],
+ ['uint', '', 'highp', '', 'float(uniformValue)', gl.UNSIGNED_INT, 1, false],
+ ['uvec2', '', 'highp', '', 'float(uniformValue.x)', gl.UNSIGNED_INT_VEC2, 1, false],
+ ['uvec3', '', 'highp', '', 'float(uniformValue.x)', gl.UNSIGNED_INT_VEC3, 1, false],
+ ['uvec4', '', 'highp', '', 'float(uniformValue.x)', gl.UNSIGNED_INT_VEC4, 1, false],
+ ['bool', '', '', '', 'float(uniformValue)', gl.BOOL, 1, false],
+ ['bvec2', '', '', '', 'float(uniformValue.x)', gl.BOOL_VEC2, 1, false],
+ ['bvec3', '', '', '', 'float(uniformValue.x)', gl.BOOL_VEC3, 1, false],
+ ['bvec4', '', '', '', 'float(uniformValue.x)', gl.BOOL_VEC4, 1, false],
+ ['mat2', '', 'highp', '', 'float(uniformValue[0][0])', gl.FLOAT_MAT2, 1, false],
+ ['mat3', '', 'highp', '', 'float(uniformValue[0][0])', gl.FLOAT_MAT3, 1, false],
+ ['mat4', '', 'highp', '', 'float(uniformValue[0][0])', gl.FLOAT_MAT4, 1, false],
+ ['mat2x3', '', 'highp', '', 'float(uniformValue[0][0])', gl.FLOAT_MAT2x3, 1, false],
+ ['mat2x4', '', 'highp', '', 'float(uniformValue[0][0])', gl.FLOAT_MAT2x4, 1, false],
+ ['mat3x2', '', 'highp', '', 'float(uniformValue[0][0])', gl.FLOAT_MAT3x2, 1, false],
+ ['mat3x4', '', 'highp', '', 'float(uniformValue[0][0])', gl.FLOAT_MAT3x4, 1, false],
+ ['mat4x2', '', 'highp', '', 'float(uniformValue[0][0])', gl.FLOAT_MAT4x2, 1, false],
+ ['mat4x3', '', 'highp', '', 'float(uniformValue[0][0])', gl.FLOAT_MAT4x3, 1, false],
+ ['sampler2D', '', 'highp', '', 'float(textureSize(uniformValue,0).r)', gl.SAMPLER_2D, 1, false],
+ ['sampler3D', '', 'highp', '', 'float(textureSize(uniformValue,0).r)', gl.SAMPLER_3D, 1, false],
+ ['samplerCube', '', 'highp', '', 'float(textureSize(uniformValue,0).r)', gl.SAMPLER_CUBE, 1, false],
+ ['sampler2DShadow', '', 'highp', '', 'float(textureSize(uniformValue,0).r)', gl.SAMPLER_2D_SHADOW, 1, false],
+ ['sampler2DArray', '', 'highp', '', 'float(textureSize(uniformValue,0).r)', gl.SAMPLER_2D_ARRAY, 1, false],
+ ['sampler2DArrayShadow', '', 'highp', '', 'float(textureSize(uniformValue,0).r)', gl.SAMPLER_2D_ARRAY_SHADOW, 1, false],
+ ['samplerCubeShadow', '', 'highp', '', 'float(textureSize(uniformValue,0).r)', gl.SAMPLER_CUBE_SHADOW, 1, false],
+ ['isampler2D', '', 'highp', '', 'float(textureSize(uniformValue,0).r)', gl.INT_SAMPLER_2D, 1, false],
+ ['isampler3D', '', 'highp', '', 'float(textureSize(uniformValue,0).r)', gl.INT_SAMPLER_3D, 1, false],
+ ['isamplerCube', '', 'highp', '', 'float(textureSize(uniformValue,0).r)', gl.INT_SAMPLER_CUBE, 1, false],
+ ['isampler2DArray', '', 'highp', '', 'float(textureSize(uniformValue,0).r)', gl.INT_SAMPLER_2D_ARRAY, 1, false],
+ ['usampler2D', '', 'highp', '', 'float(textureSize(uniformValue,0).r)', gl.UNSIGNED_INT_SAMPLER_2D, 1, false],
+ ['usampler3D', '', 'highp', '', 'float(textureSize(uniformValue,0).r)', gl.UNSIGNED_INT_SAMPLER_3D, 1, false],
+ ['usamplerCube', '', 'highp', '', 'float(textureSize(uniformValue,0).r)', gl.UNSIGNED_INT_SAMPLER_CUBE, 1, false],
+ ['usampler2DArray', '', 'highp', '', 'float(textureSize(uniformValue,0).r)', gl.UNSIGNED_INT_SAMPLER_2D_ARRAY, 1, false]
+ ];
+
+ var vertSource =
+ '#version 300 es\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(0.0);\n' +
+ '}\n';
+
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+ var program = gl.createProgram();
+
+ gl.attachShader(program, shaderVert);
+ gl.attachShader(program, shaderFrag);
+
+ gl.shaderSource(shaderVert, vertSource);
+ gl.compileShader(shaderVert);
+
+ for (var ndx = 0; ndx < uniformTypes.length; ++ndx) {
+ var declaration = uniformTypes[ndx][0];
+ var postDeclaration = uniformTypes[ndx][1];
+ var precision = uniformTypes[ndx][2];
+ var layout = uniformTypes[ndx][3];
+ var getter = uniformTypes[ndx][4];
+ var type = uniformTypes[ndx][5];
+ var size = uniformTypes[ndx][6];
+ var isRowMajor = uniformTypes[ndx][7];
+ bufferedLogToConsole('Verify type of ' + declaration + ' variable' + postDeclaration);
+
+ // gen fragment shader
+
+ var frag = '';
+ frag += '#version 300 es\n';
+ frag += layout + 'uniform ' + precision + ' ' + declaration + ' uniformValue' + postDeclaration + ';\n';
+ frag += 'layout(location = 0) out mediump vec4 fragColor;\n';
+ frag += 'void main (void)\n';
+ frag += '{\n';
+ frag += ' fragColor = vec4(' + getter + ');\n';
+ frag += '}\n';
+
+ gl.shaderSource(shaderFrag, frag);
+
+ // compile & link
+
+ gl.compileShader(shaderFrag);
+ gl.linkProgram(program);
+
+ // test
+ if (this.check(glsStateQuery.verifyProgram(program, gl.LINK_STATUS, true), 'Program link fail' + gl.getProgramInfoLog(program))) {
+ var indices = gl.getUniformIndices(program, ['uniformValue']);
+ var info_type = gl.getActiveUniforms(program, indices, gl.UNIFORM_TYPE)[0];
+ var info_size = gl.getActiveUniforms(program, indices, gl.UNIFORM_SIZE)[0];
+ var info_is_row_major = gl.getActiveUniforms(program, indices, gl.UNIFORM_IS_ROW_MAJOR)[0];
+ this.check(glsStateQuery.compare(info_size, size));
+ this.check(glsStateQuery.compare(info_type, type));
+ this.check(glsStateQuery.compare(info_is_row_major, isRowMajor));
+ }
+ }
+
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(program);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.ProgramActiveUniformBlocksCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.ProgramActiveUniformBlocksCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.ProgramActiveUniformBlocksCase.prototype.test = function() {
+ var testVertSource =
+ '#version 300 es\n' +
+ 'uniform longlongUniformBlockName {highp vec2 vector2;} longlongUniformInstanceName;\n' +
+ 'uniform shortUniformBlockName {highp vec2 vector2;highp vec4 vector4;} shortUniformInstanceName;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = shortUniformInstanceName.vector4 + vec4(longlongUniformInstanceName.vector2.x) + vec4(shortUniformInstanceName.vector2.x);\n' +
+ '}\n';
+ var testFragSource =
+ '#version 300 es\n' +
+ 'uniform longlongUniformBlockName {highp vec2 vector2;} longlongUniformInstanceName;\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(longlongUniformInstanceName.vector2.y);\n' +
+ '}\n';
+
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, testVertSource);
+ gl.shaderSource(shaderFrag, testFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ var program = gl.createProgram();
+ gl.attachShader(program, shaderVert);
+ gl.attachShader(program, shaderFrag);
+ gl.linkProgram(program);
+
+ this.check(glsStateQuery.verifyShader(shaderVert, gl.COMPILE_STATUS, true));
+ this.check(glsStateQuery.verifyShader(shaderFrag, gl.COMPILE_STATUS, true));
+ this.check(glsStateQuery.verifyProgram(program, gl.LINK_STATUS, true));
+
+ this.check(glsStateQuery.verifyProgram(program, gl.ACTIVE_UNIFORM_BLOCKS, 2));
+
+ var longlongUniformBlockIndex = gl.getUniformBlockIndex(program, 'longlongUniformBlockName');
+ var shortUniformBlockIndex = gl.getUniformBlockIndex(program, 'shortUniformBlockName');
+
+ var uniformNames = [
+ 'longlongUniformBlockName.vector2',
+ 'shortUniformBlockName.vector2',
+ 'shortUniformBlockName.vector4'
+ ];
+
+ // test UNIFORM_BLOCK_INDEX
+
+ var uniformIndices = gl.getUniformIndices(program, uniformNames);
+
+ var uniformsBlockIndices = gl.getActiveUniforms(program, uniformIndices, gl.UNIFORM_BLOCK_INDEX);
+ this.check(uniformsBlockIndices[0] == longlongUniformBlockIndex &&
+ uniformsBlockIndices[1] == shortUniformBlockIndex &&
+ uniformsBlockIndices[2] == shortUniformBlockIndex,
+ 'Expected [' + longlongUniformBlockIndex + ", " + shortUniformBlockIndex + ", " + shortUniformBlockIndex + ']; got ' +
+ uniformsBlockIndices[0] + ", " + uniformsBlockIndices[1] + ", " + uniformsBlockIndices[2] + "]");
+
+ // test UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER & UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER
+
+ this.check(glsStateQuery.verifyActiveUniformBlock(program, longlongUniformBlockIndex, gl.UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, true));
+ this.check(glsStateQuery.verifyActiveUniformBlock(program, longlongUniformBlockIndex, gl.UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, true));
+ this.check(glsStateQuery.verifyActiveUniformBlock(program, shortUniformBlockIndex, gl.UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, true));
+ this.check(glsStateQuery.verifyActiveUniformBlock(program, shortUniformBlockIndex, gl.UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, false));
+
+ // test UNIFORM_BLOCK_ACTIVE_UNIFORMS
+
+ this.check(glsStateQuery.verifyActiveUniformBlock(program, longlongUniformBlockIndex, gl.UNIFORM_BLOCK_ACTIVE_UNIFORMS, 1));
+ this.check(glsStateQuery.verifyActiveUniformBlock(program, shortUniformBlockIndex, gl.UNIFORM_BLOCK_ACTIVE_UNIFORMS, 2));
+
+ // test UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES
+
+ var shortUniformBlockIndices = gl.getActiveUniformBlockParameter(program, shortUniformBlockIndex, gl.UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES);
+ this.check(shortUniformBlockIndices.length == 2, 'Expected 2 indices; got ' + shortUniformBlockIndices.length);
+
+ this.check(glsStateQuery.compare(shortUniformBlockIndices, new Uint32Array([uniformIndices[1], uniformIndices[2]])) ||
+ glsStateQuery.compare(shortUniformBlockIndices, new Uint32Array([uniformIndices[2], uniformIndices[1]])),
+ 'Expected { ' + uniformIndices[1] +', ' + uniformIndices[2] +
+ '}; got {' + shortUniformBlockIndices[0] + ', ' + shortUniformBlockIndices[1] + '}');
+
+ // check block names
+
+ var name = gl.getActiveUniformBlockName(program, longlongUniformBlockIndex);
+ this.check(name == "longlongUniformBlockName", 'Wrong uniform block name, expected longlongUniformBlockName; got ' + name);
+ name = gl.getActiveUniformBlockName(program, shortUniformBlockIndex)
+ this.check(name == "shortUniformBlockName", 'Wrong uniform block name, expected shortUniformBlockName; got ' + name);
+
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(program);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.TransformFeedbackCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.TransformFeedbackCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.TransformFeedbackCase.prototype.test = function() {
+ var transformFeedbackTestVertSource =
+ '#version 300 es\n' +
+ 'out highp vec4 tfOutput2withLongName;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(0.0);\n' +
+ ' tfOutput2withLongName = vec4(0.0);\n' +
+ '}\n';
+ var transformFeedbackTestFragSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) out highp vec4 fragColor;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+ var shaderProg = gl.createProgram();
+
+ this.check(glsStateQuery.verifyProgram(shaderProg, gl.TRANSFORM_FEEDBACK_BUFFER_MODE, gl.INTERLEAVED_ATTRIBS));
+
+ gl.shaderSource(shaderVert, transformFeedbackTestVertSource);
+ gl.shaderSource(shaderFrag, transformFeedbackTestFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ this.check(glsStateQuery.verifyShader(shaderVert, gl.COMPILE_STATUS, true));
+ this.check(glsStateQuery.verifyShader(shaderFrag, gl.COMPILE_STATUS, true));
+
+ gl.attachShader(shaderProg, shaderVert);
+ gl.attachShader(shaderProg, shaderFrag);
+
+ // check TRANSFORM_FEEDBACK_BUFFER_MODE
+
+ var transform_feedback_outputs = ['gl_Position', 'tfOutput2withLongName'];
+ var bufferModes = [gl.SEPARATE_ATTRIBS, gl.INTERLEAVED_ATTRIBS];
+
+ for (var ndx = 0; ndx < bufferModes.length; ++ndx) {
+ gl.transformFeedbackVaryings(shaderProg, transform_feedback_outputs, bufferModes[ndx]);
+ gl.linkProgram(shaderProg);
+
+ this.check(glsStateQuery.verifyProgram(shaderProg, gl.LINK_STATUS, true));
+ this.check(glsStateQuery.verifyProgram(shaderProg, gl.TRANSFORM_FEEDBACK_BUFFER_MODE, bufferModes[ndx]));
+ }
+
+ // check varyings
+ var varyings = /** @type {number} */ (gl.getProgramParameter(shaderProg, gl.TRANSFORM_FEEDBACK_VARYINGS));
+ this.check(varyings === 2);
+
+ for (var index = 0; index < varyings; ++index) {
+ var info = gl.getTransformFeedbackVarying(shaderProg, index);
+ this.check(glsStateQuery.compare(info.type, gl.FLOAT_VEC4));
+ this.check(glsStateQuery.compare(info.size, 1));
+ this.check(glsStateQuery.compare(info.name, transform_feedback_outputs[index]));
+ }
+
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(shaderProg);
+
+ // TODO(kbr): this test is failing and leaving an error in the GL
+ // state, causing later tests to fail. Clear the error state for
+ // the time being.
+ while (gl.getError() != gl.NO_ERROR) {}
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.ActiveAttributesCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.ActiveAttributesCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.ActiveAttributesCase.prototype.test = function() {
+ var testVertSource =
+ '#version 300 es\n' +
+ 'in highp vec2 longInputAttributeName;\n' +
+ 'in highp vec2 shortName;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = longInputAttributeName.yxxy + shortName.xyxy;\n' +
+ '}\n';
+ var testFragSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, testVertSource);
+ gl.shaderSource(shaderFrag, testFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ var program = gl.createProgram();
+ gl.attachShader(program, shaderVert);
+ gl.attachShader(program, shaderFrag);
+ gl.linkProgram(program);
+
+ this.check(glsStateQuery.verifyProgram(program, gl.ACTIVE_ATTRIBUTES, 2));
+
+ var attribNames = [
+ 'longInputAttributeName',
+ 'shortName'
+ ];
+ // check names
+ for (var attributeNdx = 0; attributeNdx < 2; ++attributeNdx) {
+ var info = gl.getActiveAttrib(program, attributeNdx);
+ this.check(glsStateQuery.compare(info.name, attribNames[0]) || glsStateQuery.compare(info.name, attribNames[1]));
+ }
+
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(program);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.VertexAttributeSizeCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.VertexAttributeSizeCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.VertexAttributeSizeCase.prototype.test = function() {
+ var pointers = [
+ // size test
+ [4, gl.FLOAT, 0, false, 0],
+ [3, gl.FLOAT, 0, false, 0],
+ [2, gl.FLOAT, 0, false, 0],
+ [1, gl.FLOAT, 0, false, 0],
+ [4, gl.INT, 0, false, 0],
+ [3, gl.INT, 0, false, 0],
+ [2, gl.INT, 0, false, 0],
+ [1, gl.INT, 0, false, 0]
+ ];
+
+ var buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+
+ // Test with default VAO
+
+ for (var ndx = 0; ndx < pointers.length; ++ndx) {
+ gl.vertexAttribPointer(0, pointers[ndx][0], pointers[ndx][1], pointers[ndx][3], pointers[ndx][2], pointers[ndx][4]);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_SIZE, pointers[ndx][0]));
+ }
+
+ // Test with multiple VAOs
+ var vao0 = gl.createVertexArray();
+ var vao1 = gl.createVertexArray();
+
+ // initial
+ gl.bindVertexArray(vao0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_SIZE, 4));
+
+ // set vao 0 to some value
+ gl.vertexAttribPointer(0, pointers[0][0], pointers[0][1], pointers[0][3], pointers[0][2], 0);
+
+ // set vao 1 to some other value
+ gl.bindVertexArray(vao1);
+ gl.vertexAttribPointer(0, pointers[1][0], pointers[1][1], pointers[1][3], pointers[1][2], 0);
+
+ // verify vao 1 state
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_SIZE, pointers[1][0]));
+
+ // verify vao 0 state
+ gl.bindVertexArray(vao0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_SIZE, pointers[0][0]));
+
+ gl.deleteVertexArray(vao0);
+ gl.deleteVertexArray(vao1);
+ gl.deleteBuffer(buf);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.VertexAttributeTypeCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.VertexAttributeTypeCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.VertexAttributeTypeCase.prototype.test = function() {
+ var pointers = [
+ // type test
+ [1, gl.BYTE, 0, false, 0],
+ [1, gl.SHORT, 0, false, 0],
+ [1, gl.INT, 0, false, 0],
+ [1, gl.FLOAT, 0, false, 0],
+ [1, gl.HALF_FLOAT, 0, false, 0],
+ [1, gl.UNSIGNED_BYTE, 0, false, 0],
+ [1, gl.UNSIGNED_SHORT, 0, false, 0],
+ [1, gl.UNSIGNED_INT, 0, false, 0],
+ [4, gl.INT_2_10_10_10_REV, 0, false, 0],
+ [4, gl.UNSIGNED_INT_2_10_10_10_REV, 0, false, 0]
+ ];
+
+ var buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+
+ // Test with default VAO
+
+ for (var ndx = 0; ndx < pointers.length; ++ndx) {
+ gl.vertexAttribPointer(0, pointers[ndx][0], pointers[ndx][1], pointers[ndx][3], pointers[ndx][2], pointers[ndx][4]);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_TYPE, pointers[ndx][1]));
+ }
+
+ var pointersI = [
+ [1, gl.BYTE, 0, false, 0],
+ [1, gl.SHORT, 0, false, 0],
+ [1, gl.INT, 0, false, 0],
+ [1, gl.UNSIGNED_BYTE, 0, false, 0],
+ [1, gl.UNSIGNED_SHORT, 0, false, 0],
+ [1, gl.UNSIGNED_INT, 0, false, 0]
+ ];
+
+ for (var ndx = 0; ndx < pointersI.length; ++ndx) {
+ gl.vertexAttribIPointer(0, pointersI[ndx][0], pointersI[ndx][1], pointersI[ndx][2], pointersI[ndx][4]);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_TYPE, pointersI[ndx][1]));
+ }
+
+ // Test with multiple VAOs
+ var vao0 = gl.createVertexArray();
+ var vao1 = gl.createVertexArray();
+
+ // initial
+ gl.bindVertexArray(vao0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_TYPE, gl.FLOAT));
+
+ // set vao 0 to some value
+ gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
+
+ // set vao 1 to some other value
+ gl.bindVertexArray(vao1);
+ gl.vertexAttribPointer(0, 1, gl.SHORT, false, 0, 0);
+
+ // verify vao 1 state
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_TYPE, gl.SHORT));
+
+ // verify vao 0 state
+ gl.bindVertexArray(vao0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_TYPE, gl.FLOAT));
+
+ gl.deleteVertexArray(vao0);
+ gl.deleteVertexArray(vao1);
+ gl.deleteBuffer(buf);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.VertexAttributeStrideCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.VertexAttributeStrideCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.VertexAttributeStrideCase.prototype.test = function() {
+ var pointers = [
+ [1, gl.FLOAT, 0, 0, gl.NO_ERROR],
+ [1, gl.FLOAT, 1, 0, gl.INVALID_OPERATION],
+ [1, gl.FLOAT, 4, 0, gl.NO_ERROR],
+ [1, gl.HALF_FLOAT, 0, 0, gl.NO_ERROR],
+ [1, gl.HALF_FLOAT, 1, 0, gl.INVALID_OPERATION],
+ [1, gl.HALF_FLOAT, 4, 0, gl.NO_ERROR]
+ ];
+
+ var buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+
+ // Test with default VAO
+
+ for (var ndx = 0; ndx < pointers.length; ++ndx) {
+ gl.vertexAttribPointer(0, pointers[ndx][0], pointers[ndx][1], false, pointers[ndx][2], pointers[ndx][3]);
+ this.expectError(pointers[ndx][4]);
+ if (pointers[ndx][4] == gl.NO_ERROR) {
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_STRIDE, pointers[ndx][2]));
+ }
+ }
+
+ var pointersI = [
+ [1, gl.INT, 0, 0, gl.NO_ERROR],
+ [1, gl.INT, 1, 0, gl.INVALID_OPERATION],
+ [1, gl.INT, 4, 0, gl.NO_ERROR],
+ [4, gl.UNSIGNED_BYTE, 0, 0, gl.NO_ERROR],
+ [4, gl.UNSIGNED_BYTE, 1, 0, gl.NO_ERROR],
+ [4, gl.UNSIGNED_BYTE, 4, 0, gl.NO_ERROR],
+ [2, gl.SHORT, 0, 0, gl.NO_ERROR],
+ [2, gl.SHORT, 1, 0, gl.INVALID_OPERATION],
+ [2, gl.SHORT, 4, 0, gl.NO_ERROR]
+ ];
+
+ for (var ndx = 0; ndx < pointersI.length; ++ndx) {
+ gl.vertexAttribIPointer(0, pointersI[ndx][0], pointersI[ndx][1], pointersI[ndx][2], pointersI[ndx][3]);
+ this.expectError(pointersI[ndx][4]);
+ if (pointersI[ndx][4] == gl.NO_ERROR) {
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_STRIDE, pointersI[ndx][2]));
+ }
+ }
+
+ // Test with multiple VAOs
+ var vao0 = gl.createVertexArray();
+ var vao1 = gl.createVertexArray();
+
+ // initial
+ gl.bindVertexArray(vao0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_STRIDE, 0));
+
+ // set vao 0 to some value
+ gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 4, 0);
+
+ // set vao 1 to some other value
+ gl.bindVertexArray(vao1);
+ gl.vertexAttribPointer(0, 1, gl.SHORT, false, 8, 0);
+
+ // verify vao 1 state
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_STRIDE, 8));
+
+ // verify vao 0 state
+ gl.bindVertexArray(vao0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_STRIDE, 4));
+
+ gl.deleteVertexArray(vao0);
+ gl.deleteVertexArray(vao1);
+ gl.deleteBuffer(buf);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.VertexAttributeNormalizedCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.VertexAttributeNormalizedCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.VertexAttributeNormalizedCase.prototype.test = function() {
+ var pointers = [
+ // type test
+ [1, gl.BYTE, 0, false, 0],
+ [1, gl.SHORT, 0, false, 0],
+ [1, gl.INT, 0, false, 0],
+ [1, gl.FLOAT, 0, false, 0],
+ [1, gl.HALF_FLOAT, 0, false, 0],
+ [1, gl.UNSIGNED_BYTE, 0, false, 0],
+ [1, gl.UNSIGNED_SHORT, 0, false, 0],
+ [1, gl.UNSIGNED_INT, 0, false, 0],
+ [4, gl.INT_2_10_10_10_REV, 0, false, 0],
+ [4, gl.UNSIGNED_INT_2_10_10_10_REV, 0, false, 0],
+ [1, gl.BYTE, 0, true, 0],
+ [1, gl.SHORT, 0, true, 0],
+ [1, gl.INT, 0, true, 0],
+ [1, gl.FLOAT, 0, true, 0],
+ [1, gl.HALF_FLOAT, 0, true, 0],
+ [1, gl.UNSIGNED_BYTE, 0, true, 0],
+ [1, gl.UNSIGNED_SHORT, 0, true, 0],
+ [1, gl.UNSIGNED_INT, 0, true, 0],
+ [4, gl.INT_2_10_10_10_REV, 0, true, 0],
+ [4, gl.UNSIGNED_INT_2_10_10_10_REV, 0, true, 0]
+ ];
+
+ var buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+
+ // Test with default VAO
+
+ for (var ndx = 0; ndx < pointers.length; ++ndx) {
+ gl.vertexAttribPointer(0, pointers[ndx][0], pointers[ndx][1], pointers[ndx][3], pointers[ndx][2], pointers[ndx][4]);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED, pointers[ndx][3]));
+ }
+
+ var pointersI = [
+ [1, gl.BYTE, 0, false, 0],
+ [1, gl.SHORT, 0, false, 0],
+ [1, gl.INT, 0, false, 0],
+ [1, gl.UNSIGNED_BYTE, 0, false, 0],
+ [1, gl.UNSIGNED_SHORT, 0, false, 0],
+ [1, gl.UNSIGNED_INT, 0, false, 0]
+ ];
+
+ for (var ndx = 0; ndx < pointersI.length; ++ndx) {
+ gl.vertexAttribIPointer(0, pointersI[ndx][0], pointersI[ndx][1], pointersI[ndx][2], pointersI[ndx][4]);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED, false));
+ }
+
+ // Test with multiple VAOs
+ var vao0 = gl.createVertexArray();
+ var vao1 = gl.createVertexArray();
+
+ // initial
+ gl.bindVertexArray(vao0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED, false));
+
+ // set vao 0 to some value
+ gl.vertexAttribPointer(0, 1, gl.INT, true, 0, 0);
+
+ // set vao 1 to some other value
+ gl.bindVertexArray(vao1);
+ gl.vertexAttribPointer(0, 1, gl.INT, false, 0, 0);
+
+ // verify vao 1 state
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED, false));
+
+ // verify vao 0 state
+ gl.bindVertexArray(vao0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED, true));
+
+ gl.deleteVertexArray(vao0);
+ gl.deleteVertexArray(vao1);
+ gl.deleteBuffer(buf);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.VertexAttributeIntegerCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.VertexAttributeIntegerCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.VertexAttributeIntegerCase.prototype.test = function() {
+ var pointers = [
+ // type test
+ [1, gl.BYTE, 0, false, 0],
+ [1, gl.SHORT, 0, false, 0],
+ [1, gl.INT, 0, false, 0],
+ [1, gl.FLOAT, 0, false, 0],
+ [1, gl.HALF_FLOAT, 0, false, 0],
+ [1, gl.UNSIGNED_BYTE, 0, false, 0],
+ [1, gl.UNSIGNED_SHORT, 0, false, 0],
+ [1, gl.UNSIGNED_INT, 0, false, 0],
+ [4, gl.INT_2_10_10_10_REV, 0, false, 0],
+ [4, gl.UNSIGNED_INT_2_10_10_10_REV, 0, false, 0]
+ ];
+
+ var buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+
+ // Test with default VAO
+
+ for (var ndx = 0; ndx < pointers.length; ++ndx) {
+ gl.vertexAttribPointer(0, pointers[ndx][0], pointers[ndx][1], pointers[ndx][3], pointers[ndx][2], pointers[ndx][4]);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_INTEGER, false));
+ }
+
+ var pointersI = [
+ [1, gl.BYTE, 0, false, 0],
+ [1, gl.SHORT, 0, false, 0],
+ [1, gl.INT, 0, false, 0],
+ [1, gl.UNSIGNED_BYTE, 0, false, 0],
+ [1, gl.UNSIGNED_SHORT, 0, false, 0],
+ [1, gl.UNSIGNED_INT, 0, false, 0]
+ ];
+
+ for (var ndx = 0; ndx < pointersI.length; ++ndx) {
+ gl.vertexAttribIPointer(0, pointersI[ndx][0], pointersI[ndx][1], pointersI[ndx][2], pointersI[ndx][4]);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_INTEGER, true));
+ }
+
+ // Test with multiple VAOs
+ var vao0 = gl.createVertexArray();
+ var vao1 = gl.createVertexArray();
+
+ // initial
+ gl.bindVertexArray(vao0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_INTEGER, false));
+
+ // set vao 0 to some value
+ gl.vertexAttribIPointer(0, 1, gl.INT, 0, 0);
+
+ // set vao 1 to some other value
+ gl.bindVertexArray(vao1);
+ gl.vertexAttribPointer(0, 1, gl.FLOAT, false, 0, 0);
+
+ // verify vao 1 state
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_INTEGER, false));
+
+ // verify vao 0 state
+ gl.bindVertexArray(vao0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_INTEGER, true));
+
+ gl.deleteVertexArray(vao0);
+ gl.deleteVertexArray(vao1);
+ gl.deleteBuffer(buf);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.VertexAttributeEnabledCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.VertexAttributeEnabledCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.VertexAttributeEnabledCase.prototype.test = function() {
+ // Test with default VAO
+
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_ENABLED, false));
+ gl.enableVertexAttribArray(0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_ENABLED, true));
+ gl.disableVertexAttribArray(0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_ENABLED, false));
+
+ // Test with multiple VAOs
+ var vao0 = gl.createVertexArray();
+ var vao1 = gl.createVertexArray();
+
+ // initial
+ gl.bindVertexArray(vao0);
+ // set vao 0 to some value
+ gl.enableVertexAttribArray(0);
+
+ // set vao 1 to some other value
+ gl.bindVertexArray(vao1);
+ gl.disableVertexAttribArray(0);
+
+ // verify vao 1 state
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_ENABLED, false));
+
+ // verify vao 0 state
+ gl.bindVertexArray(vao0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_ENABLED, true));
+
+ gl.deleteVertexArray(vao0);
+ gl.deleteVertexArray(vao1);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.VertexAttributeDivisorCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.VertexAttributeDivisorCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.VertexAttributeDivisorCase.prototype.test = function() {
+ // Test with default VAO
+
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_DIVISOR, 0));
+ gl.vertexAttribDivisor(0, 1);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_DIVISOR, 1));
+ gl.vertexAttribDivisor(0, 5);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_DIVISOR, 5));
+
+ // Test with multiple VAOs
+ var vao0 = gl.createVertexArray();
+ var vao1 = gl.createVertexArray();
+
+ // initial
+ gl.bindVertexArray(vao0);
+ // set vao 0 to some value
+ gl.vertexAttribDivisor(0, 1);
+
+ // set vao 1 to some other value
+ gl.bindVertexArray(vao1);
+ gl.vertexAttribDivisor(0, 5);
+
+ // verify vao 1 state
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_DIVISOR, 5));
+
+ // verify vao 0 state
+ gl.bindVertexArray(vao0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_DIVISOR, 1));
+
+ gl.deleteVertexArray(vao0);
+ gl.deleteVertexArray(vao1);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.VertexAttributeBufferBindingCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.VertexAttributeBufferBindingCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.VertexAttributeBufferBindingCase.prototype.test = function() {
+ // Test with default VAO
+
+ var buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+
+ gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 0, 0);
+
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, buffer));
+
+ gl.deleteBuffer(buffer);
+
+ // Test with multiple VAOs
+ var vao0 = gl.createVertexArray();
+ var vao1 = gl.createVertexArray();
+ var buffer0 = gl.createBuffer();
+ var buffer1 = gl.createBuffer();
+
+ // initial
+ gl.bindVertexArray(vao0);
+ // set vao 0 to some value
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer0);
+ gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 0, 0);
+
+ // set vao 1 to some other value
+ gl.bindVertexArray(vao1);
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer1);
+ gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 0, 0);
+
+ // verify vao 1 state
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, buffer1));
+
+ // verify vao 0 state
+ gl.bindVertexArray(vao0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, buffer0));
+
+ gl.deleteVertexArray(vao0);
+ gl.deleteVertexArray(vao1);
+ gl.deleteBuffer(buffer0);
+ gl.deleteBuffer(buffer1);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.VertexAttributeOffsetCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.VertexAttributeOffsetCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.VertexAttributeOffsetCase.prototype.test = function() {
+ var pointers = [
+ [1, gl.BYTE, 0, false, 2 * 4],
+ [1, gl.SHORT, 0, false, 1 * 4],
+ [1, gl.INT, 0, false, 2 * 4],
+ [1, gl.FLOAT, 0, false, 0 * 4],
+ [1, gl.FLOAT, 0, false, 3 * 4],
+ [1, gl.FLOAT, 0, false, 2 * 4],
+ [1, gl.HALF_FLOAT, 0, false, 0 * 4],
+ [4, gl.HALF_FLOAT, 0, false, 1 * 4],
+ [4, gl.HALF_FLOAT, 0, false, 2 * 4]
+ ];
+
+ var buf = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buf);
+
+ // Test with default VAO
+
+ for (var ndx = 0; ndx < pointers.length; ++ndx) {
+ gl.vertexAttribPointer(0, pointers[ndx][0], pointers[ndx][1], pointers[ndx][3], pointers[ndx][2], pointers[ndx][4]);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_POINTER, pointers[ndx][4]));
+ }
+
+ // Test with multiple VAOs
+ var vao0 = gl.createVertexArray();
+ var vao1 = gl.createVertexArray();
+
+ // initial
+ gl.bindVertexArray(vao0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_POINTER, 0));
+
+ // set vao 0 to some value
+ gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 0, 8);
+
+ // set vao 1 to some other value
+ gl.bindVertexArray(vao1);
+ gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 0, 4);
+
+ // verify vao 1 state
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_POINTER, 4));
+
+ // verify vao 0 state
+ gl.bindVertexArray(vao0);
+ this.check(glsStateQuery.verifyVertexAttrib(0, gl.VERTEX_ATTRIB_ARRAY_POINTER, 8));
+
+ gl.deleteVertexArray(vao0);
+ gl.deleteVertexArray(vao1);
+ gl.deleteBuffer(buf);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.UniformValueFloatCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.UniformValueFloatCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.UniformValueFloatCase.prototype.test = function() {
+ var testVertSource =
+ '#version 300 es\n' +
+ 'uniform highp float floatUniform;\n' +
+ 'uniform highp vec2 float2Uniform;\n' +
+ 'uniform highp vec3 float3Uniform;\n' +
+ 'uniform highp vec4 float4Uniform;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(floatUniform + float2Uniform.x + float3Uniform.x + float4Uniform.x);\n' +
+ '}\n';
+ var testFragSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, testVertSource);
+ gl.shaderSource(shaderFrag, testFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ var program = gl.createProgram();
+ gl.attachShader(program, shaderVert);
+ gl.attachShader(program, shaderFrag);
+ gl.linkProgram(program);
+ gl.useProgram(program);
+
+ var location;
+
+ location = gl.getUniformLocation(program, 'floatUniform');
+ gl.uniform1f(location, 1);
+ this.check(glsStateQuery.verifyUniform(program, location, 1));
+
+ location = gl.getUniformLocation(program, 'float2Uniform');
+ gl.uniform2f(location, 1, 2);
+ this.check(glsStateQuery.verifyUniform(program, location, new Float32Array([1, 2])));
+
+ location = gl.getUniformLocation(program, 'float3Uniform');
+ gl.uniform3f(location, 1, 2, 3);
+ this.check(glsStateQuery.verifyUniform(program, location, new Float32Array([1, 2, 3])));
+
+ location = gl.getUniformLocation(program, 'float4Uniform');
+ gl.uniform4f(location, 1, 2, 3, 4);
+ this.check(glsStateQuery.verifyUniform(program, location, new Float32Array([1, 2, 3, 4])));
+
+ gl.useProgram(null);
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(program);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.UniformValueIntCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.UniformValueIntCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.UniformValueIntCase.prototype.test = function() {
+ var testVertSource =
+ '#version 300 es\n' +
+ 'uniform highp int intUniform;\n' +
+ 'uniform highp ivec2 int2Uniform;\n' +
+ 'uniform highp ivec3 int3Uniform;\n' +
+ 'uniform highp ivec4 int4Uniform;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(float(intUniform + int2Uniform.x + int3Uniform.x + int4Uniform.x));\n' +
+ '}\n';
+ var testFragSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, testVertSource);
+ gl.shaderSource(shaderFrag, testFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ var program = gl.createProgram();
+ gl.attachShader(program, shaderVert);
+ gl.attachShader(program, shaderFrag);
+ gl.linkProgram(program);
+ gl.useProgram(program);
+
+ var location;
+
+ location = gl.getUniformLocation(program, 'intUniform');
+ gl.uniform1i(location, 1);
+ this.check(glsStateQuery.verifyUniform(program, location, 1));
+
+ location = gl.getUniformLocation(program, 'int2Uniform');
+ gl.uniform2i(location, 1, 2);
+ this.check(glsStateQuery.verifyUniform(program, location, new Int32Array([1, 2])));
+
+ location = gl.getUniformLocation(program, 'int3Uniform');
+ gl.uniform3i(location, 1, 2, 3);
+ this.check(glsStateQuery.verifyUniform(program, location, new Int32Array([1, 2, 3])));
+
+ location = gl.getUniformLocation(program, 'int4Uniform');
+ gl.uniform4i(location, 1, 2, 3, 4);
+ this.check(glsStateQuery.verifyUniform(program, location, new Int32Array([1, 2, 3, 4])));
+
+ gl.useProgram(null);
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(program);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.UniformValueUintCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.UniformValueUintCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.UniformValueUintCase.prototype.test = function() {
+ var testVertSource =
+ '#version 300 es\n' +
+ 'uniform highp uint uintUniform;\n' +
+ 'uniform highp uvec2 uint2Uniform;\n' +
+ 'uniform highp uvec3 uint3Uniform;\n' +
+ 'uniform highp uvec4 uint4Uniform;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(float(uintUniform + uint2Uniform.x + uint3Uniform.x + uint4Uniform.x));\n' +
+ '}\n';
+ var testFragSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, testVertSource);
+ gl.shaderSource(shaderFrag, testFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ var program = gl.createProgram();
+ gl.attachShader(program, shaderVert);
+ gl.attachShader(program, shaderFrag);
+ gl.linkProgram(program);
+ gl.useProgram(program);
+
+ var location;
+
+ location = gl.getUniformLocation(program, 'uintUniform');
+ gl.uniform1ui(location, 1);
+ this.check(glsStateQuery.verifyUniform(program, location, 1));
+
+ location = gl.getUniformLocation(program, 'uint2Uniform');
+ gl.uniform2ui(location, 1, 2);
+ this.check(glsStateQuery.verifyUniform(program, location, new Uint32Array([1, 2])));
+
+ location = gl.getUniformLocation(program, 'uint3Uniform');
+ gl.uniform3ui(location, 1, 2, 3);
+ this.check(glsStateQuery.verifyUniform(program, location, new Uint32Array([1, 2, 3])));
+
+ location = gl.getUniformLocation(program, 'uint4Uniform');
+ gl.uniform4ui(location, 1, 2, 3, 4);
+ this.check(glsStateQuery.verifyUniform(program, location, new Uint32Array([1, 2, 3, 4])));
+
+ gl.useProgram(null);
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(program);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.UniformValueBooleanCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.UniformValueBooleanCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.UniformValueBooleanCase.prototype.test = function() {
+ var testVertSource =
+ '#version 300 es\n' +
+ 'uniform bool boolUniform;\n' +
+ 'uniform bvec2 bool2Uniform;\n' +
+ 'uniform bvec3 bool3Uniform;\n' +
+ 'uniform bvec4 bool4Uniform;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(float(boolUniform) + float(bool2Uniform.x) + float(bool3Uniform.x) + float(bool4Uniform.x));\n' +
+ '}\n';
+ var testFragSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, testVertSource);
+ gl.shaderSource(shaderFrag, testFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ var program = gl.createProgram();
+ gl.attachShader(program, shaderVert);
+ gl.attachShader(program, shaderFrag);
+ gl.linkProgram(program);
+ gl.useProgram(program);
+
+ var location;
+
+ location = gl.getUniformLocation(program, 'boolUniform');
+ gl.uniform1i(location, 1);
+ this.check(glsStateQuery.verifyUniform(program, location, true));
+
+ location = gl.getUniformLocation(program, 'bool2Uniform');
+ gl.uniform2i(location, 1, 0);
+ this.check(glsStateQuery.verifyUniform(program, location, [true, false]));
+
+ location = gl.getUniformLocation(program, 'bool3Uniform');
+ gl.uniform3i(location, 1, 0, 1);
+ this.check(glsStateQuery.verifyUniform(program, location, [true, false, true]));
+
+ location = gl.getUniformLocation(program, 'bool4Uniform');
+ gl.uniform4i(location, 1, 0, 1, 0);
+ this.check(glsStateQuery.verifyUniform(program, location, [true, false, true, false]));
+
+ gl.useProgram(null);
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(program);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.UniformValueSamplerCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.UniformValueSamplerCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.UniformValueSamplerCase.prototype.test = function() {
+ var testVertSource =
+ '#version 300 es\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(0.0);\n' +
+ '}\n';
+ var testFragSource =
+ '#version 300 es\n' +
+ 'uniform highp sampler2D uniformSampler;\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(textureSize(uniformSampler, 0).x);\n' +
+ '}\n';
+
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, testVertSource);
+ gl.shaderSource(shaderFrag, testFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ var program = gl.createProgram();
+ gl.attachShader(program, shaderVert);
+ gl.attachShader(program, shaderFrag);
+ gl.linkProgram(program);
+ gl.useProgram(program);
+
+ var location;
+
+ location = gl.getUniformLocation(program, 'uniformSampler');
+ gl.uniform1i(location, 1);
+ this.check(glsStateQuery.verifyUniform(program, location, 1));
+
+ gl.useProgram(null);
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(program);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.UniformValueArrayCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.UniformValueArrayCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.UniformValueArrayCase.prototype.test = function() {
+ var testVertSource =
+ '#version 300 es\n' +
+ 'uniform highp float arrayUniform[5];' +
+ 'uniform highp vec2 array2Uniform[5];' +
+ 'uniform highp vec3 array3Uniform[5];' +
+ 'uniform highp vec4 array4Uniform[5];' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = \n' +
+ ' + vec4(arrayUniform[0] + arrayUniform[1] + arrayUniform[2] + arrayUniform[3] + arrayUniform[4])\n' +
+ ' + vec4(array2Uniform[0].x + array2Uniform[1].x + array2Uniform[2].x + array2Uniform[3].x + array2Uniform[4].x)\n' +
+ ' + vec4(array3Uniform[0].x + array3Uniform[1].x + array3Uniform[2].x + array3Uniform[3].x + array3Uniform[4].x)\n' +
+ ' + vec4(array4Uniform[0].x + array4Uniform[1].x + array4Uniform[2].x + array4Uniform[3].x + array4Uniform[4].x);\n' +
+ '}\n';
+ var testFragSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, testVertSource);
+ gl.shaderSource(shaderFrag, testFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ var program = gl.createProgram();
+ gl.attachShader(program, shaderVert);
+ gl.attachShader(program, shaderFrag);
+ gl.linkProgram(program);
+ gl.useProgram(program);
+
+ var location;
+
+ var uniformValue = [
+ -1.0, 0.1, 4.0, 800.0,
+ 13.0, 55.0, 12.0, 91.0,
+ -55.1, 1.1, 98.0, 19.0,
+ 41.0, 65.0, 4.0, 12.2,
+ 95.0, 77.0, 32.0, 48.0
+ ];
+
+ location = gl.getUniformLocation(program, 'arrayUniform');
+ gl.uniform1fv(location, new Float32Array(uniformValue.slice(0, 5)));
+
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'arrayUniform[0]'), uniformValue[0]));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'arrayUniform[1]'), uniformValue[1]));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'arrayUniform[2]'), uniformValue[2]));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'arrayUniform[3]'), uniformValue[3]));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'arrayUniform[4]'), uniformValue[4]));
+
+ location = gl.getUniformLocation(program, 'array2Uniform');
+ gl.uniform2fv(location, new Float32Array(uniformValue.slice(0, 10)));
+
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'array2Uniform[0]'), new Float32Array([uniformValue[2 * 0], uniformValue[(2 * 0) + 1]])));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'array2Uniform[1]'), new Float32Array([uniformValue[2 * 1], uniformValue[(2 * 1) + 1]])));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'array2Uniform[2]'), new Float32Array([uniformValue[2 * 2], uniformValue[(2 * 2) + 1]])));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'array2Uniform[3]'), new Float32Array([uniformValue[2 * 3], uniformValue[(2 * 3) + 1]])));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'array2Uniform[4]'), new Float32Array([uniformValue[2 * 4], uniformValue[(2 * 4) + 1]])));
+
+ location = gl.getUniformLocation(program, 'array3Uniform');
+ gl.uniform3fv(location, new Float32Array(uniformValue.slice(0, 15)));
+
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'array3Uniform[0]'), new Float32Array([uniformValue[3 * 0], uniformValue[(3 * 0) + 1], uniformValue[(3 * 0) + 2]])));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'array3Uniform[1]'), new Float32Array([uniformValue[3 * 1], uniformValue[(3 * 1) + 1], uniformValue[(3 * 1) + 2]])));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'array3Uniform[2]'), new Float32Array([uniformValue[3 * 2], uniformValue[(3 * 2) + 1], uniformValue[(3 * 2) + 2]])));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'array3Uniform[3]'), new Float32Array([uniformValue[3 * 3], uniformValue[(3 * 3) + 1], uniformValue[(3 * 3) + 2]])));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'array3Uniform[4]'), new Float32Array([uniformValue[3 * 4], uniformValue[(3 * 4) + 1], uniformValue[(3 * 4) + 2]])));
+
+ location = gl.getUniformLocation(program, 'array4Uniform');
+ gl.uniform4fv(location, new Float32Array(uniformValue));
+
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'array4Uniform[0]'), new Float32Array([uniformValue[4 * 0], uniformValue[(4 * 0) + 1], uniformValue[(4 * 0) + 2], uniformValue[(4 * 0) + 3]])));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'array4Uniform[1]'), new Float32Array([uniformValue[4 * 1], uniformValue[(4 * 1) + 1], uniformValue[(4 * 1) + 2], uniformValue[(4 * 1) + 3]])));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'array4Uniform[2]'), new Float32Array([uniformValue[4 * 2], uniformValue[(4 * 2) + 1], uniformValue[(4 * 2) + 2], uniformValue[(4 * 2) + 3]])));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'array4Uniform[3]'), new Float32Array([uniformValue[4 * 3], uniformValue[(4 * 3) + 1], uniformValue[(4 * 3) + 2], uniformValue[(4 * 3) + 3]])));
+ this.check(glsStateQuery.verifyUniform(program, gl.getUniformLocation(program, 'array4Uniform[4]'), new Float32Array([uniformValue[4 * 4], uniformValue[(4 * 4) + 1], uniformValue[(4 * 4) + 2], uniformValue[(4 * 4) + 3]])));
+
+ gl.useProgram(null);
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(program);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ */
+es3fShaderStateQueryTests.UniformValueMatrixCase = function(name, description) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+};
+
+setParentClass(es3fShaderStateQueryTests.UniformValueMatrixCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.UniformValueMatrixCase.prototype.test = function() {
+ var transpose = function(rows, cols, data) {
+ var matrix = tcuMatrix.matrixFromDataArray(rows, cols, data);
+ var result = [];
+ for (var col = 0; col < cols; col++)
+ result.push(matrix.getColumn(col));
+ return new Float32Array([].concat.apply([], result));
+ };
+
+ var testVertSource =
+ '#version 300 es\n' +
+ 'uniform highp mat2 mat2Uniform;' +
+ 'uniform highp mat3 mat3Uniform;' +
+ 'uniform highp mat4 mat4Uniform;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = vec4(mat2Uniform[0][0] + mat3Uniform[0][0] + mat4Uniform[0][0]);\n' +
+ '}\n';
+ var testFragSource =
+ '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' fragColor = vec4(0.0);\n' +
+ '}\n';
+
+ var shaderVert = gl.createShader(gl.VERTEX_SHADER);
+ var shaderFrag = gl.createShader(gl.FRAGMENT_SHADER);
+
+ gl.shaderSource(shaderVert, testVertSource);
+ gl.shaderSource(shaderFrag, testFragSource);
+
+ gl.compileShader(shaderVert);
+ gl.compileShader(shaderFrag);
+
+ var program = gl.createProgram();
+ gl.attachShader(program, shaderVert);
+ gl.attachShader(program, shaderFrag);
+ gl.linkProgram(program);
+ gl.useProgram(program);
+
+ var location;
+
+ var matrixValues = [
+ -1.0, 0.1, 4.0, 800.0,
+ 13.0, 55.0, 12.0, 91.0,
+ -55.1, 1.1, 98.0, 19.0,
+ 41.0, 65.0, 4.0, 12.0
+ ];
+
+ // the values of the matrix are returned in column major order but they can be given in either order
+
+ location = gl.getUniformLocation(program, 'mat2Uniform');
+ var m2 = new Float32Array(matrixValues.slice(0, 2 * 2));
+ gl.uniformMatrix2fv(location, false, m2);
+ this.check(glsStateQuery.verifyUniform(program, location, m2));
+ gl.uniformMatrix2fv(location, true, m2);
+ this.check(glsStateQuery.verifyUniform(program, location, transpose(2, 2, m2)));
+
+ location = gl.getUniformLocation(program, 'mat3Uniform');
+ var m3 = new Float32Array(matrixValues.slice(0, 3 * 3));
+ gl.uniformMatrix3fv(location, false, m3);
+ this.check(glsStateQuery.verifyUniform(program, location, m3));
+ gl.uniformMatrix3fv(location, true, m3);
+ this.check(glsStateQuery.verifyUniform(program, location, transpose(3, 3, m3)));
+
+ location = gl.getUniformLocation(program, 'mat4Uniform');
+ var m4 = new Float32Array(matrixValues.slice(0, 4 * 4));
+ gl.uniformMatrix4fv(location, false, m4);
+ this.check(glsStateQuery.verifyUniform(program, location, m4));
+ gl.uniformMatrix4fv(location, true, m4);
+ this.check(glsStateQuery.verifyUniform(program, location, transpose(4, 4, m4)));
+
+ gl.useProgram(null);
+ gl.deleteShader(shaderVert);
+ gl.deleteShader(shaderFrag);
+ gl.deleteProgram(program);
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} shaderType
+ * @param {number} precisionType
+ */
+es3fShaderStateQueryTests.PrecisionFormatCase = function(name, description, shaderType, precisionType) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ this.m_shaderType = shaderType;
+ this.m_precisionType = precisionType;
+};
+
+setParentClass(es3fShaderStateQueryTests.PrecisionFormatCase, es3fApiCase.ApiCase);
+
+es3fShaderStateQueryTests.PrecisionFormatCase.prototype.test = function() {
+ var requirements = {};
+ requirements[gl.LOW_FLOAT] = [0, 0, 8];
+ requirements[gl.MEDIUM_FLOAT] = [13, 13, 10];
+ requirements[gl.HIGH_FLOAT] = [127, 127, 23];
+ requirements[gl.LOW_INT] = [8, 7, 0];
+ requirements[gl.MEDIUM_INT] = [15, 14, 0];
+ requirements[gl.HIGH_INT] = [31, 30, 0];
+
+
+ var expected = requirements[this.m_precisionType];
+ var result = gl.getShaderPrecisionFormat(this.m_shaderType, this.m_precisionType);
+
+ bufferedLogToConsole('Precision:' +
+ ' range min = ' + result.rangeMin +
+ ' range max = ' + result.rangeMax +
+ ' precision = ' + result.precision);
+
+ if (this.m_precisionType == gl.HIGH_FLOAT) {
+ // highp float must be IEEE 754 single
+
+ this.check(result.rangeMin == expected[0] ||
+ result.rangeMax == expected[1] ||
+ result.precision == expected[2],
+ 'Invalid precision format, expected:' +
+ ' range min = ' + expected[0] +
+ ' range max = ' + expected[1] +
+ ' precision = ' + expected[2]);
+ } else{
+ this.check(result.rangeMin >= expected[0] ||
+ result.rangeMax >= expected[1] ||
+ result.precision >= expected[2],
+ 'Invalid precision format, expected:' +
+ ' range min >= ' + expected[0] +
+ ' range max >= ' + expected[1] +
+ ' precision >= ' + expected[2]);
+ }
+};
+
+/**
+* @constructor
+* @extends {tcuTestCase.DeqpTest}
+*/
+es3fShaderStateQueryTests.ShaderStateQueryTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'shader', 'Shader State Query tests');
+};
+
+es3fShaderStateQueryTests.ShaderStateQueryTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fShaderStateQueryTests.ShaderStateQueryTests.prototype.constructor = es3fShaderStateQueryTests.ShaderStateQueryTests;
+
+es3fShaderStateQueryTests.ShaderStateQueryTests.prototype.init = function() {
+ // shader
+ this.addChild(new es3fShaderStateQueryTests.ShaderTypeCase('shader_type', 'SHADER_TYPE'));
+ this.addChild(new es3fShaderStateQueryTests.ShaderCompileStatusCase('shader_compile_status', 'COMPILE_STATUS'));
+ this.addChild(new es3fShaderStateQueryTests.ShaderInfoLogCase('shader_info_log', 'INFO_LOG'));
+ this.addChild(new es3fShaderStateQueryTests.ShaderSourceCase('shader_source', 'SHADER_SOURCE'));
+
+ // shader and program
+ this.addChild(new es3fShaderStateQueryTests.DeleteStatusCase('delete_status', 'DELETE_STATUS'));
+
+ // // vertex-attrib
+ this.addChild(new es3fShaderStateQueryTests.CurrentVertexAttribInitialCase('current_vertex_attrib_initial', 'CURRENT_VERTEX_ATTRIB'));
+ this.addChild(new es3fShaderStateQueryTests.CurrentVertexAttribFloatCase('current_vertex_attrib_float', 'CURRENT_VERTEX_ATTRIB'));
+ this.addChild(new es3fShaderStateQueryTests.CurrentVertexAttribIntCase('current_vertex_attrib_int', 'CURRENT_VERTEX_ATTRIB'));
+ this.addChild(new es3fShaderStateQueryTests.CurrentVertexAttribUintCase('current_vertex_attrib_uint', 'CURRENT_VERTEX_ATTRIB'));
+
+ // // program
+ this.addChild(new es3fShaderStateQueryTests.ProgramInfoLogCase('program_info_log', 'INFO_LOG'));
+ this.addChild(new es3fShaderStateQueryTests.ProgramValidateStatusCase('program_validate_status', 'VALIDATE_STATUS'));
+ this.addChild(new es3fShaderStateQueryTests.ProgramAttachedShadersCase('program_attached_shaders', 'ATTACHED_SHADERS'));
+
+ this.addChild(new es3fShaderStateQueryTests.ProgramActiveUniformNameCase('program_active_uniform_name', 'ACTIVE_UNIFORMS'));
+ this.addChild(new es3fShaderStateQueryTests.ProgramUniformCase('program_active_uniform_types', 'UNIFORM_TYPE, UNIFORM_SIZE, and UNIFORM_IS_ROW_MAJOR'));
+ this.addChild(new es3fShaderStateQueryTests.ProgramActiveUniformBlocksCase ("program_active_uniform_blocks", "ACTIVE_UNIFORM_BLOCK_x"));
+
+ // transform feedback
+ this.addChild(new es3fShaderStateQueryTests.TransformFeedbackCase('transform_feedback', 'TRANSFORM_FEEDBACK_BUFFER_MODE, TRANSFORM_FEEDBACK_VARYINGS, TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH'));
+
+ // attribute related
+ this.addChild(new es3fShaderStateQueryTests.ActiveAttributesCase('active_attributes', 'ACTIVE_ATTRIBUTES and ACTIVE_ATTRIBUTE_MAX_LENGTH'));
+ this.addChild(new es3fShaderStateQueryTests.VertexAttributeSizeCase('vertex_attrib_size', 'VERTEX_ATTRIB_ARRAY_SIZE'));
+ this.addChild(new es3fShaderStateQueryTests.VertexAttributeTypeCase('vertex_attrib_type', 'VERTEX_ATTRIB_ARRAY_TYPE'));
+ this.addChild(new es3fShaderStateQueryTests.VertexAttributeStrideCase('vertex_attrib_stride', 'VERTEX_ATTRIB_ARRAY_STRIDE'));
+ this.addChild(new es3fShaderStateQueryTests.VertexAttributeNormalizedCase('vertex_attrib_normalized', 'VERTEX_ATTRIB_ARRAY_NORMALIZED'));
+ this.addChild(new es3fShaderStateQueryTests.VertexAttributeIntegerCase('vertex_attrib_integer', 'VERTEX_ATTRIB_ARRAY_INTEGER'));
+ this.addChild(new es3fShaderStateQueryTests.VertexAttributeEnabledCase('vertex_attrib_array_enabled', 'VERTEX_ATTRIB_ARRAY_ENABLED'));
+ this.addChild(new es3fShaderStateQueryTests.VertexAttributeDivisorCase('vertex_attrib_array_divisor', 'VERTEX_ATTRIB_ARRAY_DIVISOR'));
+ this.addChild(new es3fShaderStateQueryTests.VertexAttributeBufferBindingCase('vertex_attrib_array_buffer_binding', 'VERTEX_ATTRIB_ARRAY_BUFFER_BINDING'));
+ this.addChild(new es3fShaderStateQueryTests.VertexAttributeOffsetCase('vertex_attrib_offset', 'VERTEX_ATTRIB_ARRAY_POINTER'));
+
+ // uniform values
+ this.addChild(new es3fShaderStateQueryTests.UniformValueFloatCase('uniform_value_float', 'GetUniform*'));
+ this.addChild(new es3fShaderStateQueryTests.UniformValueIntCase('uniform_value_int', 'GetUniform*'));
+ this.addChild(new es3fShaderStateQueryTests.UniformValueUintCase('uniform_value_uint', 'GetUniform*'));
+ this.addChild(new es3fShaderStateQueryTests.UniformValueBooleanCase('uniform_value_boolean', 'GetUniform*'));
+ this.addChild(new es3fShaderStateQueryTests.UniformValueSamplerCase('uniform_value_sampler', 'GetUniform*'));
+ this.addChild(new es3fShaderStateQueryTests.UniformValueArrayCase('uniform_value_array', 'GetUniform*'));
+ this.addChild(new es3fShaderStateQueryTests.UniformValueMatrixCase('uniform_value_matrix', 'GetUniform*'));
+
+ // precision format query
+ this.addChild(new es3fShaderStateQueryTests.PrecisionFormatCase('precision_vertex_lowp_float', 'GetShaderPrecisionFormat', gl.VERTEX_SHADER, gl.LOW_FLOAT));
+ this.addChild(new es3fShaderStateQueryTests.PrecisionFormatCase('precision_vertex_mediump_float', 'GetShaderPrecisionFormat', gl.VERTEX_SHADER, gl.MEDIUM_FLOAT));
+ this.addChild(new es3fShaderStateQueryTests.PrecisionFormatCase('precision_vertex_highp_float', 'GetShaderPrecisionFormat', gl.VERTEX_SHADER, gl.HIGH_FLOAT));
+ this.addChild(new es3fShaderStateQueryTests.PrecisionFormatCase('precision_vertex_lowp_int', 'GetShaderPrecisionFormat', gl.VERTEX_SHADER, gl.LOW_INT));
+ this.addChild(new es3fShaderStateQueryTests.PrecisionFormatCase('precision_vertex_mediump_int', 'GetShaderPrecisionFormat', gl.VERTEX_SHADER, gl.MEDIUM_INT));
+ this.addChild(new es3fShaderStateQueryTests.PrecisionFormatCase('precision_vertex_highp_int', 'GetShaderPrecisionFormat', gl.VERTEX_SHADER, gl.HIGH_INT));
+ this.addChild(new es3fShaderStateQueryTests.PrecisionFormatCase('precision_fragment_lowp_float', 'GetShaderPrecisionFormat', gl.FRAGMENT_SHADER, gl.LOW_FLOAT));
+ this.addChild(new es3fShaderStateQueryTests.PrecisionFormatCase('precision_fragment_mediump_float', 'GetShaderPrecisionFormat', gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT));
+ this.addChild(new es3fShaderStateQueryTests.PrecisionFormatCase('precision_fragment_highp_float', 'GetShaderPrecisionFormat', gl.FRAGMENT_SHADER, gl.HIGH_FLOAT));
+ this.addChild(new es3fShaderStateQueryTests.PrecisionFormatCase('precision_fragment_lowp_int', 'GetShaderPrecisionFormat', gl.FRAGMENT_SHADER, gl.LOW_INT));
+ this.addChild(new es3fShaderStateQueryTests.PrecisionFormatCase('precision_fragment_mediump_int', 'GetShaderPrecisionFormat', gl.FRAGMENT_SHADER, gl.MEDIUM_INT));
+ this.addChild(new es3fShaderStateQueryTests.PrecisionFormatCase('precision_fragment_highp_int', 'GetShaderPrecisionFormat', gl.FRAGMENT_SHADER, gl.HIGH_INT));
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fShaderStateQueryTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fShaderStateQueryTests.ShaderStateQueryTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fShaderStateQueryTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderStructTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderStructTests.js
new file mode 100644
index 0000000000..3c23545d75
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderStructTests.js
@@ -0,0 +1,1957 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fShaderStructTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+// goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTexture');
+goog.require('modules.shared.glsShaderRenderCase');
+goog.require('framework.common.tcuStringTemplate');
+
+goog.scope(function() {
+ var es3fShaderStructTests = functional.gles3.es3fShaderStructTests;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuTexture = framework.common.tcuTexture;
+ var tcuTextureUtil = framework.common.tcuTextureUtil;
+ var deMath = framework.delibs.debase.deMath;
+ // var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
+ var gluTexture = framework.opengl.gluTexture;
+ var tcuStringTemplate = framework.common.tcuStringTemplate;
+
+ /** @typedef {function(WebGLProgram, Array<number>)} */
+ es3fShaderStructTests.SetupUniformsFunc;
+
+ /** @const {number} */ es3fShaderStructTests.TEXTURE_BRICK = 0;
+
+
+ /**
+ * @constructor
+ * @extends {glsShaderRenderCase.ShaderRenderCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {boolean} usesTextures
+ * @param {glsShaderRenderCase.ShaderEvalFunc} evalFunc
+ * @param {?es3fShaderStructTests.SetupUniformsFunc} setupUniformsFunc
+ * @param {string} vertShaderSource
+ * @param {string} fragShaderSource
+ */
+ es3fShaderStructTests.ShaderStructCase = function(name, description, isVertexCase, usesTextures, evalFunc, setupUniformsFunc, vertShaderSource, fragShaderSource) {
+ glsShaderRenderCase.ShaderRenderCase.call(this, name, description, isVertexCase, evalFunc);
+ /** @type {?es3fShaderStructTests.SetupUniformsFunc} */ this.m_setupUniforms = setupUniformsFunc;
+ /** @type {boolean} */ this.m_usesTexture = usesTextures;
+ /** @type {gluTexture.Texture2D} */ this.m_brickTexture = null;
+ /** @type {string} */ this.m_vertShaderSource = vertShaderSource;
+ /** @type {string} */ this.m_fragShaderSource = fragShaderSource;
+ };
+
+ es3fShaderStructTests.ShaderStructCase.prototype = Object.create(glsShaderRenderCase.ShaderRenderCase.prototype);
+ es3fShaderStructTests.ShaderStructCase.prototype.constructor = es3fShaderStructTests.ShaderStructCase;
+
+ es3fShaderStructTests.ShaderStructCase.prototype.init = function() {
+ if (this.m_usesTexture) {
+ this.m_brickTexture = gluTexture.texture2DFromInternalFormat(gl, gl.RGBA8, 256, 256);
+ var ref = this.m_brickTexture.getRefTexture();
+ for (var i = 0 ; i < ref.getNumLevels(); i++) {
+ ref.allocLevel(i);
+ tcuTextureUtil.fillWithGrid(ref.getLevel(i), 8, [0.2, 0.7, 0.1, 1.0], [0.7, 0.1, 0.5, 0.8]);
+ }
+ this.m_brickTexture.upload();
+
+ this.m_textures.push(new glsShaderRenderCase.TextureBinding(
+ this.m_brickTexture,
+ new tcuTexture.Sampler(
+ tcuTexture.WrapMode.CLAMP_TO_EDGE,
+ tcuTexture.WrapMode.CLAMP_TO_EDGE,
+ tcuTexture.WrapMode.CLAMP_TO_EDGE,
+ tcuTexture.FilterMode.LINEAR,
+ tcuTexture.FilterMode.LINEAR)));
+
+ assertMsgOptions(this.m_textures.length === 1, 'Only one texture required', false, true);
+ }
+ this.postinit();
+ };
+
+ es3fShaderStructTests.ShaderStructCase.prototype.deinit = function() {
+ glsShaderRenderCase.ShaderRenderCase.prototype.deinit.call(this);
+ this.m_brickTexture = null;
+ };
+
+ /**
+ * @param {WebGLProgram} programID
+ * @param {Array<number>} constCoords
+ */
+ es3fShaderStructTests.ShaderStructCase.prototype.setupUniforms = function(programID, constCoords) {
+ glsShaderRenderCase.ShaderRenderCase.prototype.setupUniforms.call(this, programID, constCoords);
+ if (this.m_setupUniforms)
+ this.m_setupUniforms(programID, constCoords);
+ };
+
+ /**
+ * @param {string} name
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {boolean} usesTextures
+ * @param {glsShaderRenderCase.ShaderEvalFunc} evalFunc
+ * @param {?es3fShaderStructTests.SetupUniformsFunc} setupUniforms
+ * @param {string} shaderSrc
+ */
+ es3fShaderStructTests.ShaderStructCase.createStructCase = function(name, description, isVertexCase, usesTextures, evalFunc, setupUniforms, shaderSrc) {
+ /** @type {string} */ var defaultVertSrc =
+ '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in highp vec4 a_coords;\n' +
+ 'out mediump vec4 v_coords;\n\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' v_coords = a_coords;\n' +
+ ' gl_Position = a_position;\n' +
+ '}\n';
+ /** @type {string} */ var defaultFragSrc =
+ '#version 300 es\n' +
+ 'in mediump vec4 v_color;\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = v_color;\n' +
+ '}\n';
+
+ // Fill in specialization parameters.
+ var spParams = {};
+ if (isVertexCase) {
+ spParams["HEADER"] =
+ "#version 300 es\n" +
+ "in highp vec4 a_position;\n" +
+ "in highp vec4 a_coords;\n" +
+ "out mediump vec4 v_color;";
+ spParams["COORDS"] = "a_coords";
+ spParams["DST"] = "v_color";
+ spParams["ASSIGN_POS"] = "gl_Position = a_position;";
+ }
+ else {
+ spParams["HEADER"] =
+ "#version 300 es\n" +
+ "in mediump vec4 v_coords;\n" +
+ "layout(location = 0) out mediump vec4 o_color;";
+ spParams["COORDS"] = "v_coords";
+ spParams["DST"] = "o_color";
+ spParams["ASSIGN_POS"] = "";
+ }
+
+ if (isVertexCase)
+ return new es3fShaderStructTests.ShaderStructCase(name, description, isVertexCase, usesTextures, evalFunc, setupUniforms, tcuStringTemplate.specialize(shaderSrc, spParams), defaultFragSrc);
+ else
+ return new es3fShaderStructTests.ShaderStructCase(name, description, isVertexCase, usesTextures, evalFunc, setupUniforms, defaultVertSrc, tcuStringTemplate.specialize(shaderSrc, spParams));
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderStructTests.LocalStructTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'local', 'Local structs');
+ this.makeExecutable();
+ };
+
+ es3fShaderStructTests.LocalStructTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderStructTests.LocalStructTests.prototype.constructor = es3fShaderStructTests.LocalStructTests;
+
+ es3fShaderStructTests.LocalStructTests.prototype.init = function() {
+ var currentCtx = this;
+ function LocalStructCase(name, description, shaderSource, evalFunction) {
+ currentCtx.addChild(es3fShaderStructTests.ShaderStructCase.createStructCase(name + "_vertex", description, true, false, evalFunction, null, shaderSource));
+ currentCtx.addChild(es3fShaderStructTests.ShaderStructCase.createStructCase(name + "_fragment", description, false, false, evalFunction, null, shaderSource));
+ };
+
+ LocalStructCase('basic', 'Basic struct usage',
+ '${HEADER}\n' +
+ 'uniform int ui_one;\n' +
+ '\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec3 b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s = S(${COORDS}.x, vec3(0.0), ui_one);\n' +
+ ' s.b = ${COORDS}.yzw;\n' +
+ ' ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[0];
+ c.color[1] = c.coords[1];
+ c.color[2] = c.coords[2];
+ });
+
+ LocalStructCase('nested', "Nested struct",
+ '${HEADER}\n' +
+ "uniform int ui_zero;\n" +
+ "uniform int ui_one;\n" +
+ "\n" +
+ "struct T {\n" +
+ " int a;\n" +
+ " mediump vec2 b;\n" +
+ "};\n" +
+ "struct S {\n" +
+ ' mediump float a;\n' +
+ ' T b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);\n' +
+ ' s.b = T(ui_zero, ${COORDS}.yz);\n' +
+ ' ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[0];
+ c.color[1] = c.coords[1];
+ c.color[2] = c.coords[2];
+ });
+
+ LocalStructCase('array_member', "Struct with array member",
+ '${HEADER}\n' +
+ 'uniform int ui_one;\n' +
+ '\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump float b[3];\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s;\n' +
+ ' s.a = ${COORDS}.w;\n' +
+ ' s.c = ui_one;\n' +
+ ' s.b[0] = ${COORDS}.z;\n' +
+ ' s.b[1] = ${COORDS}.y;\n' +
+ ' s.b[2] = ${COORDS}.x;\n' +
+ ' ${DST} = vec4(s.a, s.b[0], s.b[1], s.c);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[3];
+ c.color[1] = c.coords[2];
+ c.color[2] = c.coords[1];
+ });
+
+ LocalStructCase('array_member_dynamic_index', "Struct with array member, dynamic indexing",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ '\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump float b[3];\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s;\n' +
+ ' s.a = ${COORDS}.w;\n' +
+ ' s.c = ui_one;\n' +
+ ' s.b[0] = ${COORDS}.z;\n' +
+ ' s.b[1] = ${COORDS}.y;\n' +
+ ' s.b[2] = ${COORDS}.x;\n' +
+ ' ${DST} = vec4(s.b[ui_one], s.b[ui_zero], s.b[ui_two], s.c);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[1];
+ c.color[1] = c.coords[2];
+ c.color[2] = c.coords[0];
+ });
+
+ LocalStructCase('struct_array', "Struct array",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ '\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump int b;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s[3];\n' +
+ ' s[0] = S(${COORDS}.x, ui_zero);\n' +
+ ' s[1].a = ${COORDS}.y;\n' +
+ ' s[1].b = ui_one;\n' +
+ ' s[2] = S(${COORDS}.z, ui_two);\n' +
+ ' ${DST} = vec4(s[2].a, s[1].a, s[0].a, s[2].b - s[1].b + s[0].b);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[2];
+ c.color[1] = c.coords[1];
+ c.color[2] = c.coords[0];
+ });
+
+ LocalStructCase('struct_array_dynamic_index', "Struct array with dynamic indexing",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ '\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump int b;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s[3];\n' +
+ ' s[0] = S(${COORDS}.x, ui_zero);\n' +
+ ' s[1].a = ${COORDS}.y;\n' +
+ ' s[1].b = ui_one;\n' +
+ ' s[2] = S(${COORDS}.z, ui_two);\n' +
+ ' ${DST} = vec4(s[ui_two].a, s[ui_one].a, s[ui_zero].a, s[ui_two].b - s[ui_one].b + s[ui_zero].b);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[2];
+ c.color[1] = c.coords[1];
+ c.color[2] = c.coords[0];
+ });
+
+ LocalStructCase('nested_struct_array', "Nested struct array",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ 'uniform mediump float uf_two;\n' +
+ 'uniform mediump float uf_three;\n' +
+ 'uniform mediump float uf_four;\n' +
+ 'uniform mediump float uf_half;\n' +
+ 'uniform mediump float uf_third;\n' +
+ 'uniform mediump float uf_fourth;\n' +
+ '\n' +
+ 'struct T {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec2 b[2];\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b[3];\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s[2];\n' +
+ '\n' +
+ ' // S[0]\n' +
+ ' s[0].a = ${COORDS}.x;\n' +
+ ' s[0].b[0].a = uf_half;\n' +
+ ' s[0].b[0].b[0] = ${COORDS}.xy;\n' +
+ ' s[0].b[0].b[1] = ${COORDS}.zw;\n' +
+ ' s[0].b[1].a = uf_third;\n' +
+ ' s[0].b[1].b[0] = ${COORDS}.zw;\n' +
+ ' s[0].b[1].b[1] = ${COORDS}.xy;\n' +
+ ' s[0].b[2].a = uf_fourth;\n' +
+ ' s[0].b[2].b[0] = ${COORDS}.xz;\n' +
+ ' s[0].b[2].b[1] = ${COORDS}.yw;\n' +
+ ' s[0].c = ui_zero;\n' +
+ '\n' +
+ ' // S[1]\n' +
+ ' s[1].a = ${COORDS}.w;\n' +
+ ' s[1].b[0].a = uf_two;\n' +
+ ' s[1].b[0].b[0] = ${COORDS}.xx;\n' +
+ ' s[1].b[0].b[1] = ${COORDS}.yy;\n' +
+ ' s[1].b[1].a = uf_three;\n' +
+ ' s[1].b[1].b[0] = ${COORDS}.zz;\n' +
+ ' s[1].b[1].b[1] = ${COORDS}.ww;\n' +
+ ' s[1].b[2].a = uf_four;\n' +
+ ' s[1].b[2].b[0] = ${COORDS}.yx;\n' +
+ ' s[1].b[2].b[1] = ${COORDS}.wz;\n' +
+ ' s[1].c = ui_one;\n' +
+ '\n' +
+ ' mediump float r = (s[0].b[1].b[0].x + s[1].b[2].b[1].y) * s[0].b[0].a; // (z + z) * 0.5\n' +
+ ' mediump float g = s[1].b[0].b[0].y * s[0].b[2].a * s[1].b[2].a; // x * 0.25 * 4\n' +
+ ' mediump float b = (s[0].b[2].b[1].y + s[0].b[1].b[0].y + s[1].a) * s[0].b[1].a; // (w + w + w) * 0.333\n' +
+ ' mediump float a = float(s[0].c) + s[1].b[2].a - s[1].b[1].a; // 0 + 4.0 - 3.0\n' +
+ ' ${DST} = vec4(r, g, b, a);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[2];
+ c.color[1] = c.coords[0];
+ c.color[2] = c.coords[3];
+ });
+
+ LocalStructCase('nested_struct_array_dynamic_index', "Nested struct array with dynamic indexing",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ 'uniform mediump float uf_two;\n' +
+ 'uniform mediump float uf_three;\n' +
+ 'uniform mediump float uf_four;\n' +
+ 'uniform mediump float uf_half;\n' +
+ 'uniform mediump float uf_third;\n' +
+ 'uniform mediump float uf_fourth;\n' +
+ '\n' +
+ 'struct T {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec2 b[2];\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b[3];\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s[2];\n' +
+ '\n' +
+ ' // S[0]\n' +
+ ' s[0].a = ${COORDS}.x;\n' +
+ ' s[0].b[0].a = uf_half;\n' +
+ ' s[0].b[0].b[0] = ${COORDS}.xy;\n' +
+ ' s[0].b[0].b[1] = ${COORDS}.zw;\n' +
+ ' s[0].b[1].a = uf_third;\n' +
+ ' s[0].b[1].b[0] = ${COORDS}.zw;\n' +
+ ' s[0].b[1].b[1] = ${COORDS}.xy;\n' +
+ ' s[0].b[2].a = uf_fourth;\n' +
+ ' s[0].b[2].b[0] = ${COORDS}.xz;\n' +
+ ' s[0].b[2].b[1] = ${COORDS}.yw;\n' +
+ ' s[0].c = ui_zero;\n' +
+ '\n' +
+ ' // S[1]\n' +
+ ' s[1].a = ${COORDS}.w;\n' +
+ ' s[1].b[0].a = uf_two;\n' +
+ ' s[1].b[0].b[0] = ${COORDS}.xx;\n' +
+ ' s[1].b[0].b[1] = ${COORDS}.yy;\n' +
+ ' s[1].b[1].a = uf_three;\n' +
+ ' s[1].b[1].b[0] = ${COORDS}.zz;\n' +
+ ' s[1].b[1].b[1] = ${COORDS}.ww;\n' +
+ ' s[1].b[2].a = uf_four;\n' +
+ ' s[1].b[2].b[0] = ${COORDS}.yx;\n' +
+ ' s[1].b[2].b[1] = ${COORDS}.wz;\n' +
+ ' s[1].c = ui_one;\n' +
+ '\n' +
+ ' mediump float r = (s[0].b[ui_one].b[ui_one-1].x + s[ui_one].b[ui_two].b[ui_zero+1].y) * s[0].b[0].a; // (z + z) * 0.5\n' +
+ ' mediump float g = s[ui_two-1].b[ui_two-2].b[ui_zero].y * s[0].b[ui_two].a * s[ui_one].b[2].a; // x * 0.25 * 4\n' +
+ ' mediump float b = (s[ui_zero].b[ui_one+1].b[1].y + s[0].b[ui_one*ui_one].b[0].y + s[ui_one].a) * s[0].b[ui_two-ui_one].a; // (w + w + w) * 0.333\n' +
+ ' mediump float a = float(s[ui_zero].c) + s[ui_one-ui_zero].b[ui_two].a - s[ui_zero+ui_one].b[ui_two-ui_one].a; // 0 + 4.0 - 3.0\n' +
+ ' ${DST} = vec4(r, g, b, a);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[2];
+ c.color[1] = c.coords[0];
+ c.color[2] = c.coords[3];
+ });
+
+ LocalStructCase('parameter', "Struct as a function parameter",
+ '${HEADER}\n' +
+ 'uniform int ui_one;\n' +
+ '\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec3 b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'mediump vec4 myFunc (S s)\n' +
+ '{\n' +
+ ' return vec4(s.a, s.b.x, s.b.y, s.c);\n' +
+ '}\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s = S(${COORDS}.x, vec3(0.0), ui_one);\n' +
+ ' s.b = ${COORDS}.yzw;\n' +
+ ' ${DST} = myFunc(s);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[0];
+ c.color[1] = c.coords[1];
+ c.color[2] = c.coords[2];
+ });
+
+ LocalStructCase('parameter_nested', "Nested struct as a function parameter",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ '\n' +
+ 'struct T {\n' +
+ ' int a;\n' +
+ ' mediump vec2 b;\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'mediump vec4 myFunc (S s)\n' +
+ '{\n' +
+ ' return vec4(s.a, s.b.b, s.b.a + s.c);\n' +
+ '}\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);\n' +
+ ' s.b = T(ui_zero, ${COORDS}.yz);\n' +
+ ' ${DST} = myFunc(s);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[0];
+ c.color[1] = c.coords[1];
+ c.color[2] = c.coords[2];
+ });
+
+ LocalStructCase('return', "Struct as a return value",
+ '${HEADER}\n' +
+ 'uniform int ui_one;\n' +
+ '\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec3 b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'S myFunc (void)\n' +
+ '{\n' +
+ ' S s = S(${COORDS}.x, vec3(0.0), ui_one);\n' +
+ ' s.b = ${COORDS}.yzw;\n' +
+ ' return s;\n' +
+ '}\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s = myFunc();\n' +
+ ' ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[0];
+ c.color[1] = c.coords[1];
+ c.color[2] = c.coords[2];
+ });
+
+ LocalStructCase('return_nested', "Nested struct",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ '\n' +
+ 'struct T {\n' +
+ ' int a;\n' +
+ ' mediump vec2 b;\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'S myFunc (void)\n' +
+ '{\n' +
+ ' S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);\n' +
+ ' s.b = T(ui_zero, ${COORDS}.yz);\n' +
+ ' return s;\n' +
+ '}\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s = myFunc();\n' +
+ ' ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[0];
+ c.color[1] = c.coords[1];
+ c.color[2] = c.coords[2];
+ });
+
+ LocalStructCase('conditional_assignment', "Conditional struct assignment",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform mediump float uf_one;\n' +
+ '\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec3 b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);\n' +
+ ' if (uf_one > 0.0)\n' +
+ ' s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);\n' +
+ ' ${DST} = vec4(s.a, s.b.xy, s.c);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[3];
+ c.color[1] = c.coords[2];
+ c.color[2] = c.coords[1];
+ });
+
+ LocalStructCase('loop_assignment', "Struct assignment in loop",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ '\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec3 b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);\n' +
+ ' for (int i = 0; i < 3; i++)\n' +
+ ' {\n' +
+ ' if (i == 1)\n' +
+ ' s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);\n' +
+ ' }\n' +
+ ' ${DST} = vec4(s.a, s.b.xy, s.c);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[3];
+ c.color[1] = c.coords[2];
+ c.color[2] = c.coords[1];
+ });
+
+ LocalStructCase('dynamic_loop_assignment', "Struct assignment in loop",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_three;\n' +
+ '\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec3 b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);\n' +
+ ' for (int i = 0; i < ui_three; i++)\n' +
+ ' {\n' +
+ ' if (i == ui_one)\n' +
+ ' s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);\n' +
+ ' }\n' +
+ ' ${DST} = vec4(s.a, s.b.xy, s.c);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[3];
+ c.color[1] = c.coords[2];
+ c.color[2] = c.coords[1];
+ });
+
+ LocalStructCase('nested_conditional_assignment', "Conditional assignment of nested struct",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform mediump float uf_one;\n' +
+ '\n' +
+ 'struct T {\n' +
+ ' int a;\n' +
+ ' mediump vec2 b;\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);\n' +
+ ' if (uf_one > 0.0)\n' +
+ ' s.b = T(ui_zero, ${COORDS}.zw);\n' +
+ ' ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[0];
+ c.color[1] = c.coords[2];
+ c.color[2] = c.coords[3];
+ });
+
+ LocalStructCase('nested_loop_assignment', "Nested struct assignment in loop",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform mediump float uf_one;\n' +
+ '\n' +
+ 'struct T {\n' +
+ ' int a;\n' +
+ ' mediump vec2 b;\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);\n' +
+ ' for (int i = 0; i < 3; i++)\n' +
+ ' {\n' +
+ ' if (i == 1)\n' +
+ ' s.b = T(ui_zero, ${COORDS}.zw);\n' +
+ ' }\n' +
+ ' ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[0];
+ c.color[1] = c.coords[2];
+ c.color[2] = c.coords[3];
+ });
+
+ LocalStructCase('nested_dynamic_loop_assignment', "Nested struct assignment in dynamic loop",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_three;\n' +
+ 'uniform mediump float uf_one;\n' +
+ '\n' +
+ 'struct T {\n' +
+ ' int a;\n' +
+ ' mediump vec2 b;\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);\n' +
+ ' for (int i = 0; i < ui_three; i++)\n' +
+ ' {\n' +
+ ' if (i == ui_one)\n' +
+ ' s.b = T(ui_zero, ${COORDS}.zw);\n' +
+ ' }\n' +
+ ' ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[0];
+ c.color[1] = c.coords[2];
+ c.color[2] = c.coords[3];
+ });
+
+ LocalStructCase('loop_struct_array', "Struct array usage in loop",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ '\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump int b;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s[3];\n' +
+ ' s[0] = S(${COORDS}.x, ui_zero);\n' +
+ ' s[1].a = ${COORDS}.y;\n' +
+ ' s[1].b = -ui_one;\n' +
+ ' s[2] = S(${COORDS}.z, ui_two);\n' +
+ '\n' +
+ ' mediump float rgb[3];\n' +
+ ' int alpha = 0;\n' +
+ ' for (int i = 0; i < 3; i++)\n' +
+ ' {\n' +
+ ' rgb[i] = s[2-i].a;\n' +
+ ' alpha += s[i].b;\n' +
+ ' }\n' +
+ ' ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[2];
+ c.color[1] = c.coords[1];
+ c.color[2] = c.coords[0];
+ });
+
+ LocalStructCase('loop_nested_struct_array', "Nested struct array usage in loop",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ 'uniform mediump float uf_two;\n' +
+ 'uniform mediump float uf_three;\n' +
+ 'uniform mediump float uf_four;\n' +
+ 'uniform mediump float uf_half;\n' +
+ 'uniform mediump float uf_third;\n' +
+ 'uniform mediump float uf_fourth;\n' +
+ 'uniform mediump float uf_sixth;\n' +
+ '\n' +
+ 'struct T {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec2 b[2];\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b[3];\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s[2];\n' +
+ '\n' +
+ ' // S[0]\n' +
+ ' s[0].a = ${COORDS}.x;\n' +
+ ' s[0].b[0].a = uf_half;\n' +
+ ' s[0].b[0].b[0] = ${COORDS}.yx;\n' +
+ ' s[0].b[0].b[1] = ${COORDS}.zx;\n' +
+ ' s[0].b[1].a = uf_third;\n' +
+ ' s[0].b[1].b[0] = ${COORDS}.yy;\n' +
+ ' s[0].b[1].b[1] = ${COORDS}.wy;\n' +
+ ' s[0].b[2].a = uf_fourth;\n' +
+ ' s[0].b[2].b[0] = ${COORDS}.zx;\n' +
+ ' s[0].b[2].b[1] = ${COORDS}.zy;\n' +
+ ' s[0].c = ui_zero;\n' +
+ '\n' +
+ ' // S[1]\n' +
+ ' s[1].a = ${COORDS}.w;\n' +
+ ' s[1].b[0].a = uf_two;\n' +
+ ' s[1].b[0].b[0] = ${COORDS}.zx;\n' +
+ ' s[1].b[0].b[1] = ${COORDS}.zy;\n' +
+ ' s[1].b[1].a = uf_three;\n' +
+ ' s[1].b[1].b[0] = ${COORDS}.zz;\n' +
+ ' s[1].b[1].b[1] = ${COORDS}.ww;\n' +
+ ' s[1].b[2].a = uf_four;\n' +
+ ' s[1].b[2].b[0] = ${COORDS}.yx;\n' +
+ ' s[1].b[2].b[1] = ${COORDS}.wz;\n' +
+ ' s[1].c = ui_one;\n' +
+ '\n' +
+ ' mediump float r = 0.0; // (x*3 + y*3) / 6.0\n' +
+ ' mediump float g = 0.0; // (y*3 + z*3) / 6.0\n' +
+ ' mediump float b = 0.0; // (z*3 + w*3) / 6.0\n' +
+ ' mediump float a = 1.0;\n' +
+ ' for (int i = 0; i < 2; i++)\n' +
+ ' {\n' +
+ ' for (int j = 0; j < 3; j++)\n' +
+ ' {\n' +
+ ' r += s[0].b[j].b[i].y;\n' +
+ ' g += s[i].b[j].b[0].x;\n' +
+ ' b += s[i].b[j].b[1].x;\n' +
+ ' a *= s[i].b[j].a;\n' +
+ ' }\n' +
+ ' }\n' +
+ ' ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = (c.coords[0] + c.coords[1]) * 0.5;
+ c.color[1] = (c.coords[1] + c.coords[2]) * 0.5;
+ c.color[2] = (c.coords[2] + c.coords[3]) * 0.5;
+ });
+
+ LocalStructCase('dynamic_loop_struct_array', "Struct array usage in dynamic loop",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ 'uniform int ui_three;\n' +
+ '\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump int b;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s[3];\n' +
+ ' s[0] = S(${COORDS}.x, ui_zero);\n' +
+ ' s[1].a = ${COORDS}.y;\n' +
+ ' s[1].b = -ui_one;\n' +
+ ' s[2] = S(${COORDS}.z, ui_two);\n' +
+ '\n' +
+ ' mediump float rgb[3];\n' +
+ ' int alpha = 0;\n' +
+ ' for (int i = 0; i < ui_three; i++)\n' +
+ ' {\n' +
+ ' rgb[i] = s[2-i].a;\n' +
+ ' alpha += s[i].b;\n' +
+ ' }\n' +
+ ' ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = c.coords[2];
+ c.color[1] = c.coords[1];
+ c.color[2] = c.coords[0];
+ });
+
+ LocalStructCase('dynamic_loop_nested_struct_array', "Nested struct array usage in dynamic loop",
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ 'uniform int ui_three;\n' +
+ 'uniform mediump float uf_two;\n' +
+ 'uniform mediump float uf_three;\n' +
+ 'uniform mediump float uf_four;\n' +
+ 'uniform mediump float uf_half;\n' +
+ 'uniform mediump float uf_third;\n' +
+ 'uniform mediump float uf_fourth;\n' +
+ 'uniform mediump float uf_sixth;\n' +
+ '\n' +
+ 'struct T {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec2 b[2];\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b[3];\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S s[2];\n' +
+ '\n' +
+ ' // S[0]\n' +
+ ' s[0].a = ${COORDS}.x;\n' +
+ ' s[0].b[0].a = uf_half;\n' +
+ ' s[0].b[0].b[0] = ${COORDS}.yx;\n' +
+ ' s[0].b[0].b[1] = ${COORDS}.zx;\n' +
+ ' s[0].b[1].a = uf_third;\n' +
+ ' s[0].b[1].b[0] = ${COORDS}.yy;\n' +
+ ' s[0].b[1].b[1] = ${COORDS}.wy;\n' +
+ ' s[0].b[2].a = uf_fourth;\n' +
+ ' s[0].b[2].b[0] = ${COORDS}.zx;\n' +
+ ' s[0].b[2].b[1] = ${COORDS}.zy;\n' +
+ ' s[0].c = ui_zero;\n' +
+ '\n' +
+ ' // S[1]\n' +
+ ' s[1].a = ${COORDS}.w;\n' +
+ ' s[1].b[0].a = uf_two;\n' +
+ ' s[1].b[0].b[0] = ${COORDS}.zx;\n' +
+ ' s[1].b[0].b[1] = ${COORDS}.zy;\n' +
+ ' s[1].b[1].a = uf_three;\n' +
+ ' s[1].b[1].b[0] = ${COORDS}.zz;\n' +
+ ' s[1].b[1].b[1] = ${COORDS}.ww;\n' +
+ ' s[1].b[2].a = uf_four;\n' +
+ ' s[1].b[2].b[0] = ${COORDS}.yx;\n' +
+ ' s[1].b[2].b[1] = ${COORDS}.wz;\n' +
+ ' s[1].c = ui_one;\n' +
+ '\n' +
+ ' mediump float r = 0.0; // (x*3 + y*3) / 6.0\n' +
+ ' mediump float g = 0.0; // (y*3 + z*3) / 6.0\n' +
+ ' mediump float b = 0.0; // (z*3 + w*3) / 6.0\n' +
+ ' mediump float a = 1.0;\n' +
+ ' for (int i = 0; i < ui_two; i++)\n' +
+ ' {\n' +
+ ' for (int j = 0; j < ui_three; j++)\n' +
+ ' {\n' +
+ ' r += s[0].b[j].b[i].y;\n' +
+ ' g += s[i].b[j].b[0].x;\n' +
+ ' b += s[i].b[j].b[1].x;\n' +
+ ' a *= s[i].b[j].a;\n' +
+ ' }\n' +
+ ' }\n' +
+ ' ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ c.color[0] = (c.coords[0] + c.coords[1]) * 0.5;
+ c.color[1] = (c.coords[1] + c.coords[2]) * 0.5;
+ c.color[2] = (c.coords[2] + c.coords[3]) * 0.5;
+ });
+
+ LocalStructCase('basic_equal', "Basic struct equality",
+ '${HEADER}\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ '\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec3 b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S a = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);\n' +
+ ' S b = S(floor(${COORDS}.x+0.5), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);\n' +
+ ' S c = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one);\n' +
+ ' S d = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_two);\n' +
+ ' ${DST} = vec4(0.0, 0.0, 0.0, 1.0);\n' +
+ ' if (a == b) ${DST}.x = 1.0;\n' +
+ ' if (a == c) ${DST}.y = 1.0;\n' +
+ ' if (a == d) ${DST}.z = 1.0;\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ if (Math.floor(c.coords[0]) === Math.floor(c.coords[0] + 0.5))
+ c.color[0] = 1.0;
+ if (Math.floor(c.coords[1]) === Math.floor(c.coords[1] + 0.5))
+ c.color[1] = 1.0;
+ });
+
+ LocalStructCase('basic_not_equal', "Basic struct equality",
+ '${HEADER}\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ '\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec3 b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S a = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);\n' +
+ ' S b = S(floor(${COORDS}.x+0.5), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);\n' +
+ ' S c = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one);\n' +
+ ' S d = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_two);\n' +
+ ' ${DST} = vec4(0.0, 0.0, 0.0, 1.0);\n' +
+ ' if (a != b) ${DST}.x = 1.0;\n' +
+ ' if (a != c) ${DST}.y = 1.0;\n' +
+ ' if (a != d) ${DST}.z = 1.0;\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ if (Math.floor(c.coords[0]) != Math.floor(c.coords[0] + 0.5))
+ c.color[0] = 1.0;
+ if (Math.floor(c.coords[1]) != Math.floor(c.coords[1] + 0.5))
+ c.color[1] = 1.0;
+ c.color[2] = 1.0;
+ });
+
+ LocalStructCase('nested_equal', "Nested struct struct equality",
+ '${HEADER}\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ '\n' +
+ 'struct T {\n' +
+ ' mediump vec3 a;\n' +
+ ' int b;\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S a = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);\n' +
+ ' S b = S(floor(${COORDS}.x+0.5), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);\n' +
+ ' S c = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one), 1);\n' +
+ ' S d = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_two), 1);\n' +
+ ' ${DST} = vec4(0.0, 0.0, 0.0, 1.0);\n' +
+ ' if (a == b) ${DST}.x = 1.0;\n' +
+ ' if (a == c) ${DST}.y = 1.0;\n' +
+ ' if (a == d) ${DST}.z = 1.0;\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ if (Math.floor(c.coords[0]) == Math.floor(c.coords[0] + 0.5))
+ c.color[0] = 1.0;
+ if (Math.floor(c.coords[1]) == Math.floor(c.coords[1] + 0.5))
+ c.color[1] = 1.0;
+ });
+
+ LocalStructCase('nested_not_equal', "Nested struct struct equality",
+ '${HEADER}\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ '\n' +
+ 'struct T {\n' +
+ ' mediump vec3 a;\n' +
+ ' int b;\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S a = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);\n' +
+ ' S b = S(floor(${COORDS}.x+0.5), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);\n' +
+ ' S c = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one), 1);\n' +
+ ' S d = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_two), 1);\n' +
+ ' ${DST} = vec4(0.0, 0.0, 0.0, 1.0);\n' +
+ ' if (a != b) ${DST}.x = 1.0;\n' +
+ ' if (a != c) ${DST}.y = 1.0;\n' +
+ ' if (a != d) ${DST}.z = 1.0;\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}\n',
+ function(c) {
+ if (Math.floor(c.coords[0]) != Math.floor(c.coords[0] + 0.5))
+ c.color[0] = 1.0;
+ if (Math.floor(c.coords[1]) != Math.floor(c.coords[1] + 0.5))
+ c.color[1] = 1.0;
+ c.color[2] = 1.0;
+ });
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderStructTests.UniformStructTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'uniform', 'Uniform structs');
+ this.makeExecutable();
+ };
+
+ es3fShaderStructTests.UniformStructTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderStructTests.UniformStructTests.prototype.constructor = es3fShaderStructTests.UniformStructTests;
+
+ /**
+ * @param {WebGLProgram} programID
+ * @param {string} name
+ * @param {Array<number>} vec
+ */
+ es3fShaderStructTests.setUniform2fv = function(programID, name, vec) {
+ /** @type {WebGLUniformLocation} */ var loc = gl.getUniformLocation(programID, name);
+ gl.uniform2fv(loc, vec);
+ };
+
+ /**
+ * @param {WebGLProgram} programID
+ * @param {string} name
+ * @param {Array<number>} vec
+ */
+ es3fShaderStructTests.setUniform3fv = function(programID, name, vec) {
+ /** @type {WebGLUniformLocation} */ var loc = gl.getUniformLocation(programID, name);
+ gl.uniform3fv(loc, vec);
+ };
+
+ /**
+ * @param {WebGLProgram} programID
+ * @param {string} name
+ * @param {number} value
+ */
+ es3fShaderStructTests.setUniform1i = function(programID, name, value) {
+ /** @type {WebGLUniformLocation} */ var loc = gl.getUniformLocation(programID, name);
+ gl.uniform1i(loc, value);
+ };
+
+ /**
+ * @param {WebGLProgram} programID
+ * @param {string} name
+ * @param {number} value
+ */
+ es3fShaderStructTests.setUniform1f = function(programID, name, value) {
+ /** @type {WebGLUniformLocation} */ var loc = gl.getUniformLocation(programID, name);
+ gl.uniform1f(loc, value);
+ };
+
+ /**
+ * @param {WebGLProgram} programID
+ * @param {string} name
+ * @param {Array<number>} vec
+ */
+ es3fShaderStructTests.setUniform1fv = function(programID, name, vec) {
+ /** @type {WebGLUniformLocation} */ var loc = gl.getUniformLocation(programID, name);
+ gl.uniform1fv(loc, vec);
+ };
+
+ es3fShaderStructTests.UniformStructTests.prototype.init = function() {
+ var currentCtx = this;
+ function UniformStructCase(name, description, textures, shaderSrc, setUniformsFunc, evalFunc) {
+ currentCtx.addChild(es3fShaderStructTests.ShaderStructCase.createStructCase(name + "_vertex", description, true, textures, evalFunc, setUniformsFunc, shaderSrc));
+ currentCtx.addChild(es3fShaderStructTests.ShaderStructCase.createStructCase(name + "_fragment", description, false, textures, evalFunc, setUniformsFunc, shaderSrc));
+ }
+
+ UniformStructCase('basic', "Basic struct usage", false,
+ '${HEADER}\n' +
+ 'uniform int ui_one;\n' +
+ '' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec3 b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ 'uniform S s;\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords) {
+ es3fShaderStructTests.setUniform1f(programID, "s.a", constCoords[0]);
+ es3fShaderStructTests.setUniform3fv(programID, "s.b", deMath.swizzle(constCoords, [1, 2, 3]));
+ es3fShaderStructTests.setUniform1i(programID, "s.c", 1);
+ },
+ function(c) {
+ c.color[0] = c.constCoords[0];
+ c.color[1] = c.constCoords[1];
+ c.color[2] = c.constCoords[2];
+ });
+
+ UniformStructCase('nested', "Nested struct", false,
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ '' +
+ 'struct T {\n' +
+ ' int a;\n' +
+ ' mediump vec2 b;\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ 'uniform S s;\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords) {
+ es3fShaderStructTests.setUniform1f(programID, "s.a", constCoords[0]);
+ es3fShaderStructTests.setUniform1i(programID, "s.b.a", 0);
+ es3fShaderStructTests.setUniform2fv(programID, "s.b.b", deMath.swizzle(constCoords, [1,2]));
+ es3fShaderStructTests.setUniform1i(programID, "s.c", 1);
+ },
+ function(c) {
+ c.color[0] = c.constCoords[0];
+ c.color[1] = c.constCoords[1];
+ c.color[2] = c.constCoords[2];
+ });
+
+ UniformStructCase('array_member', "Struct with array member", false,
+ '${HEADER}\n' +
+ 'uniform int ui_one;\n' +
+ '' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump float b[3];\n' +
+ ' int c;\n' +
+ '};\n' +
+ 'uniform S s;\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${DST} = vec4(s.a, s.b[0], s.b[1], s.c);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords){
+ es3fShaderStructTests.setUniform1f(programID, "s.a", constCoords[3]);
+ es3fShaderStructTests.setUniform1i(programID, "s.c", 1);
+
+ /** @type {Array<number>} */ var b = [];
+ b[0] = constCoords[2];
+ b[1] = constCoords[1];
+ b[2] = constCoords[0];
+ es3fShaderStructTests.setUniform1fv(programID, "s.b", b);
+ },
+ function(c) {
+ c.color[0] = c.constCoords[3];
+ c.color[1] = c.constCoords[2];
+ c.color[2] = c.constCoords[1];
+ });
+
+ UniformStructCase('array_member_dynamic_index', "Struct with array member, dynamic indexing", false,
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ '' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump float b[3];\n' +
+ ' int c;\n' +
+ '};\n' +
+ 'uniform S s;\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${DST} = vec4(s.b[ui_one], s.b[ui_zero], s.b[ui_two], s.c);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords) {
+ es3fShaderStructTests.setUniform1f(programID, "s.a", constCoords[3]);
+ es3fShaderStructTests.setUniform1i(programID, "s.c", 1);
+
+ /** @type {Array<number>} */ var b = [];
+ b[0] = constCoords[2];
+ b[1] = constCoords[1];
+ b[2] = constCoords[0];
+ es3fShaderStructTests.setUniform1fv(programID, "s.b", b);
+ },
+ function(c) {
+ c.color[0] = c.constCoords[1];
+ c.color[1] = c.constCoords[2];
+ c.color[2] = c.constCoords[0];
+ });
+
+ UniformStructCase('struct_array', "Struct array", false,
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ '' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump int b;\n' +
+ '};\n' +
+ 'uniform S s[3];\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${DST} = vec4(s[2].a, s[1].a, s[0].a, s[2].b - s[1].b + s[0].b);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords) {
+ es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
+ es3fShaderStructTests.setUniform1i(programID, "s[0].b", 0);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[1]);
+ es3fShaderStructTests.setUniform1i(programID, "s[1].b", 1);
+ es3fShaderStructTests.setUniform1f(programID, "s[2].a", constCoords[2]);
+ es3fShaderStructTests.setUniform1i(programID, "s[2].b", 2);
+ },
+ function(c) {
+ c.color[0] = c.constCoords[2];
+ c.color[1] = c.constCoords[1];
+ c.color[2] = c.constCoords[0];
+ });
+
+ UniformStructCase('struct_array_dynamic_index', "Struct array with dynamic indexing", false,
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ '' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump int b;\n' +
+ '};\n' +
+ 'uniform S s[3];\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${DST} = vec4(s[ui_two].a, s[ui_one].a, s[ui_zero].a, s[ui_two].b - s[ui_one].b + s[ui_zero].b);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords) {
+ es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
+ es3fShaderStructTests.setUniform1i(programID, "s[0].b", 0);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[1]);
+ es3fShaderStructTests.setUniform1i(programID, "s[1].b", 1);
+ es3fShaderStructTests.setUniform1f(programID, "s[2].a", constCoords[2]);
+ es3fShaderStructTests.setUniform1i(programID, "s[2].b", 2);
+ },
+ function(c) {
+ c.color[0] = c.constCoords[2];
+ c.color[1] = c.constCoords[1];
+ c.color[2] = c.constCoords[0];
+ });
+
+ UniformStructCase('nested_struct_array', "Nested struct array", false,
+ '${HEADER}\n' +
+ 'struct T {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec2 b[2];\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b[3];\n' +
+ ' int c;\n' +
+ '};\n' +
+ 'uniform S s[2];\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' mediump float r = (s[0].b[1].b[0].x + s[1].b[2].b[1].y) * s[0].b[0].a; // (z + z) * 0.5\n' +
+ ' mediump float g = s[1].b[0].b[0].y * s[0].b[2].a * s[1].b[2].a; // x * 0.25 * 4\n' +
+ ' mediump float b = (s[0].b[2].b[1].y + s[0].b[1].b[0].y + s[1].a) * s[0].b[1].a; // (w + w + w) * 0.333\n' +
+ ' mediump float a = float(s[0].c) + s[1].b[2].a - s[1].b[1].a; // 0 + 4.0 - 3.0\n' +
+ ' ${DST} = vec4(r, g, b, a);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords) {
+ /** @type {Array<number>} */ var arr = [];
+
+ es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
+ arr = deMath.swizzle(constCoords, [0,1,2,3]);
+ es3fShaderStructTests.setUniform1f(programID, "s[0].b[0].a", 0.5);
+ es3fShaderStructTests.setUniform2fv(programID, "s[0].b[0].b", arr);
+ arr = deMath.swizzle(constCoords, [2,3,0,1]);
+ es3fShaderStructTests.setUniform1f(programID, "s[0].b[1].a", 1.0/3.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[0].b[1].b", arr);
+ arr = deMath.swizzle(constCoords, [0,2,1,3]);
+ es3fShaderStructTests.setUniform1f(programID, "s[0].b[2].a", 1.0/4.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[0].b[2].b", arr);
+ es3fShaderStructTests.setUniform1i(programID, "s[0].c", 0);
+
+ es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[3]);
+ arr = deMath.swizzle(constCoords, [0,0,1,1]);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].b[0].a", 2.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[1].b[0].b", arr);
+ arr = deMath.swizzle(constCoords, [2,2,3,3]);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].b[1].a", 3.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[1].b[1].b", arr);
+ arr = deMath.swizzle(constCoords, [1,0,3,2]);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].b[2].a", 4.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[1].b[2].b", arr);
+ es3fShaderStructTests.setUniform1i(programID, "s[1].c", 1);
+ },
+ function(c) {
+ c.color[0] = c.constCoords[2];
+ c.color[1] = c.constCoords[0];
+ c.color[2] = c.constCoords[3];
+ });
+
+ UniformStructCase('nested_struct_array_dynamic_index', "Nested struct array with dynamic indexing", false,
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ '' +
+ 'struct T {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec2 b[2];\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b[3];\n' +
+ ' int c;\n' +
+ '};\n' +
+ 'uniform S s[2];\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' mediump float r = (s[0].b[ui_one].b[ui_one-1].x + s[ui_one].b[ui_two].b[ui_zero+1].y) * s[0].b[0].a; // (z + z) * 0.5\n' +
+ ' mediump float g = s[ui_two-1].b[ui_two-2].b[ui_zero].y * s[0].b[ui_two].a * s[ui_one].b[2].a; // x * 0.25 * 4\n' +
+ ' mediump float b = (s[ui_zero].b[ui_one+1].b[1].y + s[0].b[ui_one*ui_one].b[0].y + s[ui_one].a) * s[0].b[ui_two-ui_one].a; // (w + w + w) * 0.333\n' +
+ ' mediump float a = float(s[ui_zero].c) + s[ui_one-ui_zero].b[ui_two].a - s[ui_zero+ui_one].b[ui_two-ui_one].a; // 0 + 4.0 - 3.0\n' +
+ ' ${DST} = vec4(r, g, b, a);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords){
+ /** @type {Array<number>} */ var arr = [];
+
+ es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
+ arr = constCoords;
+ es3fShaderStructTests.setUniform1f(programID, "s[0].b[0].a", 0.5);
+ es3fShaderStructTests.setUniform2fv(programID, "s[0].b[0].b", arr);
+ arr = deMath.swizzle(constCoords, [2,3,0,1]);
+ es3fShaderStructTests.setUniform1f(programID, "s[0].b[1].a", 1.0/3.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[0].b[1].b", arr);
+ arr = deMath.swizzle(constCoords, [0,2,1,3]);
+ es3fShaderStructTests.setUniform1f(programID, "s[0].b[2].a", 1.0/4.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[0].b[2].b", arr);
+ es3fShaderStructTests.setUniform1i(programID, "s[0].c", 0);
+
+ es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[3]);
+ arr = deMath.swizzle(constCoords, [0,0,1,1]);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].b[0].a", 2.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[1].b[0].b", arr);
+ arr = deMath.swizzle(constCoords, [2,2,3,3]);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].b[1].a", 3.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[1].b[1].b", arr);
+ arr = deMath.swizzle(constCoords, [1,0,3,2]);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].b[2].a", 4.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[1].b[2].b", arr);
+ es3fShaderStructTests.setUniform1i(programID, "s[1].c", 1);
+ },
+ function(c) {
+ c.color[0] = c.constCoords[2];
+ c.color[1] = c.constCoords[0];
+ c.color[2] = c.constCoords[3];
+ });
+
+ UniformStructCase('loop_struct_array', "Struct array usage in loop", false,
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ '' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump int b;\n' +
+ '};\n' +
+ 'uniform S s[3];\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' mediump float rgb[3];\n' +
+ ' int alpha = 0;\n' +
+ ' for (int i = 0; i < 3; i++)\n' +
+ ' {\n' +
+ ' rgb[i] = s[2-i].a;\n' +
+ ' alpha += s[i].b;\n' +
+ ' }\n' +
+ ' ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords) {
+ es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
+ es3fShaderStructTests.setUniform1i(programID, "s[0].b", 0);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[1]);
+ es3fShaderStructTests.setUniform1i(programID, "s[1].b", -1);
+ es3fShaderStructTests.setUniform1f(programID, "s[2].a", constCoords[2]);
+ es3fShaderStructTests.setUniform1i(programID, "s[2].b", 2);
+ },
+ function(c) {
+ c.color[0] = c.constCoords[2];
+ c.color[1] = c.constCoords[1];
+ c.color[2] = c.constCoords[0];
+ });
+
+ UniformStructCase('loop_nested_struct_array', "Nested struct array usage in loop", false,
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ 'uniform mediump float uf_two;\n' +
+ 'uniform mediump float uf_three;\n' +
+ 'uniform mediump float uf_four;\n' +
+ 'uniform mediump float uf_half;\n' +
+ 'uniform mediump float uf_third;\n' +
+ 'uniform mediump float uf_fourth;\n' +
+ 'uniform mediump float uf_sixth;\n' +
+ '' +
+ 'struct T {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec2 b[2];\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b[3];\n' +
+ ' int c;\n' +
+ '};\n' +
+ 'uniform S s[2];\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' mediump float r = 0.0; // (x*3 + y*3) / 6.0\n' +
+ ' mediump float g = 0.0; // (y*3 + z*3) / 6.0\n' +
+ ' mediump float b = 0.0; // (z*3 + w*3) / 6.0\n' +
+ ' mediump float a = 1.0;\n' +
+ ' for (int i = 0; i < 2; i++)\n' +
+ ' {\n' +
+ ' for (int j = 0; j < 3; j++)\n' +
+ ' {\n' +
+ ' r += s[0].b[j].b[i].y;\n' +
+ ' g += s[i].b[j].b[0].x;\n' +
+ ' b += s[i].b[j].b[1].x;\n' +
+ ' a *= s[i].b[j].a;\n' +
+ ' }\n' +
+ ' }\n' +
+ ' ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords) {
+ /** @type {Array<number>} */ var arr = [];
+
+ es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
+ arr = deMath.swizzle(constCoords, [1,0,2,0]);
+ es3fShaderStructTests.setUniform1f(programID, "s[0].b[0].a", 0.5);
+ es3fShaderStructTests.setUniform2fv(programID, "s[0].b[0].b", arr);
+ arr = deMath.swizzle(constCoords, [1,1,3,1]);
+ es3fShaderStructTests.setUniform1f(programID, "s[0].b[1].a", 1.0/3.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[0].b[1].b", arr);
+ arr = deMath.swizzle(constCoords, [2,1,2,1]);
+ es3fShaderStructTests.setUniform1f(programID, "s[0].b[2].a", 1.0/4.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[0].b[2].b", arr);
+ es3fShaderStructTests.setUniform1i(programID, "s[0].c", 0);
+
+ es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[3]);
+ arr = deMath.swizzle(constCoords, [2,0,2,1]);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].b[0].a", 2.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[1].b[0].b", arr);
+ arr = deMath.swizzle(constCoords, [2,2,3,3]);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].b[1].a", 3.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[1].b[1].b", arr);
+ arr = deMath.swizzle(constCoords, [1,0,3,2]);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].b[2].a", 4.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[1].b[2].b", arr);
+ es3fShaderStructTests.setUniform1i(programID, "s[1].c", 1);
+ },
+ function(c) {
+ c.color[0] = (c.constCoords[0] + c.constCoords[1]) * 0.5;
+ c.color[1] = (c.constCoords[1] + c.constCoords[2]) * 0.5;
+ c.color[2] = (c.constCoords[2] + c.constCoords[3]) * 0.5;
+ });
+
+ UniformStructCase('dynamic_loop_struct_array', "Struct array usage in dynamic loop", false,
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ 'uniform int ui_three;\n' +
+ '' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump int b;\n' +
+ '};\n' +
+ 'uniform S s[3];\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' mediump float rgb[3];\n' +
+ ' int alpha = 0;\n' +
+ ' for (int i = 0; i < ui_three; i++)\n' +
+ ' {\n' +
+ ' rgb[i] = s[2-i].a;\n' +
+ ' alpha += s[i].b;\n' +
+ ' }\n' +
+ ' ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords) {
+ es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
+ es3fShaderStructTests.setUniform1i(programID, "s[0].b", 0);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[1]);
+ es3fShaderStructTests.setUniform1i(programID, "s[1].b", -1);
+ es3fShaderStructTests.setUniform1f(programID, "s[2].a", constCoords[2]);
+ es3fShaderStructTests.setUniform1i(programID, "s[2].b", 2);
+ },
+ function(c) {
+ c.color[0] = c.constCoords[2];
+ c.color[1] = c.constCoords[1];
+ c.color[2] = c.constCoords[0];
+ });
+
+ UniformStructCase('dynamic_loop_nested_struct_array', "Nested struct array usage in dynamic loop", false,
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ 'uniform int ui_two;\n' +
+ 'uniform int ui_three;\n' +
+ 'uniform mediump float uf_two;\n' +
+ 'uniform mediump float uf_three;\n' +
+ 'uniform mediump float uf_four;\n' +
+ 'uniform mediump float uf_half;\n' +
+ 'uniform mediump float uf_third;\n' +
+ 'uniform mediump float uf_fourth;\n' +
+ 'uniform mediump float uf_sixth;\n' +
+ '' +
+ 'struct T {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec2 b[2];\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b[3];\n' +
+ ' int c;\n' +
+ '};\n' +
+ 'uniform S s[2];\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' mediump float r = 0.0; // (x*3 + y*3) / 6.0\n' +
+ ' mediump float g = 0.0; // (y*3 + z*3) / 6.0\n' +
+ ' mediump float b = 0.0; // (z*3 + w*3) / 6.0\n' +
+ ' mediump float a = 1.0;\n' +
+ ' for (int i = 0; i < ui_two; i++)\n' +
+ ' {\n' +
+ ' for (int j = 0; j < ui_three; j++)\n' +
+ ' {\n' +
+ ' r += s[0].b[j].b[i].y;\n' +
+ ' g += s[i].b[j].b[0].x;\n' +
+ ' b += s[i].b[j].b[1].x;\n' +
+ ' a *= s[i].b[j].a;\n' +
+ ' }\n' +
+ ' }\n' +
+ ' ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords) {
+ /** @type {Array<number>} */ var arr = [];
+
+ es3fShaderStructTests.setUniform1f(programID, "s[0].a", constCoords[0]);
+ arr = deMath.swizzle(constCoords, [1,0,2,0]);
+ es3fShaderStructTests.setUniform1f(programID, "s[0].b[0].a", 0.5);
+ es3fShaderStructTests.setUniform2fv(programID, "s[0].b[0].b", arr);
+ arr = deMath.swizzle(constCoords, [1,1,3,1]);
+ es3fShaderStructTests.setUniform1f(programID, "s[0].b[1].a", 1.0/3.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[0].b[1].b", arr);
+ arr = deMath.swizzle(constCoords, [2,1,2,1]);
+ es3fShaderStructTests.setUniform1f(programID, "s[0].b[2].a", 1.0/4.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[0].b[2].b", arr);
+ es3fShaderStructTests.setUniform1i(programID, "s[0].c", 0);
+
+ es3fShaderStructTests.setUniform1f(programID, "s[1].a", constCoords[3]);
+ arr = deMath.swizzle(constCoords, [2,0,2,1]);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].b[0].a", 2.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[1].b[0].b", arr);
+ arr = deMath.swizzle(constCoords, [2,2,3,3]);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].b[1].a", 3.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[1].b[1].b", arr);
+ arr = deMath.swizzle(constCoords, [1,0,3,2]);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].b[2].a", 4.0);
+ es3fShaderStructTests.setUniform2fv(programID, "s[1].b[2].b", arr);
+ es3fShaderStructTests.setUniform1i(programID, "s[1].c", 1);
+ },
+ function(c) {
+ c.color[0] = (c.constCoords[0] + c.constCoords[1]) * 0.5;
+ c.color[1] = (c.constCoords[1] + c.constCoords[2]) * 0.5;
+ c.color[2] = (c.constCoords[2] + c.constCoords[3]) * 0.5;
+ });
+
+ UniformStructCase('sampler', "Sampler in struct", true,
+ '${HEADER}\n' +
+ 'uniform int ui_one;\n' +
+ '' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec3 b;\n' +
+ ' sampler2D c;\n' +
+ '};\n' +
+ 'uniform S s;\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${DST} = vec4(texture(s.c, ${COORDS}.xy * s.b.xy + s.b.z).rgb, s.a);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords) {
+ es3fShaderStructTests.setUniform1f(programID, "s.a", 1.0);
+ es3fShaderStructTests.setUniform3fv(programID, "s.b", [0.25, 0.25, 0.5]);
+ es3fShaderStructTests.setUniform1i(programID, "s.c", 0);
+ },
+ function(c) {
+ var tex2d = c.texture2D(es3fShaderStructTests.TEXTURE_BRICK, deMath.addScalar(deMath.scale(deMath.swizzle(c.coords, [0,1]), 0.25), 0.5))
+
+ c.color[0] = tex2d[0];
+ c.color[1] = tex2d[1];
+ c.color[2] = tex2d[2];
+ });
+
+ UniformStructCase('sampler_nested', "Sampler in nested struct", true,
+ '${HEADER}\n' +
+ 'uniform int ui_zero;\n' +
+ 'uniform int ui_one;\n' +
+ '' +
+ 'struct T {\n' +
+ ' sampler2D a;\n' +
+ ' mediump vec2 b;\n' +
+ '};\n' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' T b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ 'uniform S s;\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${DST} = vec4(texture(s.b.a, ${COORDS}.xy * s.b.b + s.a).rgb, s.c);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords) {
+ es3fShaderStructTests.setUniform1f(programID, "s.a", 0.5);
+ es3fShaderStructTests.setUniform1i(programID, "s.b.a", 0);
+ es3fShaderStructTests.setUniform2fv(programID, "s.b.b", [0.25, 0.25]);
+ es3fShaderStructTests.setUniform1i(programID, "s.c", 1);
+ },
+ function(c) {
+ var tex2d = c.texture2D(es3fShaderStructTests.TEXTURE_BRICK, deMath.addScalar(deMath.scale(deMath.swizzle(c.coords, [0,1]), 0.25), 0.5));
+ c.color[0] = tex2d[0];
+ c.color[1] = tex2d[1];
+ c.color[2] = tex2d[2];
+ });
+
+ UniformStructCase('sampler_array', "Sampler in struct array", true,
+ '${HEADER}\n' +
+ 'uniform int ui_one;\n' +
+ '' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec3 b;\n' +
+ ' sampler2D c;\n' +
+ '};\n' +
+ 'uniform S s[2];\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' ${DST} = vec4(texture(s[1].c, ${COORDS}.xy * s[0].b.xy + s[1].b.z).rgb, s[0].a);\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords) {
+ es3fShaderStructTests.setUniform1f(programID, "s[0].a", 1.0);
+ es3fShaderStructTests.setUniform3fv(programID, "s[0].b", [0.25, 0.25, 0.25]);
+ es3fShaderStructTests.setUniform1i(programID, "s[0].c", 1);
+ es3fShaderStructTests.setUniform1f(programID, "s[1].a", 0.0);
+ es3fShaderStructTests.setUniform3fv(programID, "s[1].b", [0.5, 0.5, 0.5]);
+ es3fShaderStructTests.setUniform1i(programID, "s[1].c", 0);
+ },
+ function(c) {
+ var tex2d = c.texture2D(es3fShaderStructTests.TEXTURE_BRICK, deMath.addScalar(deMath.scale(deMath.swizzle(c.coords, [0,1]), 0.25), 0.5));
+ c.color[0] = tex2d[0];
+ c.color[1] = tex2d[1];
+ c.color[2] = tex2d[2];
+ });
+
+ UniformStructCase('equal', "Struct equality", false,
+ '${HEADER}\n' +
+ 'uniform mediump float uf_one;\n' +
+ 'uniform int ui_two;\n' +
+ '' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec3 b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ 'uniform S a;\n' +
+ 'uniform S b;\n' +
+ 'uniform S c;\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S d = S(uf_one, vec3(0.0, floor(${COORDS}.y+1.0), 2.0), ui_two);\n' +
+ ' ${DST} = vec4(0.0, 0.0, 0.0, 1.0);\n' +
+ ' if (a == b) ${DST}.x = 1.0;\n' +
+ ' if (a == c) ${DST}.y = 1.0;\n' +
+ ' if (a == d) ${DST}.z = 1.0;\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords) {
+ es3fShaderStructTests.setUniform1f(programID, "a.a", 1.0);
+ es3fShaderStructTests.setUniform3fv(programID, "a.b", [0.0, 1.0, 2.0]);
+ es3fShaderStructTests.setUniform1i(programID, "a.c", 2);
+ es3fShaderStructTests.setUniform1f(programID, "b.a", 1.0);
+ es3fShaderStructTests.setUniform3fv(programID, "b.b", [0.0, 1.0, 2.0]);
+ es3fShaderStructTests.setUniform1i(programID, "b.c", 2);
+ es3fShaderStructTests.setUniform1f(programID, "c.a", 1.0);
+ es3fShaderStructTests.setUniform3fv(programID, "c.b", [0.0, 1.1, 2.0]);
+ es3fShaderStructTests.setUniform1i(programID, "c.c", 2);
+ },
+ function(c) {
+ c.color[0] = 1.0;
+ c.color[1] = 0.0;
+ if (Math.floor(c.coords[1] + 1.0) == Math.floor(1.1))
+ c.color[2] = 1.0;
+ });
+
+ UniformStructCase('not_equal', "Struct equality", false,
+ '${HEADER}\n' +
+ 'uniform mediump float uf_one;\n' +
+ 'uniform int ui_two;\n' +
+ '' +
+ 'struct S {\n' +
+ ' mediump float a;\n' +
+ ' mediump vec3 b;\n' +
+ ' int c;\n' +
+ '};\n' +
+ 'uniform S a;\n' +
+ 'uniform S b;\n' +
+ 'uniform S c;\n' +
+ '' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' S d = S(uf_one, vec3(0.0, floor(${COORDS}.y+1.0), 2.0), ui_two);\n' +
+ ' ${DST} = vec4(0.0, 0.0, 0.0, 1.0);\n' +
+ ' if (a != b) ${DST}.x = 1.0;\n' +
+ ' if (a != c) ${DST}.y = 1.0;\n' +
+ ' if (a != d) ${DST}.z = 1.0;\n' +
+ ' ${ASSIGN_POS}\n' +
+ '}',
+ function(programID, constCoords) {
+ es3fShaderStructTests.setUniform1f(programID, "a.a", 1.0);
+ es3fShaderStructTests.setUniform3fv(programID, "a.b", [0.0, 1.0, 2.0]);
+ es3fShaderStructTests.setUniform1i(programID, "a.c", 2);
+ es3fShaderStructTests.setUniform1f(programID, "b.a", 1.0);
+ es3fShaderStructTests.setUniform3fv(programID, "b.b", [0.0, 1.0, 2.0]);
+ es3fShaderStructTests.setUniform1i(programID, "b.c", 2);
+ es3fShaderStructTests.setUniform1f(programID, "c.a", 1.0);
+ es3fShaderStructTests.setUniform3fv(programID, "c.b", [0.0, 1.1, 2.0]);
+ es3fShaderStructTests.setUniform1i(programID, "c.c", 2);
+ },
+ function(c) {
+ c.color[0] = 0.0;
+ c.color[1] = 1.0;
+ if (Math.floor(c.coords[1] + 1.0) != Math.floor(1.1))
+ c.color[2] = 1.0;
+ });
+
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderStructTests.ShaderStructTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'struct', 'Struct Tests');
+ };
+
+ es3fShaderStructTests.ShaderStructTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderStructTests.ShaderStructTests.prototype.constructor = es3fShaderStructTests.ShaderStructTests;
+
+ es3fShaderStructTests.ShaderStructTests.prototype.init = function() {
+ this.addChild(new es3fShaderStructTests.LocalStructTests());
+ this.addChild(new es3fShaderStructTests.UniformStructTests());
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fShaderStructTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fShaderStructTests.ShaderStructTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fShaderStructTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderSwitchTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderSwitchTests.js
new file mode 100644
index 0000000000..27670f9d64
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderSwitchTests.js
@@ -0,0 +1,492 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fShaderSwitchTests');
+goog.require('framework.common.tcuStringTemplate');
+goog.require('framework.common.tcuTestCase');
+goog.require('modules.shared.glsShaderRenderCase');
+
+
+goog.scope(function() {
+ var es3fShaderSwitchTests = functional.gles3.es3fShaderSwitchTests;
+ var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuStringTemplate = framework.common.tcuStringTemplate;
+
+ /**
+ * @constructor
+ * @extends {glsShaderRenderCase.ShaderRenderCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {boolean} isVertexCase
+ * @param {string} vtxSource
+ * @param {string} fragSource
+ * @param {glsShaderRenderCase.ShaderEvalFunc=} evalFunc
+ */
+ es3fShaderSwitchTests.ShaderSwitchCase = function(name, description, isVertexCase, vtxSource, fragSource, evalFunc) {
+ glsShaderRenderCase.ShaderRenderCase.call(this, name, description, isVertexCase, evalFunc);
+ /** @type {string} */ this.m_vertShaderSource = vtxSource;
+ /** @type {string} */ this.m_fragShaderSource = fragSource;
+ };
+
+ es3fShaderSwitchTests.ShaderSwitchCase.prototype = Object.create(glsShaderRenderCase.ShaderRenderCase.prototype);
+ es3fShaderSwitchTests.ShaderSwitchCase.prototype.constructor = es3fShaderSwitchTests.ShaderSwitchCase;
+
+ /**
+ * @enum {number}
+ */
+ es3fShaderSwitchTests.SwitchType = {
+ STATIC: 0,
+ UNIFORM: 1,
+ DYNAMIC: 2
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} evalCtx */
+ es3fShaderSwitchTests.evalSwitchStatic = function(evalCtx) {
+ evalCtx.color[0] = evalCtx.coords[1];
+ evalCtx.color[1] = evalCtx.coords[2];
+ evalCtx.color[2] = evalCtx.coords[3];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} evalCtx */
+ es3fShaderSwitchTests.evalSwitchUniform = function(evalCtx) {
+ evalCtx.color[0] = evalCtx.coords[1];
+ evalCtx.color[1] = evalCtx.coords[2];
+ evalCtx.color[2] = evalCtx.coords[3];
+ };
+
+ /** @param {glsShaderRenderCase.ShaderEvalContext} evalCtx */
+ es3fShaderSwitchTests.evalSwitchDynamic = function(evalCtx) {
+ switch (Math.floor(evalCtx.coords[2]*1.5 + 2.0)) {
+ case 0:
+ evalCtx.color[0] = evalCtx.coords[0];
+ evalCtx.color[1] = evalCtx.coords[1];
+ evalCtx.color[2] = evalCtx.coords[2];
+ break;
+ case 1:
+ evalCtx.color[0] = evalCtx.coords[3];
+ evalCtx.color[1] = evalCtx.coords[2];
+ evalCtx.color[2] = evalCtx.coords[1];
+ break;
+ case 2:
+ evalCtx.color[0] = evalCtx.coords[1];
+ evalCtx.color[1] = evalCtx.coords[2];
+ evalCtx.color[2] = evalCtx.coords[3];
+ break;
+ case 3:
+ evalCtx.color[0] = evalCtx.coords[2];
+ evalCtx.color[1] = evalCtx.coords[1];
+ evalCtx.color[2] = evalCtx.coords[0];
+ break;
+ default:
+ evalCtx.color[0] = evalCtx.coords[0];
+ evalCtx.color[1] = evalCtx.coords[0];
+ evalCtx.color[2] = evalCtx.coords[0];
+ break;
+ }
+ };
+
+ /**
+ * @param {string} name
+ * @param {string} desc
+ * @param {es3fShaderSwitchTests.SwitchType} type
+ * @param {boolean} isVertex
+ * @param {string} switchBody
+ * @return {es3fShaderSwitchTests.ShaderSwitchCase}
+ */
+ es3fShaderSwitchTests.makeSwitchCase = function(name, desc, type, isVertex, switchBody) {
+ /** @type {string} */ var vtx = '';
+ /** @type {string} */ var frag = '';
+ /** @type {string} */ var op = '';
+
+ vtx += "#version 300 es\n" +
+ "in highp vec4 a_position;\n" +
+ "in highp vec4 a_coords;\n";
+ frag += "#version 300 es\n" +
+ "layout(location = 0) out mediump vec4 o_color;\n";
+
+ if (isVertex) {
+ vtx += "out mediump vec4 v_color;\n";
+ frag += "in mediump vec4 v_color;\n";
+ } else {
+ vtx += "out highp vec4 v_coords;\n";
+ frag += "in highp vec4 v_coords;\n";
+ }
+
+ if (type === es3fShaderSwitchTests.SwitchType.UNIFORM)
+ op += "uniform highp int ui_two;\n";
+
+ vtx += isVertex ? op : '';
+ frag += isVertex ? '' : op;
+ op = '';
+
+ vtx += "\n" +
+ "void main (void)\n" +
+ "{\n" +
+ " gl_Position = a_position;\n";
+ frag += "\n" +
+ "void main (void)\n" +
+ "{\n";
+
+ // Setup.
+ op += " highp vec4 coords = " + (isVertex ? "a_coords" : "v_coords") + ";\n";
+ op += " mediump vec3 res = vec3(0.0);\n\n";
+ vtx += isVertex ? op : '';
+ frag += isVertex ? '' : op;
+ op = '';
+
+ // Switch body.
+ var params = {};
+ params["CONDITION"] = type == es3fShaderSwitchTests.SwitchType.STATIC ? "2" :
+ type == es3fShaderSwitchTests.SwitchType.UNIFORM ? "ui_two" :
+ type == es3fShaderSwitchTests.SwitchType.DYNAMIC ? "int(floor(coords.z*1.5 + 2.0))" : "???";
+
+ op += tcuStringTemplate.specialize(switchBody, params);
+ op += "\n";
+
+ vtx += isVertex ? op : '';
+ frag += isVertex ? '' : op;
+ op = '';
+
+ if (isVertex) {
+ vtx += " v_color = vec4(res, 1.0);\n";
+ frag += " o_color = v_color;\n";
+ } else {
+ vtx += " v_coords = a_coords;\n";
+ frag += " o_color = vec4(res, 1.0);\n";
+ }
+
+ vtx += "}\n";
+ frag += "}\n";
+
+ return new es3fShaderSwitchTests.ShaderSwitchCase(name, desc, isVertex, vtx, frag,
+ type === es3fShaderSwitchTests.SwitchType.STATIC ? es3fShaderSwitchTests.evalSwitchStatic :
+ type === es3fShaderSwitchTests.SwitchType.UNIFORM ? es3fShaderSwitchTests.evalSwitchUniform :
+ type === es3fShaderSwitchTests.SwitchType.DYNAMIC ? es3fShaderSwitchTests.evalSwitchDynamic : undefined);
+ };
+
+ /**
+ * @param {tcuTestCase.DeqpTest} group
+ * @param {string} name
+ * @param {string} desc
+ * @param {string} switchBody
+ */
+ es3fShaderSwitchTests.makeSwitchCases = function(group, name, desc, switchBody) {
+ /** @type {Array<string>} */ var switchTypeNames = ["static", "uniform", "dynamic"];
+ for (var type in es3fShaderSwitchTests.SwitchType) {
+ group.addChild(es3fShaderSwitchTests.makeSwitchCase(name + "_" + switchTypeNames[es3fShaderSwitchTests.SwitchType[type]] + "_vertex", desc, es3fShaderSwitchTests.SwitchType[type], true, switchBody));
+ group.addChild(es3fShaderSwitchTests.makeSwitchCase(name + "_" + switchTypeNames[es3fShaderSwitchTests.SwitchType[type]] + "_fragment", desc, es3fShaderSwitchTests.SwitchType[type], false, switchBody));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderSwitchTests.ShaderSwitchTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'switch', 'Switch statement tests');
+ };
+
+ es3fShaderSwitchTests.ShaderSwitchTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderSwitchTests.ShaderSwitchTests.prototype.constructor = es3fShaderSwitchTests.ShaderSwitchTests;
+
+ es3fShaderSwitchTests.ShaderSwitchTests.prototype.init = function() {
+ // Expected swizzles:
+ // 0: xyz
+ // 1: wzy
+ // 2: yzw
+ // 3: zyx
+ es3fShaderSwitchTests.makeSwitchCases(this, "basic", "Basic switch statement usage",
+ ' switch (${CONDITION})\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1: res = coords.wzy; break;\n' +
+ ' case 2: res = coords.yzw; break;\n' +
+ ' case 3: res = coords.zyx; break;\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "const_expr_in_label", "Constant expression in label",
+ ' const int t = 2;\n' +
+ ' switch (${CONDITION})\n' +
+ ' {\n' +
+ ' case int(0.0): res = coords.xyz; break;\n' +
+ ' case 2-1: res = coords.wzy; break;\n' +
+ ' case 3&(1<<1): res = coords.yzw; break;\n' +
+ ' case t+1: res = coords.zyx; break;\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "default_label", "Default label usage",
+ ' switch (${CONDITION})\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1: res = coords.wzy; break;\n' +
+ ' case 3: res = coords.zyx; break;\n' +
+ ' default: res = coords.yzw;\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "default_not_last", "Default label usage",
+ ' switch (${CONDITION})\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' default: res = coords.yzw; break;\n' +
+ ' case 1: res = coords.wzy; break;\n' +
+ ' case 3: res = coords.zyx; break;\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "no_default_label", "No match in switch without default label",
+ ' res = coords.yzw;\n\n' +
+ ' switch (${CONDITION})\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1: res = coords.wzy; break;\n' +
+ ' case 3: res = coords.zyx; break;\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "fall_through", "Fall-through",
+ ' switch (${CONDITION})\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1: res = coords.wzy; break;\n' +
+ ' case 2: coords = coords.yzwx;\n' +
+ ' case 4: res = vec3(coords); break;\n' +
+ ' case 3: res = coords.zyx; break;\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "fall_through_default", "Fall-through",
+ ' switch (${CONDITION})\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1: res = coords.wzy; break;\n' +
+ ' case 3: res = coords.zyx; break;\n' +
+ ' case 2: coords = coords.yzwx;\n' +
+ ' default: res = vec3(coords);\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "conditional_fall_through", "Fall-through",
+ ' highp vec4 tmp = coords;\n' +
+ ' switch (${CONDITION})\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1: res = coords.wzy; break;\n' +
+ ' case 2:\n' +
+ ' tmp = coords.yzwx;\n' +
+ ' case 3:\n' +
+ ' res = vec3(tmp);\n' +
+ ' if (${CONDITION} != 3)\n' +
+ ' break;\n' +
+ ' default: res = tmp.zyx; break;\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "conditional_fall_through_2", "Fall-through",
+ ' highp vec4 tmp = coords;\n' +
+ ' mediump int c = ${CONDITION};\n' +
+ ' switch (c)\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1: res = coords.wzy; break;\n' +
+ ' case 2:\n' +
+ ' c += ${CONDITION};\n' +
+ ' tmp = coords.yzwx;\n' +
+ ' case 3:\n' +
+ ' res = vec3(tmp);\n' +
+ ' if (c == 4)\n' +
+ ' break;\n' +
+ ' default: res = tmp.zyx; break;\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "scope", "Basic switch statement usage",
+ ' switch (${CONDITION})\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1: res = coords.wzy; break;\n' +
+ ' case 2:\n' +
+ ' {\n' +
+ ' mediump vec3 t = coords.yzw;\n' +
+ ' res = t;\n' +
+ ' break;\n' +
+ ' }\n' +
+ ' case 3: res = coords.zyx; break;\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "switch_in_if", "Switch in for loop",
+ ' if (${CONDITION} >= 0)\n' +
+ ' {\n' +
+ ' switch (${CONDITION})\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1: res = coords.wzy; break;\n' +
+ ' case 2: res = coords.yzw; break;\n' +
+ ' case 3: res = coords.zyx; break;\n' +
+ ' }\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "switch_in_for_loop", "Switch in for loop",
+ ' for (int i = 0; i <= ${CONDITION}; i++)\n' +
+ ' {\n' +
+ ' switch (i)\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1: res = coords.wzy; break;\n' +
+ ' case 2: res = coords.yzw; break;\n' +
+ ' case 3: res = coords.zyx; break;\n' +
+ ' }\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "switch_in_while_loop", "Switch in while loop",
+ ' int i = 0;\n' +
+ ' while (i <= ${CONDITION})\n' +
+ ' {\n' +
+ ' switch (i)\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1: res = coords.wzy; break;\n' +
+ ' case 2: res = coords.yzw; break;\n' +
+ ' case 3: res = coords.zyx; break;\n' +
+ ' }\n' +
+ ' i += 1;\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "switch_in_do_while_loop", "Switch in do-while loop",
+ ' int i = 0;\n' +
+ ' do\n' +
+ ' {\n' +
+ ' switch (i)\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1: res = coords.wzy; break;\n' +
+ ' case 2: res = coords.yzw; break;\n' +
+ ' case 3: res = coords.zyx; break;\n' +
+ ' }\n' +
+ ' i += 1;\n' +
+ ' } while (i <= ${CONDITION});\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "if_in_switch", "Basic switch statement usage",
+ ' switch (${CONDITION})\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1: res = coords.wzy; break;\n' +
+ ' default:\n' +
+ ' if (${CONDITION} == 2)\n' +
+ ' res = coords.yzw;\n' +
+ ' else\n' +
+ ' res = coords.zyx;\n' +
+ ' break;\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "for_loop_in_switch", "Basic switch statement usage",
+ ' switch (${CONDITION})\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1:\n' +
+ ' case 2:\n' +
+ ' {\n' +
+ ' highp vec3 t = coords.yzw;\n' +
+ ' for (int i = 0; i < ${CONDITION}; i++)\n' +
+ ' t = t.zyx;\n' +
+ ' res = t;\n' +
+ ' break;\n' +
+ ' }\n' +
+ ' default: res = coords.zyx; break;\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "while_loop_in_switch", "Basic switch statement usage",
+ ' switch (${CONDITION})\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1:\n' +
+ ' case 2:\n' +
+ ' {\n' +
+ ' highp vec3 t = coords.yzw;\n' +
+ ' int i = 0;\n' +
+ ' while (i < ${CONDITION})\n' +
+ ' {\n' +
+ ' t = t.zyx;\n' +
+ ' i += 1;\n' +
+ ' }\n' +
+ ' res = t;\n' +
+ ' break;\n' +
+ ' }\n' +
+ ' default: res = coords.zyx; break;\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "do_while_loop_in_switch", "Basic switch statement usage",
+ ' switch (${CONDITION})\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1:\n' +
+ ' case 2:\n' +
+ ' {\n' +
+ ' highp vec3 t = coords.yzw;\n' +
+ ' int i = 0;\n' +
+ ' do\n' +
+ ' {\n' +
+ ' t = t.zyx;\n' +
+ ' i += 1;\n' +
+ ' } while (i < ${CONDITION});\n' +
+ ' res = t;\n' +
+ ' break;\n' +
+ ' }\n' +
+ ' default: res = coords.zyx; break;\n' +
+ ' }\n');
+
+ es3fShaderSwitchTests.makeSwitchCases(this, "switch_in_switch", "Basic switch statement usage",
+ ' switch (${CONDITION})\n' +
+ ' {\n' +
+ ' case 0: res = coords.xyz; break;\n' +
+ ' case 1:\n' +
+ ' case 2:\n' +
+ ' switch (${CONDITION} - 1)\n' +
+ ' {\n' +
+ ' case 0: res = coords.wzy; break;\n' +
+ ' case 1: res = coords.yzw; break;\n' +
+ ' }\n' +
+ ' break;\n' +
+ ' default: res = coords.zyx; break;\n' +
+ '}\n');
+
+ // Negative cases.
+ // This is being tested somwhere else: data/gles3/shaders/switch.html
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fShaderSwitchTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fShaderSwitchTests.ShaderSwitchTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fShaderSwitchTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderTextureFunctionTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderTextureFunctionTests.js
new file mode 100644
index 0000000000..b6386c96ed
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fShaderTextureFunctionTests.js
@@ -0,0 +1,2709 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fShaderTextureFunctionTests');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('framework.opengl.gluTexture');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.common.tcuMatrix');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('modules.shared.glsShaderRenderCase');
+
+goog.scope(function() {
+ var es3fShaderTextureFunctionTests = functional.gles3.es3fShaderTextureFunctionTests;
+ var deMath = framework.delibs.debase.deMath;
+ var tcuMatrix = framework.common.tcuMatrix;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuTexture = framework.common.tcuTexture;
+ var tcuTextureUtil = framework.common.tcuTextureUtil;
+ var gluTextureUtil = framework.opengl.gluTextureUtil;
+ var gluTexture = framework.opengl.gluTexture;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var glsShaderRenderCase = modules.shared.glsShaderRenderCase;
+
+ let canvasWH = 256;
+ if (tcuTestCase.isQuickMode()) {
+ canvasWH = 32;
+ }
+
+ /**
+ * @enum
+ */
+ es3fShaderTextureFunctionTests.TexFunction = {
+ TEXTURE: 0, //!< texture(), textureOffset()
+ TEXTUREPROJ: 1, //!< textureProj(), textureProjOffset()
+ TEXTUREPROJ3: 2, //!< textureProj(sampler2D, vec3)
+ TEXTURELOD: 3, // ...
+ TEXTUREPROJLOD: 4,
+ TEXTUREPROJLOD3: 5, //!< textureProjLod(sampler2D, vec3)
+ TEXTUREGRAD: 6,
+ TEXTUREPROJGRAD: 7,
+ TEXTUREPROJGRAD3: 8, //!< textureProjGrad(sampler2D, vec3)
+ TEXELFETCH: 9
+ };
+
+ /**
+ * @param {gluShaderProgram.shaderType} shaderType
+ * @param {es3fShaderTextureFunctionTests.TexFunction} function_
+ * @return {boolean}
+ */
+ es3fShaderTextureFunctionTests.functionHasAutoLod = function(shaderType, function_) {
+ return shaderType === gluShaderProgram.shaderType.FRAGMENT &&
+ (function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTURE ||
+ function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ ||
+ function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3);
+ };
+
+ /**
+ * @param {es3fShaderTextureFunctionTests.TexFunction} function_
+ * @return {boolean}
+ */
+ es3fShaderTextureFunctionTests.functionHasProj = function(function_) {
+ return function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ ||
+ function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3 ||
+ function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD ||
+ function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD ||
+ function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD3 ||
+ function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD3;
+ };
+
+ /**
+ * @param {es3fShaderTextureFunctionTests.TexFunction} function_
+ * @return {boolean}
+ */
+ es3fShaderTextureFunctionTests.functionHasGrad = function(function_) {
+ return function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD ||
+ function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD ||
+ function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD3;
+ };
+
+ /**
+ * @param {es3fShaderTextureFunctionTests.TexFunction} function_
+ * @return {boolean}
+ */
+ es3fShaderTextureFunctionTests.functionHasLod = function(function_) {
+ return function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD ||
+ function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD ||
+ function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD3 ||
+ function_ === es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH;
+ };
+
+ /**
+ * @struct
+ * @constructor
+ * @param {es3fShaderTextureFunctionTests.TexFunction} func
+ * @param {Array<number>} minCoord
+ * @param {Array<number>} maxCoord
+ * @param {boolean} useBias
+ * @param {number} minLodBias
+ * @param {number} maxLodBias
+ * @param {Array<number>} minDX For *Grad* functions
+ * @param {Array<number>} maxDX For *Grad* functions
+ * @param {Array<number>} minDY For *Grad* functions
+ * @param {Array<number>} maxDY For *Grad* functions
+ * @param {boolean} useOffset
+ * @param {Array<number>} offset
+ */
+ es3fShaderTextureFunctionTests.TextureLookupSpec = function(func, minCoord, maxCoord, useBias, minLodBias, maxLodBias, minDX, maxDX, minDY, maxDY, useOffset, offset) {
+ /** @type {es3fShaderTextureFunctionTests.TexFunction} */ this.func = func;
+ /** @type {Array<number>} */ this.minCoord = minCoord;
+ /** @type {Array<number>} */ this.maxCoord = maxCoord;
+ // Bias
+ /** @type {boolean} */ this.useBias = useBias;
+ // Bias or Lod for *Lod* functions
+ /** @type {number} */ this.minLodBias = minLodBias;
+ /** @type {number} */ this.maxLodBias = maxLodBias;
+ // For *Grad* functions
+ /** @type {Array<number>} */ this.minDX = minDX;
+ /** @type {Array<number>} */ this.maxDX = maxDX;
+ /** @type {Array<number>} */ this.minDY = minDY;
+ /** @type {Array<number>} */ this.maxDY = maxDY;
+ /** @type {boolean} */ this.useOffset = useOffset;
+ /** @type {Array<number>} */ this.offset = offset;
+ };
+
+ /**
+ * @enum
+ */
+ es3fShaderTextureFunctionTests.TextureType = {
+ TEXTURETYPE_2D: 0,
+ TEXTURETYPE_CUBE_MAP: 1,
+ TEXTURETYPE_2D_ARRAY: 2,
+ TEXTURETYPE_3D: 3
+ };
+
+ /**
+ * @struct
+ * @constructor
+ * @param {?es3fShaderTextureFunctionTests.TextureType} type
+ * @param {number} format
+ * @param {number} width
+ * @param {number} height
+ * @param {number} depth
+ * @param {number} numLevels
+ * @param {?tcuTexture.Sampler} sampler
+ */
+ es3fShaderTextureFunctionTests.TextureSpec = function(type, format, width, height, depth, numLevels, sampler) {
+ /** @type {?es3fShaderTextureFunctionTests.TextureType} */ this.type = type; //!< Texture type (2D, cubemap, ...)
+ /** @type {number} */ this.format = format; //!< Internal format.
+ /** @type {number} */ this.width = width;
+ /** @type {number} */ this.height = height;
+ /** @type {number} */ this.depth = depth;
+ /** @type {number} */ this.numLevels = numLevels;
+ /** @type {?tcuTexture.Sampler} */ this.sampler = sampler;
+ };
+
+ /**
+ * @struct
+ * @constructor
+ */
+ es3fShaderTextureFunctionTests.TexLookupParams = function() {
+ /** @type {number} */ this.lod = 0;
+ /** @type {Array<number>} */ this.offset = [0, 0, 0];
+ /** @type {Array<number>} */ this.scale = [1.0, 1.0, 1.0, 1.0];
+ /** @type {Array<number>} */ this.bias = [0.0, 0.0, 0.0, 0.0];
+ };
+
+ /**
+ * @enum
+ */
+ es3fShaderTextureFunctionTests.LodMode = {
+ EXACT: 0,
+ MIN_BOUND: 1,
+ MAX_BOUND: 2
+ };
+
+ /** @const {es3fShaderTextureFunctionTests.LodMode} */ es3fShaderTextureFunctionTests.DEFAULT_LOD_MODE = es3fShaderTextureFunctionTests.LodMode.EXACT;
+
+ /**
+ * @param {number} dudx
+ * @param {number} dvdx
+ * @param {number} dudy
+ * @param {number} dvdy
+ * @return {number}
+ */
+ es3fShaderTextureFunctionTests.computeLodFromDerivates_UV = function(dudx, dvdx, dudy, dvdy) {
+ /** @type {es3fShaderTextureFunctionTests.LodMode} */ var mode = es3fShaderTextureFunctionTests.DEFAULT_LOD_MODE;
+ /** @type {number} */ var p;
+
+ switch (mode) {
+ case es3fShaderTextureFunctionTests.LodMode.EXACT:
+ p = Math.max(Math.sqrt(dudx * dudx + dvdx * dvdx), Math.sqrt(dudy * dudy + dvdy * dvdy));
+ break;
+
+ case es3fShaderTextureFunctionTests.LodMode.MIN_BOUND:
+ case es3fShaderTextureFunctionTests.LodMode.MAX_BOUND:
+ /** @type {number} */ var mu = Math.max(Math.abs(dudx), Math.abs(dudy));
+ /** @type {number} */ var mv = Math.max(Math.abs(dvdx), Math.abs(dvdy));
+
+ p = mode === es3fShaderTextureFunctionTests.LodMode.MIN_BOUND ? Math.max(mu, mv) : mu + mv;
+ break;
+
+ default:
+ throw new Error('LOD_MODE not supported.');
+ }
+
+ return Math.log2(p);
+ };
+
+ /**
+ * @param {number} dudx
+ * @param {number} dvdx
+ * @param {number} dwdx
+ * @param {number} dudy
+ * @param {number} dvdy
+ * @param {number} dwdy
+ * @return {number}
+ */
+ es3fShaderTextureFunctionTests.computeLodFromDerivates_UVW = function(dudx, dvdx, dwdx, dudy, dvdy, dwdy) {
+ /** @type {es3fShaderTextureFunctionTests.LodMode} */ var mode = es3fShaderTextureFunctionTests.DEFAULT_LOD_MODE;
+ /** @type {number} */ var p;
+
+ switch (mode) {
+ case es3fShaderTextureFunctionTests.LodMode.EXACT:
+ p = Math.max(Math.sqrt(dudx * dudx + dvdx * dvdx + dwdx * dwdx), Math.sqrt(dudy * dudy + dvdy * dvdy + dwdy * dwdy));
+ break;
+
+ case es3fShaderTextureFunctionTests.LodMode.MIN_BOUND:
+ case es3fShaderTextureFunctionTests.LodMode.MAX_BOUND:
+ /** @type {number} */ var mu = Math.max(Math.abs(dudx), Math.abs(dudy));
+ /** @type {number} */ var mv = Math.max(Math.abs(dvdx), Math.abs(dvdy));
+ /** @type {number} */ var mw = Math.max(Math.abs(dwdx), Math.abs(dwdy));
+
+ p = mode === es3fShaderTextureFunctionTests.LodMode.MIN_BOUND ? Math.max(mu, mv, mw) : (mu + mv + mw);
+ break;
+
+ default:
+ throw new Error('LOD_MODE not supported.');
+ }
+
+ return Math.log2(p);
+ };
+
+ /**
+ * [dag] Wrapper function for computeLodFromDerivates_UV or computeLodFromDerivates_UVW
+ * @param {number} dudx
+ * @param {number} dvdx
+ * @param {number} dwdxOrdudy
+ * @param {number} dudyOrdvdy
+ * @param {number=} dvdy
+ * @param {number=} dwdy
+ * @return {number}
+ */
+ es3fShaderTextureFunctionTests.computeLodFromDerivates = function(dudx, dvdx, dwdxOrdudy, dudyOrdvdy, dvdy, dwdy) {
+ if (arguments.length === 4)
+ return es3fShaderTextureFunctionTests.computeLodFromDerivates_UV(dudx, dvdx, dwdxOrdudy, dudyOrdvdy);
+ else
+ return es3fShaderTextureFunctionTests.computeLodFromDerivates_UVW(dudx, dvdx, dwdxOrdudy, dudyOrdvdy, /** @type {number} */ (dvdy), /** @type {number} */ (dwdy));
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @return {number}
+ */
+ es3fShaderTextureFunctionTests.computeLodFromGrad2D = function(c) {
+ /** @type {number} */ var w = c.textures[0].tex2D.getWidth();
+ /** @type {number} */ var h = c.textures[0].tex2D.getHeight();
+ return es3fShaderTextureFunctionTests.computeLodFromDerivates(c.in_[1][0] * w, c.in_[1][1] * h, c.in_[2][0] * w, c.in_[2][1] * h);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @return {number}
+ */
+ es3fShaderTextureFunctionTests.computeLodFromGrad2DArray = function(c) {
+ /** @type {number} */ var w = c.textures[0].tex2DArray.getWidth();
+ /** @type {number} */ var h = c.textures[0].tex2DArray.getHeight();
+ return es3fShaderTextureFunctionTests.computeLodFromDerivates(c.in_[1][0] * w, c.in_[1][1] * h, c.in_[2][0] * w, c.in_[2][1] * h);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @return {number}
+ */
+ es3fShaderTextureFunctionTests.computeLodFromGrad3D = function(c) {
+ /** @type {number} */ var w = c.textures[0].tex3D.getWidth();
+ /** @type {number} */ var h = c.textures[0].tex3D.getHeight();
+ /** @type {number} */ var d = c.textures[0].tex3D.getDepth();
+ return es3fShaderTextureFunctionTests.computeLodFromDerivates(c.in_[1][0] * w, c.in_[1][1] * h, c.in_[1][2] * d, c.in_[2][0] * w, c.in_[2][1] * h, c.in_[2][2] * d);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @return {number}
+ */
+ es3fShaderTextureFunctionTests.computeLodFromGradCube = function(c) {
+ // \note Major axis is always -Z or +Z
+ /** @type {number} */ var m = Math.abs(c.in_[0][2]);
+ /** @type {number} */ var d = c.textures[0].texCube.getSize();
+ /** @type {number} */ var s = d / (2.0 * m);
+ /** @type {number} */ var t = d / (2.0 * m);
+ return es3fShaderTextureFunctionTests.computeLodFromDerivates(c.in_[1][0] * s, c.in_[1][1] * t, c.in_[2][0] * s, c.in_[2][1] * t);
+ };
+
+ /** @typedef {function(glsShaderRenderCase.ShaderEvalContext, es3fShaderTextureFunctionTests.TexLookupParams)} */ es3fShaderTextureFunctionTests.TexEvalFunc;
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {number} s
+ * @param {number} t
+ * @param {number} lod
+ * @return {Array<number>}
+ */
+ es3fShaderTextureFunctionTests.texture2D = function(c, s, t, lod) {
+ return c.textures[0].tex2D.getView().sample(c.textures[0].sampler, [s, t], lod);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {number} s
+ * @param {number} t
+ * @param {number} r
+ * @param {number} lod
+ * @return {Array<number>}
+ */
+ es3fShaderTextureFunctionTests.textureCube = function(c, s, t, r, lod) {
+ return c.textures[0].texCube.getView().sample(c.textures[0].sampler, [s, t, r], lod);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {number} s
+ * @param {number} t
+ * @param {number} r
+ * @param {number} lod
+ * @return {Array<number>}
+ */
+ es3fShaderTextureFunctionTests.texture2DArray = function(c, s, t, r, lod) {
+ return c.textures[0].tex2DArray.getView().sample(c.textures[0].sampler, [s, t, r], lod);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {number} s
+ * @param {number} t
+ * @param {number} r
+ * @param {number} lod
+ * @return {Array<number>}
+ */
+ es3fShaderTextureFunctionTests.texture3D = function(c, s, t, r, lod) {
+ return c.textures[0].tex3D.getView().sample(c.textures[0].sampler, [s, t, r], lod);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {number} ref
+ * @param {number} s
+ * @param {number} t
+ * @param {number} lod
+ * @return {number}
+ */
+ es3fShaderTextureFunctionTests.texture2DShadow = function(c, ref, s, t, lod) {
+ return c.textures[0].tex2D.getView().sampleCompare(c.textures[0].sampler, ref, [s, t], lod);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {number} ref
+ * @param {number} s
+ * @param {number} t
+ * @param {number} r
+ * @param {number} lod
+ * @return {number}
+ */
+ es3fShaderTextureFunctionTests.textureCubeShadow = function(c, ref, s, t, r, lod) {
+ return c.textures[0].texCube.getView().sampleCompare(c.textures[0].sampler, ref, [s, t, r], lod);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {number} ref
+ * @param {number} s
+ * @param {number} t
+ * @param {number} r
+ * @param {number} lod
+ * @return {number}
+ */
+ es3fShaderTextureFunctionTests.texture2DArrayShadow = function(c, ref, s, t, r, lod) {
+ return c.textures[0].tex2DArray.getView().sampleCompare(c.textures[0].sampler, ref, [s, t, r], lod);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {number} s
+ * @param {number} t
+ * @param {number} lod
+ * @param {Array<number>} offset
+ * @return {Array<number>}
+ */
+ es3fShaderTextureFunctionTests.texture2DOffset = function(c, s, t, lod, offset) {
+ return c.textures[0].tex2D.getView().sampleOffset(c.textures[0].sampler, [s, t], lod, offset);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {number} s
+ * @param {number} t
+ * @param {number} r
+ * @param {number} lod
+ * @param {Array<number>} offset
+ * @return {Array<number>}
+ */
+ es3fShaderTextureFunctionTests.texture2DArrayOffset = function(c, s, t, r, lod, offset) {
+ return c.textures[0].tex2DArray.getView().sampleOffset(c.textures[0].sampler, [s, t, r], lod, offset);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {number} s
+ * @param {number} t
+ * @param {number} r
+ * @param {number} lod
+ * @param {Array<number>} offset
+ * @return {Array<number>}
+ */
+ es3fShaderTextureFunctionTests.texture3DOffset = function(c, s, t, r, lod, offset) {
+ return c.textures[0].tex3D.getView().sampleOffset(c.textures[0].sampler, [s, t, r], lod, offset);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {number} ref
+ * @param {number} s
+ * @param {number} t
+ * @param {number} lod
+ * @param {Array<number>} offset
+ * @return {number}
+ */
+ es3fShaderTextureFunctionTests.texture2DShadowOffset = function(c, ref, s, t, lod, offset) {
+ return c.textures[0].tex2D.getView().sampleCompareOffset(c.textures[0].sampler, ref, [s, t], lod, offset);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {number} ref
+ * @param {number} s
+ * @param {number} t
+ * @param {number} r
+ * @param {number} lod
+ * @param {Array<number>} offset
+ * @return {number}
+ */
+ es3fShaderTextureFunctionTests.texture2DArrayShadowOffset = function(c, ref, s, t, r, lod, offset) {
+ return c.textures[0].tex2DArray.getView().sampleCompareOffset(c.textures[0].sampler, ref, [s, t, r], lod, offset);
+ };
+
+ // Eval functions.
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2D = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2D(c, c.in_[0][0], c.in_[0][1], p.lod), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTextureCube = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.textureCube(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], p.lod), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DArray = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DArray(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], p.lod), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3D = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3D(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], p.lod), p.scale), p.bias);
+ };
+
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DBias = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2D(c, c.in_[0][0], c.in_[0][1], p.lod+c.in_[1][0]), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTextureCubeBias = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.textureCube(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], p.lod+c.in_[1][0]), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DArrayBias = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DArray(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], p.lod+c.in_[1][0]), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3DBias = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3D(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], p.lod+c.in_[1][0]), p.scale), p.bias);
+ };
+
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProj3 = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2D(c, c.in_[0][0]/c.in_[0][2], c.in_[0][1]/c.in_[0][2], p.lod), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProj3Bias = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2D(c, c.in_[0][0]/c.in_[0][2], c.in_[0][1]/c.in_[0][2], p.lod+c.in_[1][0]), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProj = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2D(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], p.lod), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProjBias = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2D(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], p.lod+c.in_[1][0]), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3DProj = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3D(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], c.in_[0][2]/c.in_[0][3], p.lod), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3DProjBias = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3D(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], c.in_[0][2]/c.in_[0][3], p.lod+c.in_[1][0]), p.scale), p.bias);
+ };
+
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DLod = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2D(c, c.in_[0][0], c.in_[0][1], c.in_[1][0]), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTextureCubeLod = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.textureCube(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], c.in_[1][0]), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DArrayLod = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DArray(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], c.in_[1][0]), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3DLod = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3D(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], c.in_[1][0]), p.scale), p.bias);
+ };
+
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProjLod3 = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2D(c, c.in_[0][0]/c.in_[0][2], c.in_[0][1]/c.in_[0][2], c.in_[1][0]), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProjLod = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2D(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], c.in_[1][0]), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3DProjLod = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3D(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], c.in_[0][2]/c.in_[0][3], c.in_[1][0]), p.scale), p.bias);
+ };
+
+ // Offset variants
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DOffset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DOffset(c, c.in_[0][0], c.in_[0][1], p.lod, deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DArrayOffset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DArrayOffset(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], p.lod, deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3DOffset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3DOffset(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], p.lod, p.offset), p.scale), p.bias);
+ };
+
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DOffsetBias = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DOffset(c, c.in_[0][0], c.in_[0][1], p.lod+c.in_[1][0], deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DArrayOffsetBias = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DArrayOffset(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], p.lod+c.in_[1][0], deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3DOffsetBias = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3DOffset(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], p.lod+c.in_[1][0], p.offset), p.scale), p.bias);
+ };
+
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DLodOffset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DOffset(c, c.in_[0][0], c.in_[0][1], c.in_[1][0], deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DArrayLodOffset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DArrayOffset(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], c.in_[1][0], deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3DLodOffset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3DOffset(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], c.in_[1][0], p.offset), p.scale), p.bias);
+ };
+
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProj3Offset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DOffset(c, c.in_[0][0]/c.in_[0][2], c.in_[0][1]/c.in_[0][2], p.lod, deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProj3OffsetBias = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DOffset(c, c.in_[0][0]/c.in_[0][2], c.in_[0][1]/c.in_[0][2], p.lod+c.in_[1][0], deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProjOffset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DOffset(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], p.lod, deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProjOffsetBias = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DOffset(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], p.lod+c.in_[1][0], deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3DProjOffset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3DOffset(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], c.in_[0][2]/c.in_[0][3], p.lod, p.offset), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3DProjOffsetBias = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3DOffset(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], c.in_[0][2]/c.in_[0][3], p.lod+c.in_[1][0], p.offset), p.scale), p.bias);
+ };
+
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProjLod3Offset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DOffset(c, c.in_[0][0]/c.in_[0][2], c.in_[0][1]/c.in_[0][2], c.in_[1][0], deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProjLodOffset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DOffset(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], c.in_[1][0], deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3DProjLodOffset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3DOffset(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], c.in_[0][2]/c.in_[0][3], c.in_[1][0], p.offset), p.scale), p.bias);
+ };
+
+ // Shadow variants
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadow = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadow(c, c.in_[0][2], c.in_[0][0], c.in_[0][1], p.lod);
+ };
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadowBias = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadow(c, c.in_[0][2], c.in_[0][0], c.in_[0][1], p.lod+c.in_[1][0]);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTextureCubeShadow = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.textureCubeShadow(c, c.in_[0][3], c.in_[0][0], c.in_[0][1], c.in_[0][2], p.lod);
+ };
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTextureCubeShadowBias = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.textureCubeShadow(c, c.in_[0][3], c.in_[0][0], c.in_[0][1], c.in_[0][2], p.lod+c.in_[1][0]);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DArrayShadow = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DArrayShadow(c, c.in_[0][3], c.in_[0][0], c.in_[0][1], c.in_[0][2], p.lod);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadowLod = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadow(c, c.in_[0][2], c.in_[0][0], c.in_[0][1], c.in_[1][0]);
+ };
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadowLodOffset = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadowOffset(c, c.in_[0][2], c.in_[0][0], c.in_[0][1], c.in_[1][0], deMath.swizzle(p.offset, [0,1]));
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadowProj = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadow(c, c.in_[0][2]/c.in_[0][3], c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], p.lod);
+ };
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadowProjBias = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadow(c, c.in_[0][2]/c.in_[0][3], c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], p.lod+c.in_[1][0]);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadowProjLod = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadow(c, c.in_[0][2]/c.in_[0][3], c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], c.in_[1][0]);
+ };
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadowProjLodOffset = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadowOffset(c, c.in_[0][2]/c.in_[0][3], c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], c.in_[1][0], deMath.swizzle(p.offset, [0,1]));
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadowOffset = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadowOffset(c, c.in_[0][2], c.in_[0][0], c.in_[0][1], p.lod, deMath.swizzle(p.offset, [0,1]));
+ };
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadowOffsetBias = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadowOffset(c, c.in_[0][2], c.in_[0][0], c.in_[0][1], p.lod+c.in_[1][0], deMath.swizzle(p.offset, [0,1]));
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadowProjOffset = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadowOffset(c, c.in_[0][2]/c.in_[0][3], c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], p.lod, deMath.swizzle(p.offset, [0,1]));
+ };
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadowProjOffsetBias = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadowOffset(c, c.in_[0][2]/c.in_[0][3], c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], p.lod+c.in_[1][0], deMath.swizzle(p.offset, [0,1]));
+ };
+
+ // Gradient variarts
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DGrad = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2D(c, c.in_[0][0], c.in_[0][1], es3fShaderTextureFunctionTests.computeLodFromGrad2D(c)), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTextureCubeGrad = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.textureCube(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], es3fShaderTextureFunctionTests.computeLodFromGradCube(c)), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DArrayGrad = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DArray(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], es3fShaderTextureFunctionTests.computeLodFromGrad2DArray(c)), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3DGrad = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3D(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], es3fShaderTextureFunctionTests.computeLodFromGrad3D(c)), p.scale), p.bias);
+ };
+
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadowGrad = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadow(c, c.in_[0][2], c.in_[0][0], c.in_[0][1], es3fShaderTextureFunctionTests.computeLodFromGrad2D(c));
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTextureCubeShadowGrad = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.textureCubeShadow(c, c.in_[0][3], c.in_[0][0], c.in_[0][1], c.in_[0][2], es3fShaderTextureFunctionTests.computeLodFromGradCube(c));
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DArrayShadowGrad = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DArrayShadow(c, c.in_[0][3], c.in_[0][0], c.in_[0][1], c.in_[0][2], es3fShaderTextureFunctionTests.computeLodFromGrad2DArray(c));
+ };
+
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DGradOffset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DOffset(c, c.in_[0][0], c.in_[0][1], es3fShaderTextureFunctionTests.computeLodFromGrad2D(c), deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DArrayGradOffset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DArrayOffset(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], es3fShaderTextureFunctionTests.computeLodFromGrad2DArray(c), deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3DGradOffset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3DOffset(c, c.in_[0][0], c.in_[0][1], c.in_[0][2], es3fShaderTextureFunctionTests.computeLodFromGrad3D(c), p.offset), p.scale), p.bias);
+ };
+
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadowGradOffset = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadowOffset(c, c.in_[0][2], c.in_[0][0], c.in_[0][1], es3fShaderTextureFunctionTests.computeLodFromGrad2D(c), deMath.swizzle(p.offset, [0,1]));
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DArrayShadowGradOffset = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DArrayShadowOffset(c, c.in_[0][3], c.in_[0][0], c.in_[0][1], c.in_[0][2], es3fShaderTextureFunctionTests.computeLodFromGrad2DArray(c), deMath.swizzle(p.offset, [0,1]));
+ };
+
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadowProjGrad = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadow(c, c.in_[0][2]/c.in_[0][3], c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], es3fShaderTextureFunctionTests.computeLodFromGrad2D(c));
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DShadowProjGradOffset = function(c, p) {
+ c.color[0] = es3fShaderTextureFunctionTests.texture2DShadowOffset(c, c.in_[0][2]/c.in_[0][3], c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], es3fShaderTextureFunctionTests.computeLodFromGrad2D(c), deMath.swizzle(p.offset, [0,1]));
+ };
+
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProjGrad3 = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2D(c, c.in_[0][0]/c.in_[0][2], c.in_[0][1]/c.in_[0][2], es3fShaderTextureFunctionTests.computeLodFromGrad2D(c)), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProjGrad = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2D(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], es3fShaderTextureFunctionTests.computeLodFromGrad2D(c)), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3DProjGrad = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3D(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], c.in_[0][2]/c.in_[0][3], es3fShaderTextureFunctionTests.computeLodFromGrad3D(c)), p.scale), p.bias);
+ };
+
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProjGrad3Offset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DOffset(c, c.in_[0][0]/c.in_[0][2], c.in_[0][1]/c.in_[0][2], es3fShaderTextureFunctionTests.computeLodFromGrad2D(c), deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture2DProjGradOffset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture2DOffset(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], es3fShaderTextureFunctionTests.computeLodFromGrad2D(c), deMath.swizzle(p.offset, [0,1])), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexture3DProjGradOffset = function(c, p) {
+ c.color = deMath.add(deMath.multiply(es3fShaderTextureFunctionTests.texture3DOffset(c, c.in_[0][0]/c.in_[0][3], c.in_[0][1]/c.in_[0][3], c.in_[0][2]/c.in_[0][3], es3fShaderTextureFunctionTests.computeLodFromGrad3D(c), p.offset), p.scale), p.bias);
+ };
+
+ // Texel fetch variants
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexelFetch2D = function(c, p) {
+ /** @type {number} */ var x = Math.trunc(c.in_[0][0]) + p.offset[0];
+ /** @type {number} */ var y = Math.trunc(c.in_[0][1]) + p.offset[1];
+ /** @type {number} */ var lod = Math.trunc(c.in_[1][0]);
+ c.color = deMath.add(deMath.multiply(c.textures[0].tex2D.getLevel(lod).getPixel(x, y), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexelFetch2DArray = function(c, p) {
+ /** @type {number} */ var x = Math.trunc(c.in_[0][0]) + p.offset[0];
+ /** @type {number} */ var y = Math.trunc(c.in_[0][1]) + p.offset[1];
+ /** @type {number} */ var l = Math.trunc(c.in_[0][2]);
+ /** @type {number} */ var lod = Math.trunc(c.in_[1][0]);
+ c.color = deMath.add(deMath.multiply(c.textures[0].tex2DArray.getLevel(lod).getPixel(x, y, l), p.scale), p.bias);
+ };
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} c
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} p
+ */
+ es3fShaderTextureFunctionTests.evalTexelFetch3D = function(c, p) {
+ /** @type {number} */ var x = Math.trunc(c.in_[0][0]) + p.offset[0];
+ /** @type {number} */ var y = Math.trunc(c.in_[0][1]) + p.offset[1];
+ /** @type {number} */ var z = Math.trunc(c.in_[0][2]) + p.offset[2];
+ /** @type {number} */ var lod = Math.trunc(c.in_[1][0]);
+ c.color = deMath.add(deMath.multiply(c.textures[0].tex3D.getLevel(lod).getPixel(x, y, z), p.scale), p.bias);
+ };
+
+ /**
+ * @constructor
+ * @extends {glsShaderRenderCase.ShaderEvaluator}
+ * @param {es3fShaderTextureFunctionTests.TexEvalFunc} evalFunc
+ * @param {es3fShaderTextureFunctionTests.TexLookupParams} lookupParams
+ */
+ es3fShaderTextureFunctionTests.TexLookupEvaluator = function(evalFunc, lookupParams) {
+ /** @type {es3fShaderTextureFunctionTests.TexEvalFunc} */ this.m_evalFunc = evalFunc;
+ /** @type {es3fShaderTextureFunctionTests.TexLookupParams} */ this.m_lookupParams = lookupParams;
+ };
+
+ es3fShaderTextureFunctionTests.TexLookupEvaluator.prototype = Object.create(glsShaderRenderCase.ShaderEvaluator.prototype);
+ es3fShaderTextureFunctionTests.TexLookupEvaluator.prototype.constructor = es3fShaderTextureFunctionTests.TexLookupEvaluator;
+
+ /**
+ * @param {glsShaderRenderCase.ShaderEvalContext} ctx
+ */
+ es3fShaderTextureFunctionTests.TexLookupEvaluator.prototype.evaluate = function(ctx) {
+ this.m_evalFunc(ctx, this.m_lookupParams);
+ };
+
+ /**
+ * @constructor
+ * @extends {glsShaderRenderCase.ShaderRenderCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {es3fShaderTextureFunctionTests.TextureLookupSpec} lookup
+ * @param {es3fShaderTextureFunctionTests.TextureSpec} texture
+ * @param {es3fShaderTextureFunctionTests.TexEvalFunc} evalFunc
+ * @param {boolean} isVertexCase
+ */
+ es3fShaderTextureFunctionTests.ShaderTextureFunctionCase = function(name, desc, lookup, texture, evalFunc, isVertexCase) {
+ glsShaderRenderCase.ShaderRenderCase.call(this, name, desc, isVertexCase);
+
+ /** @type {es3fShaderTextureFunctionTests.TextureLookupSpec} */ this.m_lookupSpec = lookup;
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ this.m_textureSpec = texture;
+ /** @type {es3fShaderTextureFunctionTests.TexLookupParams} */ this.m_lookupParams = new es3fShaderTextureFunctionTests.TexLookupParams();
+ /** @type {es3fShaderTextureFunctionTests.TexLookupEvaluator} */ this.m_evaluator = new es3fShaderTextureFunctionTests.TexLookupEvaluator(evalFunc, this.m_lookupParams);
+
+ /** @type {gluTexture.Texture2D} */ this.m_texture2D = null;
+ /** @type {gluTexture.TextureCube} */ this.m_textureCube = null;
+ /** @type {gluTexture.Texture2DArray} */ this.m_texture2DArray = null;
+ /** @type {gluTexture.Texture3D} */ this.m_texture3D = null;
+ };
+
+ es3fShaderTextureFunctionTests.ShaderTextureFunctionCase.prototype = Object.create(glsShaderRenderCase.ShaderRenderCase.prototype);
+ es3fShaderTextureFunctionTests.ShaderTextureFunctionCase.prototype.constructor = es3fShaderTextureFunctionTests.ShaderTextureFunctionCase;
+
+ es3fShaderTextureFunctionTests.ShaderTextureFunctionCase.prototype.init = function() {
+
+ // Base coord scale & bias
+ /** @type {(Array<number>|number)} */ var s = deMath.subtract(this.m_lookupSpec.maxCoord, this.m_lookupSpec.minCoord);
+ /** @type {(Array<number>|number)} */ var b = this.m_lookupSpec.minCoord;
+
+ /** @type {Array<number>} */ var baseCoordTrans = [
+ s[0], 0.0, 0.0, b[0],
+ 0.0, s[1], 0., b[1],
+ s[2]/2.0, -s[2]/2.0, 0.0, s[2]/2.0 + b[2],
+ -s[3]/2.0, s[3]/2.0, 0.0, s[3]/2.0 + b[3]
+ ];
+ this.m_userAttribTransforms.push(tcuMatrix.matrixFromArray(4, 4, baseCoordTrans));
+
+ /** @type {boolean} */ var hasLodBias = es3fShaderTextureFunctionTests.functionHasLod(this.m_lookupSpec.func) || this.m_lookupSpec.useBias;
+ /** @type {boolean} */ var isGrad = es3fShaderTextureFunctionTests.functionHasGrad(this.m_lookupSpec.func);
+ assertMsgOptions(!isGrad || !hasLodBias, 'Assert Error. expected: isGrad || hasLodBias === false', false, true);
+
+ if (hasLodBias) {
+ s = this.m_lookupSpec.maxLodBias - this.m_lookupSpec.minLodBias;
+ b = this.m_lookupSpec.minLodBias;
+ /** @type {Array<number>} */ var lodCoordTrans = [
+ s/2.0, s/2.0, 0.0, b,
+ 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0
+ ];
+
+ this.m_userAttribTransforms.push(tcuMatrix.matrixFromArray(4, 4, lodCoordTrans));
+ }
+ else if (isGrad) {
+ /** @type {Array<number>} */ var sx = deMath.subtract(this.m_lookupSpec.maxDX, this.m_lookupSpec.minDX);
+ /** @type {Array<number>} */ var sy = deMath.subtract(this.m_lookupSpec.maxDY, this.m_lookupSpec.minDY);
+ /** @type {Array<number>} */ var gradDxTrans = [
+ sx[0]/2.0, sx[0]/2.0, 0.0, this.m_lookupSpec.minDX[0],
+ sx[1]/2.0, sx[1]/2.0, 0.0, this.m_lookupSpec.minDX[1],
+ sx[2]/2.0, sx[2]/2.0, 0.0, this.m_lookupSpec.minDX[2],
+ 0.0, 0.0, 0.0, 0.0
+ ];
+ /** @type {Array<number>} */ var gradDyTrans = [
+ -sy[0]/2.0, -sy[0]/2.0, 0.0, this.m_lookupSpec.maxDY[0],
+ -sy[1]/2.0, -sy[1]/2.0, 0.0, this.m_lookupSpec.maxDY[1],
+ -sy[2]/2.0, -sy[2]/2.0, 0.0, this.m_lookupSpec.maxDY[2],
+ 0.0, 0.0, 0.0, 0.0
+ ];
+
+ this.m_userAttribTransforms.push(tcuMatrix.matrixFromArray(4, 4, gradDxTrans));
+ this.m_userAttribTransforms.push(tcuMatrix.matrixFromArray(4, 4, gradDyTrans));
+ }
+
+ this.initShaderSources();
+ this.initTexture();
+
+ this.postinit();
+
+ };
+
+ es3fShaderTextureFunctionTests.ShaderTextureFunctionCase.prototype.initTexture = function() {
+ /** @type {Array<Array<number>>} */ var texCubeSwz = [
+ [0, 0, 1, 1],
+ [1, 1, 0, 0],
+ [0, 1, 0, 1],
+ [1, 0, 1, 0],
+ [0, 1, 1, 0],
+ [1, 0, 0, 1]
+ ];
+
+ assertMsgOptions(texCubeSwz.length === 6, 'Cube should have 6 faces.', false, true);
+
+ /** @type {number} */ var levelStep;
+ /** @type {Array<number>} */ var cScale;
+ /** @type {Array<number>} */ var cBias;
+ /** @type {number} */ var baseCellSize;
+
+ /** @type {number} */ var fA;
+ /** @type {number} */ var fB;
+ /** @type {Array<number>} */ var colorA;
+ /** @type {Array<number>} */ var colorB;
+
+ /** @type {number} */ var dudx;
+ /** @type {number} */ var dvdy;
+
+ /** @type {tcuTexture.TextureFormat} */ var texFmt = gluTextureUtil.mapGLInternalFormat(this.m_textureSpec.format);
+ /** @type {tcuTextureUtil.TextureFormatInfo} */ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
+ /** @type {Array<number>} */ var viewportSize = this.getViewportSize();
+ /** @type {boolean} */ var isProj = es3fShaderTextureFunctionTests.functionHasProj(this.m_lookupSpec.func);
+ /** @type {boolean} */ var isAutoLod = es3fShaderTextureFunctionTests.functionHasAutoLod(
+ this.m_isVertexCase ? gluShaderProgram.shaderType.VERTEX : gluShaderProgram.shaderType.FRAGMENT,
+ this.m_lookupSpec.func); // LOD can vary significantly
+ /** @type {number} */ var proj = isProj ?
+ 1.0 / this.m_lookupSpec.minCoord[this.m_lookupSpec.func === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3 ? 2 : 3] :
+ 1.0;
+
+ switch (this.m_textureSpec.type) {
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D:
+ levelStep = isAutoLod ? 0.0 : 1.0 / Math.max(1, this.m_textureSpec.numLevels - 1);
+ cScale = deMath.subtract(fmtInfo.valueMax, fmtInfo.valueMin);
+ cBias = fmtInfo.valueMin;
+ baseCellSize = Math.min(this.m_textureSpec.width / 4, this.m_textureSpec.height / 4);
+
+ this.m_texture2D = gluTexture.texture2DFromInternalFormat(gl, this.m_textureSpec.format, this.m_textureSpec.width, this.m_textureSpec.height);
+ for (var level = 0; level < this.m_textureSpec.numLevels; level++) {
+ fA = level * levelStep;
+ fB = 1.0 - fA;
+ colorA = deMath.add(cBias, deMath.multiply(cScale, [fA, fB, fA, fB]));
+ colorB = deMath.add(cBias, deMath.multiply(cScale, [fB, fA, fB, fA]));
+
+ this.m_texture2D.getRefTexture().allocLevel(level);
+ tcuTextureUtil.fillWithGrid(this.m_texture2D.getRefTexture().getLevel(level), Math.max(1, baseCellSize >> level), colorA, colorB);
+ }
+ this.m_texture2D.upload();
+
+ // Compute LOD.
+ dudx = (this.m_lookupSpec.maxCoord[0] - this.m_lookupSpec.minCoord[0]) * proj * this.m_textureSpec.width / viewportSize[0];
+ dvdy = (this.m_lookupSpec.maxCoord[1] - this.m_lookupSpec.minCoord[1]) * proj * this.m_textureSpec.height / viewportSize[1];
+ this.m_lookupParams.lod = es3fShaderTextureFunctionTests.computeLodFromDerivates(dudx, 0.0, 0.0, dvdy);
+
+ // Append to texture list.
+ this.m_textures.push(new glsShaderRenderCase.TextureBinding(this.m_texture2D, this.m_textureSpec.sampler));
+ break;
+
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP:
+ levelStep = isAutoLod ? 0.0 : 1.0 / Math.max(1, this.m_textureSpec.numLevels - 1);
+ cScale = deMath.subtract(fmtInfo.valueMax, fmtInfo.valueMin);
+ cBias = fmtInfo.valueMin;
+ /** @type {Array<number>} */ var cCorner = deMath.add(cBias, deMath.scale(cScale, 0.5));
+ baseCellSize = Math.min(this.m_textureSpec.width / 4, this.m_textureSpec.height / 4);
+
+ assertMsgOptions(this.m_textureSpec.width === this.m_textureSpec.height, 'Expected width === height', false, true);
+ this.m_textureCube = gluTexture.cubeFromInternalFormat(gl, this.m_textureSpec.format, this.m_textureSpec.width);
+ for (var level = 0; level < this.m_textureSpec.numLevels; level++) {
+ fA = level * levelStep;
+ fB = 1.0 - fA;
+ /** @type {Array<number>} */ var f = [fA, fB];
+
+ for (var face = 0; face < 6; face++) {
+ /** @type {Array<number>} */ var swzA = texCubeSwz[face];
+ /** @type {Array<number>} */ var swzB = deMath.subtract([1, 1, 1, 1], swzA);
+ colorA = deMath.add(cBias, deMath.multiply(cScale, deMath.swizzle(f, [swzA[0], swzA[1], swzA[2], swzA[3]])));
+ colorB = deMath.add(cBias, deMath.multiply(cScale, deMath.swizzle(f, [swzB[0], swzB[1], swzB[2], swzB[3]])));
+
+ this.m_textureCube.getRefTexture().allocLevel(face, level);
+
+ /** @type {tcuTexture.PixelBufferAccess} */ var access = this.m_textureCube.getRefTexture().getLevelFace(level, face);
+ /** @type {number} */ var lastPix = access.getWidth() - 1;
+
+ tcuTextureUtil.fillWithGrid(access, Math.max(1, baseCellSize >> level), colorA, colorB);
+
+ // Ensure all corners have identical colors in order to avoid dealing with ambiguous corner texel filtering
+ access.setPixel(cCorner, 0, 0);
+ access.setPixel(cCorner, 0, lastPix);
+ access.setPixel(cCorner, lastPix, 0);
+ access.setPixel(cCorner, lastPix, lastPix);
+ }
+ }
+ this.m_textureCube.upload();
+
+ // Compute LOD \note Assumes that only single side is accessed and R is constant major axis.
+ assertMsgOptions(Math.abs(this.m_lookupSpec.minCoord[2] - this.m_lookupSpec.maxCoord[2]) < 0.005, 'Expected abs(minCoord-maxCoord) < 0.005', false, true);
+ assertMsgOptions(Math.abs(this.m_lookupSpec.minCoord[0]) < Math.abs(this.m_lookupSpec.minCoord[2]) && Math.abs(this.m_lookupSpec.maxCoord[0]) < Math.abs(this.m_lookupSpec.minCoord[2]), 'Assert error: minCoord, maxCoord', false, true);
+ assertMsgOptions(Math.abs(this.m_lookupSpec.minCoord[1]) < Math.abs(this.m_lookupSpec.minCoord[2]) && Math.abs(this.m_lookupSpec.maxCoord[1]) < Math.abs(this.m_lookupSpec.minCoord[2]), 'Assert error: minCoord, maxCoord', false, true);
+
+ /** @type {tcuTexture.CubeFaceCoords} */ var c00 = tcuTexture.getCubeFaceCoords([this.m_lookupSpec.minCoord[0] * proj, this.m_lookupSpec.minCoord[1] * proj, this.m_lookupSpec.minCoord[2] * proj]);
+ /** @type {tcuTexture.CubeFaceCoords} */ var c10 = tcuTexture.getCubeFaceCoords([this.m_lookupSpec.maxCoord[0] * proj, this.m_lookupSpec.minCoord[1] * proj, this.m_lookupSpec.minCoord[2] * proj]);
+ /** @type {tcuTexture.CubeFaceCoords} */ var c01 = tcuTexture.getCubeFaceCoords([this.m_lookupSpec.minCoord[0] * proj, this.m_lookupSpec.maxCoord[1] * proj, this.m_lookupSpec.minCoord[2] * proj]);
+ dudx = (c10.s - c00.s) * this.m_textureSpec.width / viewportSize[0];
+ dvdy = (c01.t - c00.t) * this.m_textureSpec.height / viewportSize[1];
+
+ this.m_lookupParams.lod = es3fShaderTextureFunctionTests.computeLodFromDerivates(dudx, 0.0, 0.0, dvdy);
+
+ this.m_textures.push(new glsShaderRenderCase.TextureBinding(this.m_textureCube, this.m_textureSpec.sampler));
+ break;
+
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY:
+ /** @type {number} */ var layerStep = 1.0 / this.m_textureSpec.depth;
+ levelStep = isAutoLod ? 0.0 : 1.0 / (Math.max(1, this.m_textureSpec.numLevels - 1) * this.m_textureSpec.depth);
+ cScale = deMath.subtract(fmtInfo.valueMax, fmtInfo.valueMin);
+ cBias = fmtInfo.valueMin;
+ baseCellSize = Math.min(this.m_textureSpec.width / 4, this.m_textureSpec.height / 4);
+
+ this.m_texture2DArray = gluTexture.texture2DArrayFromInternalFormat(gl,
+ this.m_textureSpec.format,
+ this.m_textureSpec.width,
+ this.m_textureSpec.height,
+ this.m_textureSpec.depth);
+
+ for (var level = 0; level < this.m_textureSpec.numLevels; level++) {
+ this.m_texture2DArray.getRefTexture().allocLevel(level);
+ /** @type {tcuTexture.PixelBufferAccess} */ var levelAccess = this.m_texture2DArray.getRefTexture().getLevel(level);
+
+ for (var layer = 0; layer < levelAccess.getDepth(); layer++) {
+ fA = layer * layerStep + level * levelStep;
+ fB = 1.0 - fA;
+ colorA = deMath.add(cBias, deMath.multiply(cScale, [fA, fB, fA, fB]));
+ colorB = deMath.add(cBias, deMath.multiply(cScale, [fB, fA, fB, fA]));
+
+ tcuTextureUtil.fillWithGrid(tcuTextureUtil.getSubregion(levelAccess, 0, 0, layer, levelAccess.getWidth(), levelAccess.getHeight(), 1), Math.max(1, baseCellSize >> level), colorA, colorB);
+ }
+ }
+ this.m_texture2DArray.upload();
+
+ // Compute LOD.
+ dudx = (this.m_lookupSpec.maxCoord[0] - this.m_lookupSpec.minCoord[0]) * proj * this.m_textureSpec.width / viewportSize[0];
+ dvdy = (this.m_lookupSpec.maxCoord[1] - this.m_lookupSpec.minCoord[1]) * proj * this.m_textureSpec.height / viewportSize[1];
+ this.m_lookupParams.lod = es3fShaderTextureFunctionTests.computeLodFromDerivates(dudx, 0.0, 0.0, dvdy);
+
+ // Append to texture list.
+ this.m_textures.push(new glsShaderRenderCase.TextureBinding(this.m_texture2DArray, this.m_textureSpec.sampler));
+ break;
+
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D:
+ levelStep = isAutoLod ? 0.0 : 1.0 / Math.max(1, this.m_textureSpec.numLevels - 1);
+ cScale = deMath.subtract(fmtInfo.valueMax, fmtInfo.valueMin);
+ cBias = fmtInfo.valueMin;
+ baseCellSize = Math.min(this.m_textureSpec.width / 2, this.m_textureSpec.height / 2, this.m_textureSpec.depth / 2);
+
+ this.m_texture3D = gluTexture.texture3DFromInternalFormat(gl, this.m_textureSpec.format, this.m_textureSpec.width, this.m_textureSpec.height, this.m_textureSpec.depth);
+ for (var level = 0; level < this.m_textureSpec.numLevels; level++) {
+ fA = level * levelStep;
+ fB = 1.0 - fA;
+ colorA = deMath.add(cBias, deMath.multiply(cScale, [fA, fB, fA, fB]));
+ colorB = deMath.add(cBias, deMath.multiply(cScale, [fB, fA, fB, fA]));
+
+ this.m_texture3D.getRefTexture().allocLevel(level);
+ tcuTextureUtil.fillWithGrid(this.m_texture3D.getRefTexture().getLevel(level), Math.max(1, baseCellSize >> level), colorA, colorB);
+ }
+ this.m_texture3D.upload();
+
+ // Compute LOD.
+ dudx = (this.m_lookupSpec.maxCoord[0] - this.m_lookupSpec.minCoord[0]) * proj * this.m_textureSpec.width / viewportSize[0];
+ dvdy = (this.m_lookupSpec.maxCoord[1] - this.m_lookupSpec.minCoord[1]) * proj * this.m_textureSpec.height / viewportSize[1];
+ /** @type {number} */ var dwdx = (this.m_lookupSpec.maxCoord[2] - this.m_lookupSpec.minCoord[2]) * 0.5 * proj * this.m_textureSpec.depth / viewportSize[0];
+ /** @type {number} */ var dwdy = (this.m_lookupSpec.maxCoord[2] - this.m_lookupSpec.minCoord[2]) * 0.5 * proj * this.m_textureSpec.depth / viewportSize[1];
+ this.m_lookupParams.lod = es3fShaderTextureFunctionTests.computeLodFromDerivates(dudx, 0.0, dwdx, 0.0, dvdy, dwdy);
+
+ // Append to texture list.
+ this.m_textures.push(new glsShaderRenderCase.TextureBinding(this.m_texture3D, this.m_textureSpec.sampler));
+ break;
+
+ default:
+ throw new Error('Texture type not supported.');
+ }
+
+ // Set lookup scale & bias
+ this.m_lookupParams.scale = fmtInfo.lookupScale;
+ this.m_lookupParams.bias = fmtInfo.lookupBias;
+ this.m_lookupParams.offset = this.m_lookupSpec.offset;
+ };
+
+ es3fShaderTextureFunctionTests.ShaderTextureFunctionCase.prototype.initShaderSources = function() {
+ /** @type {es3fShaderTextureFunctionTests.TexFunction} */ var function_ = this.m_lookupSpec.func;
+ /** @type {boolean} */ var isVtxCase = this.m_isVertexCase;
+ /** @type {boolean} */ var isProj = es3fShaderTextureFunctionTests.functionHasProj(function_);
+ /** @type {boolean} */ var isGrad = es3fShaderTextureFunctionTests.functionHasGrad(function_);
+ /** @type {boolean} */ var isShadow = this.m_textureSpec.sampler.compare !== tcuTexture.CompareMode.COMPAREMODE_NONE;
+ /** @type {boolean} */ var is2DProj4 = !isShadow && this.m_textureSpec.type === es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D && (function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ || function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD || function_ === es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD);
+ /** @type {boolean} */ var isIntCoord = function_ === es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH;
+ /** @type {boolean} */ var hasLodBias = es3fShaderTextureFunctionTests.functionHasLod(this.m_lookupSpec.func) || this.m_lookupSpec.useBias;
+ /** @type {number} */ var texCoordComps = this.m_textureSpec.type === es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D ? 2 : 3;
+ /** @type {number} */ var extraCoordComps = (isProj ? (is2DProj4 ? 2 : 1) : 0) + (isShadow ? 1 : 0);
+ /** @type {gluShaderUtil.DataType} */ var coordType = gluShaderUtil.getDataTypeVector(gluShaderUtil.DataType.FLOAT, texCoordComps+extraCoordComps);
+ /** @type {gluShaderUtil.precision} */ var coordPrec = gluShaderUtil.precision.PRECISION_HIGHP;
+ /** @type {string} */ var coordTypeName = gluShaderUtil.getDataTypeName(coordType);
+ /** @type {string} */ var coordPrecName = gluShaderUtil.getPrecisionName(coordPrec);
+ /** @type {tcuTexture.TextureFormat} */ var texFmt = gluTextureUtil.mapGLInternalFormat(this.m_textureSpec.format);
+ /** @type {?gluShaderUtil.DataType} */ var samplerType = null;
+ /** @type {gluShaderUtil.DataType} */ var gradType = (this.m_textureSpec.type === es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP || this.m_textureSpec.type === es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D) ? gluShaderUtil.DataType.FLOAT_VEC3 : gluShaderUtil.DataType.FLOAT_VEC2;
+ /** @type {string} */ var gradTypeName = gluShaderUtil.getDataTypeName(gradType);
+ /** @type {string} */ var baseFuncName = '';
+
+ assertMsgOptions(!isGrad || !hasLodBias, 'Expected !isGrad || !hasLodBias', false, true);
+
+ switch (this.m_textureSpec.type) {
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D:
+ samplerType = isShadow ? gluShaderUtil.DataType.SAMPLER_2D_SHADOW : gluTextureUtil.getSampler2DType(texFmt);
+ break;
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP:
+ samplerType = isShadow ? gluShaderUtil.DataType.SAMPLER_CUBE_SHADOW : gluTextureUtil.getSamplerCubeType(texFmt);
+ break;
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY:
+ samplerType = isShadow ? gluShaderUtil.DataType.SAMPLER_2D_ARRAY_SHADOW : gluTextureUtil.getSampler2DArrayType(texFmt);
+ break;
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D:
+ assertMsgOptions(!isShadow, 'Expected !isShadow', false, true);
+ samplerType = gluTextureUtil.getSampler3DType(texFmt);
+ break;
+ default:
+ throw new Error('Unexpected type.');
+ }
+
+ switch (this.m_lookupSpec.func) {
+ case es3fShaderTextureFunctionTests.TexFunction.TEXTURE: baseFuncName = 'texture'; break;
+ case es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ: baseFuncName = 'textureProj'; break;
+ case es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3: baseFuncName = 'textureProj'; break;
+ case es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD: baseFuncName = 'textureLod'; break;
+ case es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD: baseFuncName = 'textureProjLod'; break;
+ case es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD3: baseFuncName = 'textureProjLod'; break;
+ case es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD: baseFuncName = 'textureGrad'; break;
+ case es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD: baseFuncName = 'textureProjGrad'; break;
+ case es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD3: baseFuncName = 'textureProjGrad'; break;
+ case es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH: baseFuncName = 'texelFetch'; break;
+ default:
+ throw new Error('Unexpected function.');
+ }
+
+ /** @type {string} */ var vert = '';
+ /** @type {string} */ var frag = '';
+ /** @type {string} */ var op = '';
+
+ vert += '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'in ' + coordPrecName + ' ' + coordTypeName + ' a_in0;\n';
+
+ if (isGrad) {
+ vert += 'in ' + coordPrecName + ' ' + gradTypeName + ' a_in1;\n';
+ vert += 'in ' + coordPrecName + ' ' + gradTypeName + ' a_in2;\n';
+ }
+ else if (hasLodBias)
+ vert += 'in ' + coordPrecName + ' float a_in1;\n';
+
+ frag += '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ if (isVtxCase) {
+ vert += 'out mediump vec4 v_color;\n';
+ frag += 'in mediump vec4 v_color;\n';
+ }
+ else
+ {
+ vert += 'out ' + coordPrecName + ' ' + coordTypeName + ' v_texCoord;\n';
+ frag += 'in ' + coordPrecName + ' ' + coordTypeName + ' v_texCoord;\n';
+
+ if (isGrad) {
+ vert += 'out ' + coordPrecName + ' ' + gradTypeName + ' v_gradX;\n';
+ vert += 'out ' + coordPrecName + ' ' + gradTypeName + ' v_gradY;\n';
+ frag += 'in ' + coordPrecName + ' ' + gradTypeName + ' v_gradX;\n';
+ frag += 'in ' + coordPrecName + ' ' + gradTypeName + ' v_gradY;\n';
+ }
+
+ if (hasLodBias) {
+ vert += 'out ' + coordPrecName + ' float v_lodBias;\n';
+ frag += 'in ' + coordPrecName + ' float v_lodBias;\n';
+ }
+ }
+
+ // Uniforms
+ op += 'uniform highp ' + gluShaderUtil.getDataTypeName(samplerType) + ' u_sampler;\n' +
+ 'uniform highp vec4 u_scale;\n' +
+ 'uniform highp vec4 u_bias;\n';
+
+ vert += isVtxCase ? op : '';
+ frag += isVtxCase ? '' : op;
+ op = '';
+
+ vert += '\nvoid main()\n{\n' +
+ '\tgl_Position = a_position;\n';
+ frag += '\nvoid main()\n{\n';
+
+ if (isVtxCase)
+ vert += '\tv_color = ';
+ else
+ frag += '\to_color = ';
+
+ // Op.
+ /** @type {string} */ var texCoord = isVtxCase ? 'a_in0' : 'v_texCoord';
+ /** @type {string} */ var gradX = isVtxCase ? 'a_in1' : 'v_gradX';
+ /** @type {string} */ var gradY = isVtxCase ? 'a_in2' : 'v_gradY';
+ /** @type {string} */ var lodBias = isVtxCase ? 'a_in1' : 'v_lodBias';
+
+ op += 'vec4(' + baseFuncName;
+ if (this.m_lookupSpec.useOffset)
+ op += 'Offset';
+ op += '(u_sampler, ';
+
+ if (isIntCoord)
+ op += 'ivec' + (texCoordComps+extraCoordComps) + '(';
+
+ op += texCoord;
+
+ if (isIntCoord)
+ op += ')';
+
+ if (isGrad)
+ op += ', ' + gradX + ', ' + gradY;
+
+ if (es3fShaderTextureFunctionTests.functionHasLod(function_)) {
+ if (isIntCoord)
+ op += ', int(' + lodBias + ')';
+ else
+ op += ', ' + lodBias;
+ }
+
+ if (this.m_lookupSpec.useOffset) {
+ /** @type {number} */ var offsetComps = this.m_textureSpec.type === es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D ? 3 : 2;
+
+ op += ', ivec' + offsetComps + '(';
+ for (var ndx = 0; ndx < offsetComps; ndx++) {
+ if (ndx !== 0)
+ op += ', ';
+ op += this.m_lookupSpec.offset[ndx];
+ }
+ op += ')';
+ }
+
+ if (this.m_lookupSpec.useBias)
+ op += ', ' + lodBias;
+
+ op += ')';
+
+ if (isShadow)
+ op += ', 0.0, 0.0, 1.0)';
+ else
+ op += ')*u_scale + u_bias';
+
+ op += ';\n';
+
+ vert += isVtxCase ? op : '';
+ frag += isVtxCase ? '' : op;
+ op = '';
+
+ if (isVtxCase)
+ frag += '\to_color = v_color;\n';
+ else {
+ vert += '\tv_texCoord = a_in0;\n';
+
+ if (isGrad) {
+ vert += '\tv_gradX = a_in1;\n';
+ vert += '\tv_gradY = a_in2;\n';
+ }
+ else if (hasLodBias)
+ vert += '\tv_lodBias = a_in1;\n';
+ }
+
+ vert += '}\n';
+ frag += '}\n';
+
+ this.m_vertShaderSource = vert;
+ this.m_fragShaderSource = frag;
+ };
+
+ es3fShaderTextureFunctionTests.ShaderTextureFunctionCase.prototype.deinit = function() {
+ this.m_program = null;
+ this.m_texture2D = null;
+ this.m_textureCube = null;
+ this.m_texture2DArray = null;
+ this.m_texture3D = null;
+ };
+
+ /**
+ * @param {WebGLProgram} programID
+ * @param {Array<number>} constCoords
+ */
+ es3fShaderTextureFunctionTests.ShaderTextureFunctionCase.prototype.setupUniforms = function(programID, constCoords) {
+ gl.uniform1i(gl.getUniformLocation(programID, 'u_sampler'), 0);
+ gl.uniform4fv(gl.getUniformLocation(programID, 'u_scale'), this.m_lookupParams.scale);
+ gl.uniform4fv(gl.getUniformLocation(programID, 'u_bias'), this.m_lookupParams.bias);
+ };
+
+
+ /**
+ * @struct
+ * @constructor
+ * @param {Array<number>} textureSize
+ * @param {number} lod
+ * @param {number} lodBase
+ * @param {Array<number>} expectedSize
+ */
+ es3fShaderTextureFunctionTests.TestSize = function(textureSize, lod, lodBase, expectedSize) {
+ /** @type {Array<number>} */ this.textureSize = textureSize;
+ /** @type {number} */ this.lod = lod;
+ /** @type {number} */ this.lodBase = lodBase;
+ /** @type {Array<number>} */ this.expectedSize = expectedSize;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * @param {string} samplerType
+ * @param {es3fShaderTextureFunctionTests.TextureSpec} texture
+ * @param {boolean} isVertexCase
+ */
+ es3fShaderTextureFunctionTests.TextureSizeCase = function(name, desc, samplerType, texture, isVertexCase) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ /** @type {string} */ this.m_samplerTypeStr = samplerType;
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ this.m_textureSpec = texture;
+ /** @type {boolean} */ this.m_isVertexCase = isVertexCase;
+ /** @type {boolean} */ this.m_has3DSize = texture.type === es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D || texture.type === es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY;
+ /** @type {?gluShaderProgram.ShaderProgram} */ this.m_program = null;
+ /** @type {number} */ this.m_iterationCounter = 0;
+ };
+
+ es3fShaderTextureFunctionTests.TextureSizeCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderTextureFunctionTests.TextureSizeCase.prototype.constructor = es3fShaderTextureFunctionTests.TextureSizeCase;
+
+ es3fShaderTextureFunctionTests.TextureSizeCase.prototype.deinit = function() {
+ this.freeShader();
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fShaderTextureFunctionTests.TextureSizeCase.prototype.iterate = function() {
+ /** @type {number} */ var currentIteration = this.m_iterationCounter++;
+ /** @type {Array<es3fShaderTextureFunctionTests.TestSize>} */ var testSizes = [
+ new es3fShaderTextureFunctionTests.TestSize([1, 2, 1], 1, 0, [1, 1, 1]),
+ new es3fShaderTextureFunctionTests.TestSize([1, 2, 1], 0, 0, [1, 2, 1]),
+
+ new es3fShaderTextureFunctionTests.TestSize([1, 3, 2], 0, 0, [1, 3, 2]),
+ new es3fShaderTextureFunctionTests.TestSize([1, 3, 2], 1, 0, [1, 1, 1]),
+
+ new es3fShaderTextureFunctionTests.TestSize([100, 31, 18], 0, 0, [100, 31, 18]),
+ new es3fShaderTextureFunctionTests.TestSize([100, 31, 18], 1, 0, [50, 15, 9]),
+ new es3fShaderTextureFunctionTests.TestSize([100, 31, 18], 2, 0, [25, 7, 4]),
+ new es3fShaderTextureFunctionTests.TestSize([100, 31, 18], 3, 0, [12, 3, 2]),
+ new es3fShaderTextureFunctionTests.TestSize([100, 31, 18], 4, 0, [6, 1, 1]),
+ new es3fShaderTextureFunctionTests.TestSize([100, 31, 18], 5, 0, [3, 1, 1]),
+ new es3fShaderTextureFunctionTests.TestSize([100, 31, 18], 6, 0, [1, 1, 1]),
+
+ new es3fShaderTextureFunctionTests.TestSize([100, 128, 32], 0, 0, [100, 128, 32]),
+ new es3fShaderTextureFunctionTests.TestSize([100, 128, 32], 1, 0, [50, 64, 16]),
+ new es3fShaderTextureFunctionTests.TestSize([100, 128, 32], 2, 0, [25, 32, 8]),
+ new es3fShaderTextureFunctionTests.TestSize([100, 128, 32], 3, 0, [12, 16, 4]),
+ new es3fShaderTextureFunctionTests.TestSize([100, 128, 32], 4, 0, [6, 8, 2]),
+ new es3fShaderTextureFunctionTests.TestSize([100, 128, 32], 5, 0, [3, 4, 1]),
+ new es3fShaderTextureFunctionTests.TestSize([100, 128, 32], 6, 0, [1, 2, 1]),
+ new es3fShaderTextureFunctionTests.TestSize([100, 128, 32], 7, 0, [1, 1, 1]),
+
+ // pow 2
+ new es3fShaderTextureFunctionTests.TestSize([128, 64, 32], 0, 0, [128, 64, 32]),
+ new es3fShaderTextureFunctionTests.TestSize([128, 64, 32], 1, 0, [64, 32, 16]),
+ new es3fShaderTextureFunctionTests.TestSize([128, 64, 32], 2, 0, [32, 16, 8]),
+ new es3fShaderTextureFunctionTests.TestSize([128, 64, 32], 3, 0, [16, 8, 4]),
+ new es3fShaderTextureFunctionTests.TestSize([128, 64, 32], 4, 0, [8, 4, 2]),
+ new es3fShaderTextureFunctionTests.TestSize([128, 64, 32], 5, 0, [4, 2, 1]),
+ new es3fShaderTextureFunctionTests.TestSize([128, 64, 32], 6, 0, [2, 1, 1]),
+ new es3fShaderTextureFunctionTests.TestSize([128, 64, 32], 7, 0, [1, 1, 1]),
+
+ // w === h
+ new es3fShaderTextureFunctionTests.TestSize([1, 1, 1], 0, 0, [1, 1, 1]),
+ new es3fShaderTextureFunctionTests.TestSize([64, 64, 64], 0, 0, [64, 64, 64]),
+ new es3fShaderTextureFunctionTests.TestSize([64, 64, 64], 1, 0, [32, 32, 32]),
+ new es3fShaderTextureFunctionTests.TestSize([64, 64, 64], 2, 0, [16, 16, 16]),
+ new es3fShaderTextureFunctionTests.TestSize([64, 64, 64], 3, 0, [8, 8, 8]),
+ new es3fShaderTextureFunctionTests.TestSize([64, 64, 64], 4, 0, [4, 4, 4]),
+
+ // with lod base
+ new es3fShaderTextureFunctionTests.TestSize([100, 31, 18], 3, 1, [6, 1, 1]),
+ new es3fShaderTextureFunctionTests.TestSize([128, 64, 32], 3, 1, [8, 4, 2]),
+ new es3fShaderTextureFunctionTests.TestSize([64, 64, 64], 1, 1, [16, 16, 16])
+
+ ];
+ /** @type {number} */ var lastIterationIndex = testSizes.length + 1;
+
+ if (currentIteration === 0) {
+ return this.initShader() ? tcuTestCase.IterateResult.CONTINUE : tcuTestCase.IterateResult.STOP;
+ }
+ else if (currentIteration === lastIterationIndex) {
+ this.freeShader();
+ return tcuTestCase.IterateResult.STOP;
+ }
+ else {
+ if (!this.testTextureSize(testSizes[currentIteration - 1]))
+ testFailedOptions('Fail: Case ' + (currentIteration - 1) + ' Got unexpected texture size', false);
+ else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.CONTINUE;
+ }
+ };
+
+ /**
+ * @return {boolean}
+ */
+ es3fShaderTextureFunctionTests.TextureSizeCase.prototype.initShader = function() {
+ /** @type {string} */ var vertSrc = this.genVertexShader();
+ /** @type {string} */ var fragSrc = this.genFragmentShader();
+
+ assertMsgOptions(this.m_program === null, 'Program should be null', false, true);
+ this.m_program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertSrc, fragSrc));
+
+ if (!this.m_program.isOk()) {
+ testFailedOptions('Fail: Shader failed', false);
+ return false;
+ }
+
+ return true;
+ };
+
+ es3fShaderTextureFunctionTests.TextureSizeCase.prototype.freeShader = function() {
+ this.m_program = null;
+ };
+
+ /**
+ * @param {es3fShaderTextureFunctionTests.TestSize} testSize
+ * @return {boolean}
+ */
+ es3fShaderTextureFunctionTests.TextureSizeCase.prototype.testTextureSize = function(testSize) {
+ /** @type {Array<number>} */ var triangle = [ // covers entire viewport
+ -1, -1, 0, 1, // was a 3x4 matrix
+ 4, -1, 0, 1,
+ -1, 4, 0, 1
+ ];
+
+ /** @type {number} */ var positionLoc = gl.getAttribLocation(this.m_program.getProgram(), 'a_position');
+ /** @type {WebGLUniformLocation} */ var samplerLoc = gl.getUniformLocation(this.m_program.getProgram(), 'u_sampler');
+ /** @type {WebGLUniformLocation} */ var sizeLoc = gl.getUniformLocation(this.m_program.getProgram(), 'u_texSize');
+ /** @type {WebGLUniformLocation} */ var lodLoc = gl.getUniformLocation(this.m_program.getProgram(), 'u_lod');
+ /** @type {number} */ var textureTarget = this.getGLTextureTarget();
+ /** @type {boolean} */ var isSquare = testSize.textureSize[0] === testSize.textureSize[1];
+ /** @type {boolean} */ var is2DLodValid = (testSize.textureSize[0] >> (testSize.lod + testSize.lodBase)) !== 0 || (testSize.textureSize[1] >> (testSize.lod + testSize.lodBase)) !== 0;
+ /** @type {boolean} */ var success = true;
+ /** @type {number} */ var errorValue;
+
+ // Skip incompatible cases
+ if (this.m_textureSpec.type === es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP && !isSquare)
+ return true;
+ if (this.m_textureSpec.type === es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D && !is2DLodValid)
+ return true;
+ if (this.m_textureSpec.type === es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY && !is2DLodValid)
+ return true;
+
+ // setup rendering
+ gl.useProgram(this.m_program.getProgram());
+ gl.uniform1i(samplerLoc, 0);
+ gl.clearColor(0.5, 0.5, 0.5, 1.0);
+ gl.viewport(0, 0, 1, 1);
+
+ /** @type {WebGLBuffer} */ var triangleGlBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, triangleGlBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangle), gl.STATIC_DRAW);
+
+ gl.vertexAttribPointer(positionLoc, 4, gl.FLOAT, false, 0, 0);
+ gl.enableVertexAttribArray(positionLoc);
+
+ // setup texture
+ /** @type {number} */ var maxLevel = testSize.lod + testSize.lodBase;
+ /** @type {number} */ var levels = maxLevel + 1;
+ /** @type {?WebGLTexture} */ var texId = null;
+
+ // gen texture
+ texId = gl.createTexture();
+ gl.bindTexture(textureTarget, texId);
+ gl.texParameteri(textureTarget, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(textureTarget, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ gl.texParameteri(textureTarget, gl.TEXTURE_BASE_LEVEL, testSize.lodBase);
+ gl.texParameteri(textureTarget, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
+
+ // set up texture
+
+ switch (this.m_textureSpec.type) {
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D:
+ // bufferedLogToConsole('Testing image size ' + testSize.textureSize[0] + 'x' + testSize.textureSize[1] + 'x' + testSize.textureSize[2]);
+ // bufferedLogToConsole('Lod: ' + testSize.lod + ', base level: ' + testSize.lodBase);
+ // bufferedLogToConsole('Expecting: ' + testSize.expectedSize[0] + 'x' + testSize.expectedSize[1] + 'x' + testSize.expectedSize[2]);
+
+ gl.uniform3iv(sizeLoc, testSize.expectedSize);
+ gl.uniform1iv(lodLoc, [testSize.lod]);
+
+ gl.texStorage3D(textureTarget, levels, this.m_textureSpec.format, testSize.textureSize[0], testSize.textureSize[1], testSize.textureSize[2]);
+ break;
+
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D:
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP:
+ // bufferedLogToConsole('Testing image size ' + testSize.textureSize[0] + 'x' + testSize.textureSize[1]);
+ // bufferedLogToConsole('Lod: ' + testSize.lod + ', base level: ' + testSize.lodBase);
+ // bufferedLogToConsole('Expecting: ' + testSize.expectedSize[0] + 'x' + testSize.expectedSize[1]);
+
+ gl.uniform2iv(sizeLoc, testSize.expectedSize.slice(0,2));
+ gl.uniform1iv(lodLoc, [testSize.lod]);
+
+ gl.texStorage2D(textureTarget, levels, this.m_textureSpec.format, testSize.textureSize[0], testSize.textureSize[1]);
+ break;
+
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY:
+ /** @type {Array<number>} */ var expectedSize = [testSize.expectedSize[0], testSize.expectedSize[1], testSize.textureSize[2]];
+
+ // bufferedLogToConsole('Testing image size ' + testSize.textureSize[0] + 'x' + testSize.textureSize[1] + ' with ' + testSize.textureSize[2] + ' layer(s)');
+ // bufferedLogToConsole('Lod: ' + testSize.lod + ', base level: ' + testSize.lodBase);
+ // bufferedLogToConsole('Expecting: ' + testSize.expectedSize[0] + 'x' + testSize.expectedSize[1] + ' and ' + testSize.textureSize[2] + ' layer(s)');
+
+ gl.uniform3iv(sizeLoc, expectedSize);
+ gl.uniform1iv(lodLoc, [testSize.lod]);
+
+ gl.texStorage3D(textureTarget, levels, this.m_textureSpec.format, testSize.textureSize[0], testSize.textureSize[1], testSize.textureSize[2]);
+ break;
+
+ default:
+ throw new Error('Type not supported');
+ }
+
+ // test
+ /** @type {number} */ var colorTolerance = 0.1;
+ /** @type {tcuSurface.Surface} */ var sample = new tcuSurface.Surface(1, 1);
+ /** @type {Array<number>} */ var outputColor;
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+ gl.finish();
+
+ sample.readViewport(gl, [0, 0, 1, 1]);
+
+ outputColor = sample.getAccess().getPixel(0, 0);
+
+ if (outputColor[0] >= 1.0 - colorTolerance &&
+ outputColor[1] >= 1.0 - colorTolerance &&
+ outputColor[2] >= 1.0 - colorTolerance)
+ bufferedLogToConsole('Passed');
+ else {
+ // failure
+ bufferedLogToConsole('Failed');
+ success = false;
+ }
+
+ // free
+ gl.bindTexture(textureTarget, null);
+ gl.deleteTexture(texId);
+
+ gl.useProgram(null);
+
+ return success;
+ };
+
+ /**
+ * @return {string}
+ */
+ es3fShaderTextureFunctionTests.TextureSizeCase.prototype.genVertexShader = function() {
+ /** @type {string} */ var vert = '';
+ vert += '#version 300 es\n' +
+ 'in highp vec4 a_position;\n';
+
+ if (this.m_isVertexCase) {
+ vert += 'out mediump vec4 v_color;\n' +
+ 'uniform highp ' + this.m_samplerTypeStr + ' u_sampler;\n' +
+ 'uniform highp ivec' + (this.m_has3DSize ? 3 : 2) + ' u_texSize;\n' +
+ 'uniform highp int u_lod;\n';
+ }
+
+ vert += 'void main()\n{\n';
+
+ if (this.m_isVertexCase)
+ vert += ' v_color = (textureSize(u_sampler, u_lod) == u_texSize ? vec4(1.0, 1.0, 1.0, 1.0) : vec4(0.0, 0.0, 0.0, 1.0));\n';
+
+ vert += ' gl_Position = a_position;\n' +
+ '}\n';
+
+ return vert;
+ };
+
+ /**
+ * @return {string}
+ */
+ es3fShaderTextureFunctionTests.TextureSizeCase.prototype.genFragmentShader = function() {
+ /** @type {string} */ var frag = '';
+
+ frag += '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n';
+
+ if (this.m_isVertexCase)
+ frag += 'in mediump vec4 v_color;\n';
+
+ if (!this.m_isVertexCase) {
+ frag += 'uniform highp ' + this.m_samplerTypeStr + ' u_sampler;\n' +
+ 'uniform highp ivec' + (this.m_has3DSize ? 3 : 2) + ' u_texSize;\n' +
+ 'uniform highp int u_lod;\n';
+ }
+
+ frag += 'void main()\n{\n';
+
+ if (!this.m_isVertexCase)
+ frag += ' o_color = (textureSize(u_sampler, u_lod) == u_texSize ? vec4(1.0, 1.0, 1.0, 1.0) : vec4(0.0, 0.0, 0.0, 1.0));\n';
+ else
+ frag += ' o_color = v_color;\n';
+
+ frag += '}\n';
+
+ return frag;
+ };
+
+ /**
+ * @return {number}
+ */
+ es3fShaderTextureFunctionTests.TextureSizeCase.prototype.getGLTextureTarget = function() {
+ switch (this.m_textureSpec.type) {
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D:
+ return gl.TEXTURE_2D;
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP:
+ return gl.TEXTURE_CUBE_MAP;
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY:
+ return gl.TEXTURE_2D_ARRAY;
+ case es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D:
+ return gl.TEXTURE_3D;
+ default:
+ throw new Error('Texture Type not supported.');
+ }
+ };
+
+ /** @typedef {Array<string, es3fShaderTextureFunctionTests.TextureLookupSpec, es3fShaderTextureFunctionTests.TextureSpec, es3fShaderTextureFunctionTests.EvalFunc, es3fShaderTextureFunctionTests.CaseFlags>} */ es3fShaderTextureFunctionTests.TestSpec;
+
+ /**
+ * @param {string} name
+ * @param {es3fShaderTextureFunctionTests.TexFunction} func
+ * @param {Array<number>} minCoord
+ * @param {Array<number>} maxCoord
+ * @param {boolean} useBias
+ * @param {number} minLodBias
+ * @param {number} maxLodBias
+ * @param {boolean} useOffset
+ * @param {Array<number>} offset
+ * @param {es3fShaderTextureFunctionTests.TextureSpec} texSpec
+ * @param {es3fShaderTextureFunctionTests.TexEvalFunc} evalFunc
+ * @param {es3fShaderTextureFunctionTests.CaseFlags} flags
+ * @return {es3fShaderTextureFunctionTests.TexFuncCaseSpec}
+ */
+ es3fShaderTextureFunctionTests.getCaseSpec = function(name, func, minCoord, maxCoord, useBias, minLodBias, maxLodBias, useOffset, offset, texSpec, evalFunc, flags) {
+ return new es3fShaderTextureFunctionTests.TexFuncCaseSpec(name,
+ new es3fShaderTextureFunctionTests.TextureLookupSpec(func, minCoord, maxCoord, useBias, minLodBias, maxLodBias, [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], useOffset, offset),
+ texSpec,
+ evalFunc,
+ flags);
+ };
+
+ /**
+ * @param {string} name
+ * @param {es3fShaderTextureFunctionTests.TexFunction} func
+ * @param {Array<number>} minCoord
+ * @param {Array<number>} maxCoord
+ * @param {Array<number>} mindx
+ * @param {Array<number>} maxdx
+ * @param {Array<number>} mindy
+ * @param {Array<number>} maxdy
+ * @param {boolean} useOffset
+ * @param {Array<number>} offset
+ * @param {es3fShaderTextureFunctionTests.TextureSpec} texSpec
+ * @param {es3fShaderTextureFunctionTests.TexEvalFunc} evalFunc
+ * @param {es3fShaderTextureFunctionTests.CaseFlags} flags
+ * @return {es3fShaderTextureFunctionTests.TexFuncCaseSpec}
+ */
+ es3fShaderTextureFunctionTests.getGradCaseSpec = function(name, func, minCoord, maxCoord, mindx, maxdx, mindy, maxdy, useOffset, offset, texSpec, evalFunc, flags) {
+ return new es3fShaderTextureFunctionTests.TexFuncCaseSpec(name,
+ new es3fShaderTextureFunctionTests.TextureLookupSpec(func, minCoord, maxCoord, false, 0.0, 0.0, mindx, maxdx, mindy, maxdy, useOffset, offset),
+ texSpec,
+ evalFunc,
+ flags);
+ };
+
+ /**
+ * @enum {number}
+ */
+ es3fShaderTextureFunctionTests.CaseFlags = {
+ VERTEX: 1,
+ FRAGMENT: 2,
+ BOTH: 3
+ };
+
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {es3fShaderTextureFunctionTests.TextureLookupSpec} lookupSpec
+ * @param {es3fShaderTextureFunctionTests.TextureSpec} texSpec
+ * @param {es3fShaderTextureFunctionTests.TexEvalFunc} evalFunc
+ * @param {number} flags
+ */
+ es3fShaderTextureFunctionTests.TexFuncCaseSpec = function(name, lookupSpec, texSpec, evalFunc, flags) {
+ /** @type {string} */ this.name = name;
+ /** @type {es3fShaderTextureFunctionTests.TextureLookupSpec} */ this.lookupSpec = lookupSpec;
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ this.texSpec = texSpec;
+ /** @type {es3fShaderTextureFunctionTests.TexEvalFunc} */ this.evalFunc = evalFunc;
+ /** @type {number} */ this.flags = flags;
+ };
+
+ /**
+ * @param {tcuTestCase.DeqpTest} parent
+ * @param {string} groupName
+ * @param {string} groupDesc
+ * @param {Array<es3fShaderTextureFunctionTests.TexFuncCaseSpec>} cases
+ */
+ es3fShaderTextureFunctionTests.createCaseGroup = function(parent, groupName, groupDesc, cases) {
+ /** @type {tcuTestCase.DeqpTest} */ var group = tcuTestCase.newTest(groupName, groupDesc);
+ parent.addChild(group);
+
+ for (var ndx = 0; ndx < cases.length; ndx++) {
+ /** @type {string} */ var name = cases[ndx].name;
+ if (cases[ndx].flags & es3fShaderTextureFunctionTests.CaseFlags.VERTEX)
+ group.addChild(new es3fShaderTextureFunctionTests.ShaderTextureFunctionCase(name + '_vertex', '', cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, true));
+ if (cases[ndx].flags & es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT)
+ group.addChild(new es3fShaderTextureFunctionTests.ShaderTextureFunctionCase(name + '_fragment', '', cases[ndx].lookupSpec, cases[ndx].texSpec, cases[ndx].evalFunc, false));
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fShaderTextureFunctionTests.ShaderTextureFunctionTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'texture_functions', 'Texture Access Function Tests');
+ };
+
+ es3fShaderTextureFunctionTests.ShaderTextureFunctionTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fShaderTextureFunctionTests.ShaderTextureFunctionTests.prototype.constructor = es3fShaderTextureFunctionTests.ShaderTextureFunctionTests;
+
+ es3fShaderTextureFunctionTests.ShaderTextureFunctionTests.prototype.init = function() {
+ // Samplers
+ /** @type {tcuTexture.Sampler} */ var samplerNearestNoMipmap = new tcuTexture.Sampler(tcuTexture.WrapMode.REPEAT_GL, tcuTexture.WrapMode.REPEAT_GL, tcuTexture.WrapMode.REPEAT_GL,
+ tcuTexture.FilterMode.NEAREST, tcuTexture.FilterMode.NEAREST,
+ 0.0 /* LOD threshold */, true /* normalized coords */, tcuTexture.CompareMode.COMPAREMODE_NONE,
+ 0 /* cmp channel */, [0.0, 0.0, 0.0, 0.0] /* border color */, true /* seamless cube map */);
+ /** @type {tcuTexture.Sampler} */ var samplerLinearNoMipmap = new tcuTexture.Sampler(tcuTexture.WrapMode.REPEAT_GL, tcuTexture.WrapMode.REPEAT_GL, tcuTexture.WrapMode.REPEAT_GL,
+ tcuTexture.FilterMode.LINEAR, tcuTexture.FilterMode.LINEAR,
+ 0.0 /* LOD threshold */, true /* normalized coords */, tcuTexture.CompareMode.COMPAREMODE_NONE,
+ 0 /* cmp channel */, [0.0, 0.0, 0.0, 0.0] /* border color */, true /* seamless cube map */);
+ /** @type {tcuTexture.Sampler} */ var samplerNearestMipmap = new tcuTexture.Sampler(tcuTexture.WrapMode.REPEAT_GL, tcuTexture.WrapMode.REPEAT_GL, tcuTexture.WrapMode.REPEAT_GL,
+ tcuTexture.FilterMode.NEAREST_MIPMAP_NEAREST, tcuTexture.FilterMode.NEAREST,
+ 0.0 /* LOD threshold */, true /* normalized coords */, tcuTexture.CompareMode.COMPAREMODE_NONE,
+ 0 /* cmp channel */, [0.0, 0.0, 0.0, 0.0] /* border color */, true /* seamless cube map */);
+ /** @type {tcuTexture.Sampler} */ var samplerLinearMipmap = new tcuTexture.Sampler(tcuTexture.WrapMode.REPEAT_GL, tcuTexture.WrapMode.REPEAT_GL, tcuTexture.WrapMode.REPEAT_GL,
+ tcuTexture.FilterMode.LINEAR_MIPMAP_NEAREST, tcuTexture.FilterMode.LINEAR,
+ 0.0 /* LOD threshold */, true /* normalized coords */, tcuTexture.CompareMode.COMPAREMODE_NONE,
+ 0 /* cmp channel */, [0.0, 0.0, 0.0, 0.0] /* border color */, true /* seamless cube map */);
+
+ /** @type {tcuTexture.Sampler} */ var samplerShadowNoMipmap = new tcuTexture.Sampler(tcuTexture.WrapMode.REPEAT_GL, tcuTexture.WrapMode.REPEAT_GL, tcuTexture.WrapMode.REPEAT_GL,
+ tcuTexture.FilterMode.NEAREST, tcuTexture.FilterMode.NEAREST,
+ 0.0 /* LOD threshold */, true /* normalized coords */, tcuTexture.CompareMode.COMPAREMODE_LESS,
+ 0 /* cmp channel */, [0.0, 0.0, 0.0, 0.0] /* border color */, true /* seamless cube map */);
+ /** @type {tcuTexture.Sampler} */ var samplerShadowMipmap = new tcuTexture.Sampler(tcuTexture.WrapMode.REPEAT_GL, tcuTexture.WrapMode.REPEAT_GL, tcuTexture.WrapMode.REPEAT_GL,
+ tcuTexture.FilterMode.NEAREST_MIPMAP_NEAREST, tcuTexture.FilterMode.NEAREST,
+ 0.0 /* LOD threshold */, true /* normalized coords */, tcuTexture.CompareMode.COMPAREMODE_LESS,
+ 0 /* cmp channel */, [0.0, 0.0, 0.0, 0.0] /* border color */, true /* seamless cube map */);
+
+ /** @type {tcuTexture.Sampler} */ var samplerTexelFetch = new tcuTexture.Sampler(tcuTexture.WrapMode.REPEAT_GL, tcuTexture.WrapMode.REPEAT_GL, tcuTexture.WrapMode.REPEAT_GL,
+ tcuTexture.FilterMode.NEAREST_MIPMAP_NEAREST, tcuTexture.FilterMode.NEAREST,
+ 0.0 /* LOD threshold */, false /* non-normalized coords */, tcuTexture.CompareMode.COMPAREMODE_NONE,
+ 0 /* cmp channel */, [0.0, 0.0, 0.0, 0.0] /* border color */, true /* seamless cube map */);
+
+ // Default textures.
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DFixed = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D, gl.RGBA8, 256, 256, 1, 1, samplerLinearNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DFloat = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D, gl.RGBA16F, 256, 256, 1, 1, samplerLinearNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DInt = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D, gl.RGBA8I, 256, 256, 1, 1, samplerNearestNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DUint = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D, gl.RGBA8UI, 256, 256, 1, 1, samplerNearestNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DMipmapFixed = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D, gl.RGBA8, 256, 256, 1, 9, samplerLinearMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DMipmapFloat = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D, gl.RGBA16F, 256, 256, 1, 9, samplerLinearMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DMipmapInt = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D, gl.RGBA8I, 256, 256, 1, 9, samplerNearestMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DMipmapUint = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D, gl.RGBA8UI, 256, 256, 1, 9, samplerNearestMipmap);
+
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DShadow = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D, gl.DEPTH_COMPONENT16, 256, 256, 1, 9, samplerShadowNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DMipmapShadow = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D, gl.DEPTH_COMPONENT16, 256, 256, 1, 9, samplerShadowMipmap);
+
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DTexelFetchFixed = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D, gl.RGBA8, 256, 256, 1, 9, samplerTexelFetch);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DTexelFetchFloat = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D, gl.RGBA16F, 256, 256, 1, 9, samplerTexelFetch);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DTexelFetchInt = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D, gl.RGBA8I, 256, 256, 1, 9, samplerTexelFetch);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DTexelFetchUint = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D, gl.RGBA8UI, 256, 256, 1, 9, samplerTexelFetch);
+
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var texCubeFixed = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP, gl.RGBA8, 256, 256, 1, 1, samplerLinearNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var texCubeFloat = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP, gl.RGBA16F, 256, 256, 1, 1, samplerLinearNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var texCubeInt = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP, gl.RGBA8I, 256, 256, 1, 1, samplerNearestNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var texCubeUint = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP, gl.RGBA8UI, 256, 256, 1, 1, samplerNearestNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var texCubeMipmapFixed = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP, gl.RGBA8, 256, 256, 1, 9, samplerLinearMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var texCubeMipmapFloat = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP, gl.RGBA16F, 128, 128, 1, 8, samplerLinearMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var texCubeMipmapInt = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP, gl.RGBA8I, 256, 256, 1, 9, samplerNearestMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var texCubeMipmapUint = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP, gl.RGBA8UI, 256, 256, 1, 9, samplerNearestMipmap);
+
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var texCubeShadow = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP, gl.DEPTH_COMPONENT16, 256, 256, 1, 1, samplerShadowNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var texCubeMipmapShadow = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_CUBE_MAP, gl.DEPTH_COMPONENT16, 256, 256, 1, 9, samplerShadowMipmap);
+
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DArrayFixed = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY, gl.RGBA8, 128, 128, 4, 1, samplerLinearNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DArrayFloat = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY, gl.RGBA16F, 128, 128, 4, 1, samplerLinearNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DArrayInt = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY, gl.RGBA8I, 128, 128, 4, 1, samplerNearestNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DArrayUint = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY, gl.RGBA8UI, 128, 128, 4, 1, samplerNearestNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DArrayMipmapFixed = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY, gl.RGBA8, 128, 128, 4, 8, samplerLinearMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DArrayMipmapFloat = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY, gl.RGBA16F, 128, 128, 4, 8, samplerLinearMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DArrayMipmapInt = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY, gl.RGBA8I, 128, 128, 4, 8, samplerNearestMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DArrayMipmapUint = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY, gl.RGBA8UI, 128, 128, 4, 8, samplerNearestMipmap);
+
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DArrayShadow = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY, gl.DEPTH_COMPONENT16, 128, 128, 4, 1, samplerShadowNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DArrayMipmapShadow = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY, gl.DEPTH_COMPONENT16, 128, 128, 4, 8, samplerShadowMipmap);
+
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DArrayTexelFetchFixed = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY, gl.RGBA8, 128, 128, 4, 8, samplerTexelFetch);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DArrayTexelFetchFloat = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY, gl.RGBA16F, 128, 128, 4, 8, samplerTexelFetch);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DArrayTexelFetchInt = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY, gl.RGBA8I, 128, 128, 4, 8, samplerTexelFetch);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex2DArrayTexelFetchUint = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_2D_ARRAY, gl.RGBA8UI, 128, 128, 4, 8, samplerTexelFetch);
+
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex3DFixed = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D, gl.RGBA8, 64, 32, 32, 1, samplerLinearNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex3DFloat = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D, gl.RGBA16F, 64, 32, 32, 1, samplerLinearNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex3DInt = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D, gl.RGBA8I, 64, 32, 32, 1, samplerNearestNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex3DUint = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D, gl.RGBA8UI, 64, 32, 32, 1, samplerNearestNoMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex3DMipmapFixed = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D, gl.RGBA8, 64, 32, 32, 7, samplerLinearMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex3DMipmapFloat = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D, gl.RGBA16F, 64, 32, 32, 7, samplerLinearMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex3DMipmapInt = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D, gl.RGBA8I, 64, 32, 32, 7, samplerNearestMipmap);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex3DMipmapUint = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D, gl.RGBA8UI, 64, 32, 32, 7, samplerNearestMipmap);
+
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex3DTexelFetchFixed = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D, gl.RGBA8, 64, 32, 32, 7, samplerTexelFetch);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex3DTexelFetchFloat = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D, gl.RGBA16F, 64, 32, 32, 7, samplerTexelFetch);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex3DTexelFetchInt = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D, gl.RGBA8I, 64, 32, 32, 7, samplerTexelFetch);
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ var tex3DTexelFetchUint = new es3fShaderTextureFunctionTests.TextureSpec(es3fShaderTextureFunctionTests.TextureType.TEXTURETYPE_3D, gl.RGBA8UI, 64, 32, 32, 7, samplerTexelFetch);
+
+ var testGroup = tcuTestCase.runner.testCases;
+ // texture() cases
+ /** @type {Array<es3fShaderTextureFunctionTests.TexFuncCaseSpec>} */ var textureCases = [
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DFixed, es3fShaderTextureFunctionTests.evalTexture2D, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2D, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DFloat, es3fShaderTextureFunctionTests.evalTexture2D, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2D, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DInt, es3fShaderTextureFunctionTests.evalTexture2D, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2D, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DUint, es3fShaderTextureFunctionTests.evalTexture2D, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2D, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_bias_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], true, -2.0, 2.0, false, [0, 0, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_bias_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], true, -2.0, 2.0, false, [0, 0, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], true, -2.0, 2.0, false, [0, 0, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], true, -2.0, 2.0, false, [0, 0, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('samplercube_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.0, -1.0, 1.01, 0.0], [1.0, 1.0, 1.01, 0.0], false, 0.0, 0.0, false, [0, 0, 0], texCubeFixed, es3fShaderTextureFunctionTests.evalTextureCube, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('samplercube_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.0, -1.0, 1.01, 0.0], [1.0, 1.0, 1.01, 0.0], false, 0.0, 0.0, false, [0, 0, 0], texCubeMipmapFixed, es3fShaderTextureFunctionTests.evalTextureCube, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('samplercube_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.0, -1.0, -1.01, 0.0], [1.0, 1.0, -1.01, 0.0], false, 0.0, 0.0, false, [0, 0, 0], texCubeFloat, es3fShaderTextureFunctionTests.evalTextureCube, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('samplercube_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.0, -1.0, -1.01, 0.0], [1.0, 1.0, -1.01, 0.0], false, 0.0, 0.0, false, [0, 0, 0], texCubeMipmapFloat, es3fShaderTextureFunctionTests.evalTextureCube, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isamplercube', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.0, -1.0, 1.01, 0.0], [1.0, 1.0, 1.01, 0.0], false, 0.0, 0.0, false, [0, 0, 0], texCubeInt, es3fShaderTextureFunctionTests.evalTextureCube, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('isamplercube', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.0, -1.0, 1.01, 0.0], [1.0, 1.0, 1.01, 0.0], false, 0.0, 0.0, false, [0, 0, 0], texCubeMipmapInt, es3fShaderTextureFunctionTests.evalTextureCube, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usamplercube', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.0, -1.0, -1.01, 0.0], [1.0, 1.0, -1.01, 0.0], false, 0.0, 0.0, false, [0, 0, 0], texCubeUint, es3fShaderTextureFunctionTests.evalTextureCube, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('usamplercube', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.0, -1.0, -1.01, 0.0], [1.0, 1.0, -1.01, 0.0], false, 0.0, 0.0, false, [0, 0, 0], texCubeMipmapUint, es3fShaderTextureFunctionTests.evalTextureCube, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('samplercube_bias_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.0, -1.0, 1.01, 0.0], [1.0, 1.0, 1.01, 0.0], true, -2.0, 2.0, false, [0, 0, 0], texCubeMipmapFixed, es3fShaderTextureFunctionTests.evalTextureCubeBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('samplercube_bias_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.0, -1.0, -1.01, 0.0], [1.0, 1.0, -1.01, 0.0], true, -2.0, 2.0, false, [0, 0, 0], texCubeMipmapFloat, es3fShaderTextureFunctionTests.evalTextureCubeBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isamplercube_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.0, -1.0, 1.01, 0.0], [1.0, 1.0, 1.01, 0.0], true, -2.0, 2.0, false, [0, 0, 0], texCubeMipmapInt, es3fShaderTextureFunctionTests.evalTextureCubeBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usamplercube_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.0, -1.0, -1.01, 0.0], [1.0, 1.0, -1.01, 0.0], true, -2.0, 2.0, false, [0, 0, 0], texCubeMipmapUint, es3fShaderTextureFunctionTests.evalTextureCubeBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DArrayFixed, es3fShaderTextureFunctionTests.evalTexture2DArray, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DArrayMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DArray, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DArrayFloat, es3fShaderTextureFunctionTests.evalTexture2DArray, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DArrayMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DArray, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DArrayInt, es3fShaderTextureFunctionTests.evalTexture2DArray, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DArrayMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DArray, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DArrayUint, es3fShaderTextureFunctionTests.evalTexture2DArray, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DArrayMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DArray, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_bias_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], true, -2.0, 2.0, false, [0, 0, 0], tex2DArrayMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DArrayBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_bias_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], true, -2.0, 2.0, false, [0, 0, 0], tex2DArrayMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DArrayBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2darray_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], true, -2.0, 2.0, false, [0, 0, 0], tex2DArrayMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DArrayBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2darray_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], true, -2.0, 2.0, false, [0, 0, 0], tex2DArrayMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DArrayBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex3DFixed, es3fShaderTextureFunctionTests.evalTexture3D, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex3DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture3D, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex3DFloat, es3fShaderTextureFunctionTests.evalTexture3D, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3D, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex3DInt, es3fShaderTextureFunctionTests.evalTexture3D, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex3DMipmapInt, es3fShaderTextureFunctionTests.evalTexture3D, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex3DUint, es3fShaderTextureFunctionTests.evalTexture3D, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3D, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_bias_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], true, -2.0, 1.0, false, [0, 0, 0], tex3DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture3DBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_bias_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], true, -2.0, 1.0, false, [0, 0, 0], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], true, -2.0, 2.0, false, [0, 0, 0], tex3DMipmapInt, es3fShaderTextureFunctionTests.evalTexture3DBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], true, -2.0, 2.0, false, [0, 0, 0], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 1.0, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DShadow, es3fShaderTextureFunctionTests.evalTexture2DShadow, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 1.0, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadow, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 1.0, 0.0], true, -2.0, 2.0, false, [0, 0, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('samplercubeshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.0, -1.0, 1.01, 0.0], [1.0, 1.0, 1.01, 1.0], false, 0.0, 0.0, false, [0, 0, 0], texCubeShadow, es3fShaderTextureFunctionTests.evalTextureCubeShadow, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('samplercubeshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.0, -1.0, 1.01, 0.0], [1.0, 1.0, 1.01, 1.0], false, 0.0, 0.0, false, [0, 0, 0], texCubeMipmapShadow, es3fShaderTextureFunctionTests.evalTextureCubeShadow, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('samplercubeshadow_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.0, -1.0, 1.01, 0.0], [1.0, 1.0, 1.01, 1.0], true, -2.0, 2.0, false, [0, 0, 0], texCubeMipmapShadow, es3fShaderTextureFunctionTests.evalTextureCubeShadowBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darrayshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 1.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DArrayShadow, es3fShaderTextureFunctionTests.evalTexture2DArrayShadow, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darrayshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 1.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DArrayMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DArrayShadow, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT)
+
+ // Not in spec.
+ // es3fShaderTextureFunctionTests.getCaseSpec('sampler2darrayshadow_bias', (es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 1.0], true, -2.0, 2.0, Vec2(0.0), Vec2(0.0), false, [0, 0, 0]), tex2DArrayMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DArrayShadowBias, FRAGMENT)
+ ];
+ es3fShaderTextureFunctionTests.createCaseGroup(this, 'texture', 'texture() Tests', textureCases);
+
+ // textureOffset() cases
+ // \note _bias variants are not using mipmap thanks to wide allowed range for LOD computation
+ /** @type {Array<es3fShaderTextureFunctionTests.TexFuncCaseSpec>} */ var textureOffsetCases = [
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, true, [-8, 7, 0], tex2DFixed, es3fShaderTextureFunctionTests.evalTexture2DOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, true, [7, -8, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, true, [-8, 7, 0], tex2DFloat, es3fShaderTextureFunctionTests.evalTexture2DOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, true, [7, -8, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, true, [-8, 7, 0], tex2DInt, es3fShaderTextureFunctionTests.evalTexture2DOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, true, [7, -8, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, true, [-8, 7, 0], tex2DUint, es3fShaderTextureFunctionTests.evalTexture2DOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, 0.0, 0.0, true, [7, -8, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_bias_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], true, -2.0, 2.0, true, [-8, 7, 0], tex2DFixed, es3fShaderTextureFunctionTests.evalTexture2DOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_bias_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], true, -2.0, 2.0, true, [7, -8, 0], tex2DFloat, es3fShaderTextureFunctionTests.evalTexture2DOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], true, -2.0, 2.0, true, [-8, 7, 0], tex2DInt, es3fShaderTextureFunctionTests.evalTexture2DOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], true, -2.0, 2.0, true, [7, -8, 0], tex2DUint, es3fShaderTextureFunctionTests.evalTexture2DOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, true, [-8, 7, 0], tex2DArrayFixed, es3fShaderTextureFunctionTests.evalTexture2DArrayOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, true, [7, -8, 0], tex2DArrayMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DArrayOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, true, [-8, 7, 0], tex2DArrayFloat, es3fShaderTextureFunctionTests.evalTexture2DArrayOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, true, [7, -8, 0], tex2DArrayMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DArrayOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, true, [-8, 7, 0], tex2DArrayInt, es3fShaderTextureFunctionTests.evalTexture2DArrayOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, true, [7, -8, 0], tex2DArrayMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DArrayOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, true, [-8, 7, 0], tex2DArrayUint, es3fShaderTextureFunctionTests.evalTexture2DArrayOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, 0.0, 0.0, true, [7, -8, 0], tex2DArrayMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DArrayOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_bias_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], true, -2.0, 2.0, true, [-8, 7, 0], tex2DArrayFixed, es3fShaderTextureFunctionTests.evalTexture2DArrayOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_bias_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], true, -2.0, 2.0, true, [7, -8, 0], tex2DArrayFloat, es3fShaderTextureFunctionTests.evalTexture2DArrayOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2darray_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], true, -2.0, 2.0, true, [-8, 7, 0], tex2DArrayInt, es3fShaderTextureFunctionTests.evalTexture2DArrayOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2darray_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], true, -2.0, 2.0, true, [7, -8, 0], tex2DArrayUint, es3fShaderTextureFunctionTests.evalTexture2DArrayOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, true, [-8, 7, 3], tex3DFixed, es3fShaderTextureFunctionTests.evalTexture3DOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, true, [7, 3, -8], tex3DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture3DOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, true, [3, -8, 7], tex3DFloat, es3fShaderTextureFunctionTests.evalTexture3DOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, true, [-8, 7, 3], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, true, [7, 3, -8], tex3DInt, es3fShaderTextureFunctionTests.evalTexture3DOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, true, [3, -8, 7], tex3DMipmapInt, es3fShaderTextureFunctionTests.evalTexture3DOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, true, [-8, 7, 3], tex3DUint, es3fShaderTextureFunctionTests.evalTexture3DOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, 0.0, 0.0, true, [7, 3, -8], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_bias_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], true, -2.0, 1.0, true, [-8, 7, 3], tex3DFixed, es3fShaderTextureFunctionTests.evalTexture3DOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_bias_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], true, -2.0, 1.0, true, [7, 3, -8], tex3DFloat, es3fShaderTextureFunctionTests.evalTexture3DOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], true, -2.0, 2.0, true, [3, -8, 7], tex3DInt, es3fShaderTextureFunctionTests.evalTexture3DOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], true, -2.0, 2.0, true, [-8, 7, 3], tex3DUint, es3fShaderTextureFunctionTests.evalTexture3DOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 1.0, 0.0], false, 0.0, 0.0, true, [-8, 7, 0], tex2DShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 1.0, 0.0], false, 0.0, 0.0, true, [7, -8, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTURE, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 1.0, 0.0], true, -2.0, 2.0, true, [-8, 7, 0], tex2DShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT)
+ ];
+ es3fShaderTextureFunctionTests.createCaseGroup(this, 'textureoffset', 'textureOffset() Tests', textureOffsetCases);
+
+ // textureProj() cases
+ // \note Currently uses constant divider!
+ /** @type {Array<es3fShaderTextureFunctionTests.TexFuncCaseSpec>} */ var textureProjCases = [
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DFixed, es3fShaderTextureFunctionTests.evalTexture2DProj3, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DProj3, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DFloat, es3fShaderTextureFunctionTests.evalTexture2DProj3, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DProj3, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DInt, es3fShaderTextureFunctionTests.evalTexture2DProj3, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DProj3, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DUint, es3fShaderTextureFunctionTests.evalTexture2DProj3, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DProj3, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_bias_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], true, -2.0, 2.0, false, [0, 0, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DProj3Bias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_bias_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], true, -2.0, 2.0, false, [0, 0, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DProj3Bias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec3_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], true, -2.0, 2.0, false, [0, 0, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DProj3Bias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec3_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], true, -2.0, 2.0, false, [0, 0, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DProj3Bias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, false, [0, 0, 0], tex2DFixed, es3fShaderTextureFunctionTests.evalTexture2DProj, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, false, [0, 0, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DProj, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, false, [0, 0, 0], tex2DFloat, es3fShaderTextureFunctionTests.evalTexture2DProj, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, false, [0, 0, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DProj, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, false, [0, 0, 0], tex2DInt, es3fShaderTextureFunctionTests.evalTexture2DProj, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, false, [0, 0, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DProj, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, false, [0, 0, 0], tex2DUint, es3fShaderTextureFunctionTests.evalTexture2DProj, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, false, [0, 0, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DProj, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_bias_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], true, -2.0, 2.0, false, [0, 0, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DProjBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_bias_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], true, -2.0, 2.0, false, [0, 0, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DProjBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec4_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], true, -2.0, 2.0, false, [0, 0, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DProjBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec4_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], true, -2.0, 2.0, false, [0, 0, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DProjBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, false, [0, 0, 0], tex3DFixed, es3fShaderTextureFunctionTests.evalTexture3DProj, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, false, [0, 0, 0], tex3DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture3DProj, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, false, [0, 0, 0], tex3DFloat, es3fShaderTextureFunctionTests.evalTexture3DProj, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, false, [0, 0, 0], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DProj, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, false, [0, 0, 0], tex3DInt, es3fShaderTextureFunctionTests.evalTexture3DProj, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, false, [0, 0, 0], tex3DMipmapInt, es3fShaderTextureFunctionTests.evalTexture3DProj, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, false, [0, 0, 0], tex3DUint, es3fShaderTextureFunctionTests.evalTexture3DProj, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, false, [0, 0, 0], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DProj, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_bias_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], true, -2.0, 1.0, false, [0, 0, 0], tex3DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture3DProjBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_bias_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], true, -2.0, 1.0, false, [0, 0, 0], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DProjBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], true, -2.0, 2.0, false, [0, 0, 0], tex3DMipmapInt, es3fShaderTextureFunctionTests.evalTexture3DProjBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], true, -2.0, 2.0, false, [0, 0, 0], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DProjBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.2, 0.6, 0.0, 1.5], [-2.25, -3.45, 1.5, 1.5], false, 0.0, 0.0, false, [0, 0, 0], tex2DShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowProj, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.2, 0.6, 0.0, 1.5], [-2.25, -3.45, 1.5, 1.5], false, 0.0, 0.0, false, [0, 0, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowProj, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.2, 0.6, 0.0, 1.5], [-2.25, -3.45, 1.5, 1.5], true, -2.0, 2.0, false, [0, 0, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowProjBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT)
+ ];
+ es3fShaderTextureFunctionTests.createCaseGroup(this, 'textureproj', 'textureProj() Tests', textureProjCases);
+
+ // textureProjOffset() cases
+ // \note Currently uses constant divider!
+ /** @type {Array<es3fShaderTextureFunctionTests.TexFuncCaseSpec>} */ var textureProjOffsetCases = [
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, true, [-8, 7, 0], tex2DFixed, es3fShaderTextureFunctionTests.evalTexture2DProj3Offset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, true, [7, -8, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DProj3Offset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, true, [-8, 7, 0], tex2DFloat, es3fShaderTextureFunctionTests.evalTexture2DProj3Offset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, true, [7, -8, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DProj3Offset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, true, [-8, 7, 0], tex2DInt, es3fShaderTextureFunctionTests.evalTexture2DProj3Offset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, true, [7, -8, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DProj3Offset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, true, [-8, 7, 0], tex2DUint, es3fShaderTextureFunctionTests.evalTexture2DProj3Offset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, 0.0, 0.0, true, [7, -8, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DProj3Offset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_bias_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], true, -2.0, 2.0, true, [-8, 7, 0], tex2DFixed, es3fShaderTextureFunctionTests.evalTexture2DProj3OffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_bias_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], true, -2.0, 2.0, true, [7, -8, 0], tex2DFloat, es3fShaderTextureFunctionTests.evalTexture2DProj3OffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec3_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], true, -2.0, 2.0, true, [-8, 7, 0], tex2DInt, es3fShaderTextureFunctionTests.evalTexture2DProj3OffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec3_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], true, -2.0, 2.0, true, [7, -8, 0], tex2DUint, es3fShaderTextureFunctionTests.evalTexture2DProj3OffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, true, [-8, 7, 0], tex2DFixed, es3fShaderTextureFunctionTests.evalTexture2DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, true, [7, -8, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, true, [-8, 7, 0], tex2DFloat, es3fShaderTextureFunctionTests.evalTexture2DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, true, [7, -8, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, true, [-8, 7, 0], tex2DInt, es3fShaderTextureFunctionTests.evalTexture2DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, true, [7, -8, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, true, [-8, 7, 0], tex2DUint, es3fShaderTextureFunctionTests.evalTexture2DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, 0.0, 0.0, true, [7, -8, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_bias_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], true, -2.0, 2.0, true, [-8, 7, 0], tex2DFixed, es3fShaderTextureFunctionTests.evalTexture2DProjOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_bias_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], true, -2.0, 2.0, true, [7, -8, 0], tex2DFloat, es3fShaderTextureFunctionTests.evalTexture2DProjOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec4_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], true, -2.0, 2.0, true, [-8, 7, 0], tex2DInt, es3fShaderTextureFunctionTests.evalTexture2DProjOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec4_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], true, -2.0, 2.0, true, [7, -8, 0], tex2DUint, es3fShaderTextureFunctionTests.evalTexture2DProjOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, true, [-8, 7, 3], tex3DFixed, es3fShaderTextureFunctionTests.evalTexture3DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, true, [7, 3, -8], tex3DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture3DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, true, [3, -8, 7], tex3DFloat, es3fShaderTextureFunctionTests.evalTexture3DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, true, [-8, 7, 3], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, true, [7, 3, -8], tex3DInt, es3fShaderTextureFunctionTests.evalTexture3DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, true, [3, -8, 7], tex3DMipmapInt, es3fShaderTextureFunctionTests.evalTexture3DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, true, [-8, 7, 3], tex3DUint, es3fShaderTextureFunctionTests.evalTexture3DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, 0.0, 0.0, true, [7, 3, -8], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DProjOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_bias_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], true, -2.0, 2.0, true, [-8, 7, 3], tex3DFixed, es3fShaderTextureFunctionTests.evalTexture3DProjOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_bias_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], true, -2.0, 2.0, true, [7, 3, -8], tex3DFloat, es3fShaderTextureFunctionTests.evalTexture3DProjOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], true, -2.0, 2.0, true, [3, -8, 7], tex3DInt, es3fShaderTextureFunctionTests.evalTexture3DProjOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], true, -2.0, 2.0, true, [-8, 7, 3], tex3DUint, es3fShaderTextureFunctionTests.evalTexture3DProjOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ // NOTE: offset changed from [-8, 7, 0] in native dEQP to [7, -8, 0] per https://github.com/KhronosGroup/WebGL/issues/2033
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.2, 0.6, 0.0, 1.5], [-2.25, -3.45, 1.5, 1.5], false, 0.0, 0.0, true, [7, -8, 0], tex2DShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowProjOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.2, 0.6, 0.0, 1.5], [-2.25, -3.45, 1.5, 1.5], false, 0.0, 0.0, true, [7, -8, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowProjOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow_bias', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJ, [0.2, 0.6, 0.0, 1.5], [-2.25, -3.45, 1.5, 1.5], true, -2.0, 2.0, true, [-8, 7, 0], tex2DShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowProjOffsetBias, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT)
+ ];
+ es3fShaderTextureFunctionTests.createCaseGroup(this, 'textureprojoffset', 'textureOffsetProj() Tests', textureProjOffsetCases);
+
+ // textureLod() cases
+ /** @type {Array<es3fShaderTextureFunctionTests.TexFuncCaseSpec>} */ var textureLodCases = [
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, -1.0, 9.0, false, [0, 0, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, -1.0, 9.0, false, [0, 0, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, -1.0, 9.0, false, [0, 0, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, -1.0, 9.0, false, [0, 0, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('samplercube_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.0, -1.0, 1.01, 0.0], [1.0, 1.0, 1.01, 0.0], false, -1.0, 9.0, false, [0, 0, 0], texCubeMipmapFixed, es3fShaderTextureFunctionTests.evalTextureCubeLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('samplercube_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.0, -1.0, -1.01, 0.0], [1.0, 1.0, -1.01, 0.0], false, -1.0, 9.0, false, [0, 0, 0], texCubeMipmapFloat, es3fShaderTextureFunctionTests.evalTextureCubeLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isamplercube', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.0, -1.0, 1.01, 0.0], [1.0, 1.0, 1.01, 0.0], false, -1.0, 9.0, false, [0, 0, 0], texCubeMipmapInt, es3fShaderTextureFunctionTests.evalTextureCubeLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usamplercube', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.0, -1.0, -1.01, 0.0], [1.0, 1.0, -1.01, 0.0], false, -1.0, 9.0, false, [0, 0, 0], texCubeMipmapUint, es3fShaderTextureFunctionTests.evalTextureCubeLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, -1.0, 8.0, false, [0, 0, 0], tex2DArrayMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DArrayLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, -1.0, 8.0, false, [0, 0, 0], tex2DArrayMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DArrayLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, -1.0, 8.0, false, [0, 0, 0], tex2DArrayMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DArrayLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, -1.0, 8.0, false, [0, 0, 0], tex2DArrayMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DArrayLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, -1.0, 7.0, false, [0, 0, 0], tex3DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture3DLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, -1.0, 7.0, false, [0, 0, 0], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, -1.0, 7.0, false, [0, 0, 0], tex3DMipmapInt, es3fShaderTextureFunctionTests.evalTexture3DLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, -1.0, 7.0, false, [0, 0, 0], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 1.0, 0.0], false, -1.0, 9.0, false, [0, 0, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH)
+ ];
+ es3fShaderTextureFunctionTests.createCaseGroup(this, 'texturelod', 'textureLod() Tests', textureLodCases);
+
+ // textureLodOffset() cases
+ /** @type {Array<es3fShaderTextureFunctionTests.TexFuncCaseSpec>} */ var textureLodOffsetCases = [
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, -1.0, 9.0, true, [-8, 7, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, -1.0, 9.0, true, [7, -8, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, -1.0, 9.0, true, [-8, 7, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], false, -1.0, 9.0, true, [7, -8, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, -1.0, 8.0, true, [-8, 7, 0], tex2DArrayMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DArrayLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, -1.0, 8.0, true, [7, -8, 0], tex2DArrayMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DArrayLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, -1.0, 8.0, true, [-8, 7, 0], tex2DArrayMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DArrayLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], false, -1.0, 8.0, true, [7, -8, 0], tex2DArrayMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DArrayLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, -1.0, 7.0, true, [-8, 7, 3], tex3DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture3DLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, -1.0, 7.0, true, [7, 3, -8], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, -1.0, 7.0, true, [3, -8, 7], tex3DMipmapInt, es3fShaderTextureFunctionTests.evalTexture3DLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], false, -1.0, 7.0, true, [-8, 7, 3], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTURELOD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 1.0, 0.0], false, -1.0, 9.0, true, [-8, 7, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH)
+ ];
+ es3fShaderTextureFunctionTests.createCaseGroup(this, 'texturelodoffset', 'textureLodOffset() Tests', textureLodOffsetCases);
+
+ // textureProjLod() cases
+ /** @type {Array<es3fShaderTextureFunctionTests.TexFuncCaseSpec>} */ var textureProjLodCases = [
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, -1.0, 9.0, false, [0, 0, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DProjLod3, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, -1.0, 9.0, false, [0, 0, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DProjLod3, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, -1.0, 9.0, false, [0, 0, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DProjLod3, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, -1.0, 9.0, false, [0, 0, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DProjLod3, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, -1.0, 9.0, false, [0, 0, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DProjLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, -1.0, 9.0, false, [0, 0, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DProjLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, -1.0, 9.0, false, [0, 0, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DProjLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, -1.0, 9.0, false, [0, 0, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DProjLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, -1.0, 7.0, false, [0, 0, 0], tex3DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture3DProjLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, -1.0, 7.0, false, [0, 0, 0], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DProjLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, -1.0, 7.0, false, [0, 0, 0], tex3DMipmapInt, es3fShaderTextureFunctionTests.evalTexture3DProjLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, -1.0, 7.0, false, [0, 0, 0], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DProjLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [0.2, 0.6, 0.0, 1.5], [-2.25, -3.45, 1.5, 1.5], false, -1.0, 9.0, false, [0, 0, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowProjLod, es3fShaderTextureFunctionTests.CaseFlags.BOTH)
+ ];
+ es3fShaderTextureFunctionTests.createCaseGroup(this, 'textureprojlod', 'textureProjLod() Tests', textureProjLodCases);
+
+ // textureProjLodOffset() cases
+ /** @type {Array<es3fShaderTextureFunctionTests.TexFuncCaseSpec>} */ var textureProjLodOffsetCases = [
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, -1.0, 9.0, true, [-8, 7, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DProjLod3Offset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec3_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, -1.0, 9.0, true, [7, -8, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DProjLod3Offset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, -1.0, 9.0, true, [-8, 7, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DProjLod3Offset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], false, -1.0, 9.0, true, [7, -8, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DProjLod3Offset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, -1.0, 9.0, true, [-8, 7, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DProjLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_vec4_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, -1.0, 9.0, true, [7, -8, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DProjLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, -1.0, 9.0, true, [-8, 7, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DProjLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], false, -1.0, 9.0, true, [7, -8, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DProjLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, -1.0, 7.0, true, [-8, 7, 3], tex3DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture3DProjLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, -1.0, 7.0, true, [7, 3, -8], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DProjLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, -1.0, 7.0, true, [3, -8, 7], tex3DMipmapInt, es3fShaderTextureFunctionTests.evalTexture3DProjLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], false, -1.0, 7.0, true, [-8, 7, 3], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DProjLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJLOD, [0.2, 0.6, 0.0, 1.5], [-2.25, -3.45, 1.5, 1.5], false, -1.0, 9.0, true, [-8, 7, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowProjLodOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH)
+ ];
+ es3fShaderTextureFunctionTests.createCaseGroup(this, 'textureprojlodoffset', 'textureProjLodOffset() Tests', textureProjLodOffsetCases);
+
+ // textureGrad() cases
+ // \note Only one of dudx, dudy, dvdx, dvdy is non-zero since spec allows approximating p from derivates by various methods.
+ /** @type {Array<es3fShaderTextureFunctionTests.TexFuncCaseSpec>} */ var textureGradCases = [
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('isampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [-0.2, 0.0, 0.0], false, [0, 0, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.2, 0.0], false, [0, 0, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getGradCaseSpec('samplercube_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.0, -1.0, 1.01, 0.0], [1.0, 1.0, 1.01, 0.0], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], texCubeMipmapFixed, es3fShaderTextureFunctionTests.evalTextureCubeGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('samplercube_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.0, -1.0, -1.01, 0.0], [1.0, 1.0, -1.01, 0.0], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], texCubeMipmapFloat, es3fShaderTextureFunctionTests.evalTextureCubeGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('isamplercube', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.0, -1.0, 1.01, 0.0], [1.0, 1.0, 1.01, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [-0.2, 0.0, 0.0], false, [0, 0, 0], texCubeMipmapInt, es3fShaderTextureFunctionTests.evalTextureCubeGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usamplercube', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.0, -1.0, -1.01, 0.0], [1.0, 1.0, -1.01, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.2, 0.0], false, [0, 0, 0], texCubeMipmapUint, es3fShaderTextureFunctionTests.evalTextureCubeGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2darray_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex2DArrayMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DArrayGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2darray_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex2DArrayMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DArrayGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('isampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [-0.2, 0.0, 0.0], false, [0, 0, 0], tex2DArrayMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DArrayGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.2, 0.0], false, [0, 0, 0], tex2DArrayMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DArrayGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex3DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture3DGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DGrad, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.2], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DGrad, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [-0.2, 0.0, 0.0], false, [0, 0, 0], tex3DMipmapInt, es3fShaderTextureFunctionTests.evalTexture3DGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.2, 0.0], false, [0, 0, 0], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DGrad, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, -0.2], false, [0, 0, 0], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DGrad, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 1.0, 0.0], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('samplercubeshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.0, -1.0, 1.01, 0.0], [1.0, 1.0, 1.01, 1.0], [0.0, 0.0, 0.0], [0.0, 0.2, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], texCubeMipmapShadow, es3fShaderTextureFunctionTests.evalTextureCubeShadowGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2darrayshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 1.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], false, [0, 0, 0], tex2DArrayMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DArrayShadowGrad, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2darrayshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 1.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], false, [0, 0, 0], tex2DArrayMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DArrayShadowGrad, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT)
+ ];
+ es3fShaderTextureFunctionTests.createCaseGroup(this, 'texturegrad', 'textureGrad() Tests', textureGradCases);
+
+ // textureGradOffset() cases
+ /** @type {Array<es3fShaderTextureFunctionTests.TexFuncCaseSpec>} */ var textureGradOffsetCases = [
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [-8, 7, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [7, -8, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('isampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [-0.2, 0.0, 0.0], true, [-8, 7, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.2, 0.0], true, [7, -8, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2darray_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [-8, 7, 0], tex2DArrayMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DArrayGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2darray_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [7, -8, 0], tex2DArrayMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DArrayGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('isampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [-0.2, 0.0, 0.0], true, [-8, 7, 0], tex2DArrayMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DArrayGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.2, 0.0], true, [7, -8, 0], tex2DArrayMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DArrayGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [-8, 7, 3], tex3DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture3DGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [7, 3, -8], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DGradOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.2], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [3, -8, 7], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DGradOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [-0.2, 0.0, 0.0], true, [-8, 7, 3], tex3DMipmapInt, es3fShaderTextureFunctionTests.evalTexture3DGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.2, 0.0], true, [7, 3, -8], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DGradOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -1.4, 0.1, 0.0], [1.5, 2.3, 2.3, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, -0.2], true, [3, -8, 7], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DGradOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 1.0, 0.0], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [-8, 7, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowGradOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-0.2, -0.4, 0.0, 0.0], [1.5, 2.3, 1.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.2, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [7, -8, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowGradOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2darrayshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 1.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], true, [-8, 7, 0], tex2DArrayMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DArrayShadowGradOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2darrayshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREGRAD, [-1.2, -0.4, -0.5, 0.0], [1.5, 2.3, 3.5, 1.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], true, [7, -8, 0], tex2DArrayMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DArrayShadowGradOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT)
+ ];
+ es3fShaderTextureFunctionTests.createCaseGroup(this, 'texturegradoffset', 'textureGradOffset() Tests', textureGradOffsetCases);
+
+ // textureProjGrad() cases
+ /** @type {Array<es3fShaderTextureFunctionTests.TexFuncCaseSpec>} */ var textureProjGradCases = [
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2d_vec3_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DProjGrad3, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2d_vec3_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DProjGrad3, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('isampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [-0.2, 0.0, 0.0], false, [0, 0, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DProjGrad3, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.2, 0.0], false, [0, 0, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DProjGrad3, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2d_vec4_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DProjGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2d_vec4_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DProjGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('isampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [-0.2, 0.0, 0.0], false, [0, 0, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DProjGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.2, 0.0], false, [0, 0, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DProjGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex3DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture3DProjGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DProjGrad, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], [0.0, 0.0, 0.0], [0.0, 0.0, 0.2], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DProjGrad, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [-0.2, 0.0, 0.0], false, [0, 0, 0], tex3DMipmapInt, es3fShaderTextureFunctionTests.evalTexture3DProjGrad, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.2, 0.0], false, [0, 0, 0], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DProjGrad, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, -0.2], false, [0, 0, 0], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DProjGrad, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.2, 0.6, 0.0, -1.5], [-2.25, -3.45, -1.5, -1.5], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], false, [0, 0, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowProjGrad, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.2, 0.6, 0.0, -1.5], [-2.25, -3.45, -1.5, -1.5], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], false, [0, 0, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowProjGrad, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT)
+ ];
+ es3fShaderTextureFunctionTests.createCaseGroup(this, 'textureprojgrad', 'textureProjGrad() Tests', textureProjGradCases);
+
+ // textureProjGradOffset() cases
+ /** @type {Array<es3fShaderTextureFunctionTests.TexFuncCaseSpec>} */ var textureProjGradOffsetCases = [
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2d_vec3_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [-8, 7, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DProjGrad3Offset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2d_vec3_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [7, -8, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DProjGrad3Offset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('isampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [-0.2, 0.0, 0.0], true, [-8, 7, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DProjGrad3Offset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler2d_vec3', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD3, [-0.3, -0.6, 1.5, 0.0], [2.25, 3.45, 1.5, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.2, 0.0], true, [7, -8, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DProjGrad3Offset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2d_vec4_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [-8, 7, 0], tex2DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture2DProjGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2d_vec4_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [7, -8, 0], tex2DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture2DProjGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('isampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [-0.2, 0.0, 0.0], true, [-8, 7, 0], tex2DMipmapInt, es3fShaderTextureFunctionTests.evalTexture2DProjGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler2d_vec4', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [-0.3, -0.6, 0.0, 1.5], [2.25, 3.45, 0.0, 1.5], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.2, 0.0], true, [7, -8, 0], tex2DMipmapUint, es3fShaderTextureFunctionTests.evalTexture2DProjGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [-8, 7, 3], tex3DMipmapFixed, es3fShaderTextureFunctionTests.evalTexture3DProjGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [7, 3, -8], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DProjGradOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], [0.0, 0.0, 0.0], [0.0, 0.0, 0.2], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [3, -8, 7], tex3DMipmapFloat, es3fShaderTextureFunctionTests.evalTexture3DProjGradOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [-0.2, 0.0, 0.0], true, [-8, 7, 3], tex3DMipmapInt, es3fShaderTextureFunctionTests.evalTexture3DProjGradOffset, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.2, 0.0], true, [7, 3, -8], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DProjGradOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.9, 1.05, -0.08, -0.75], [-1.13, -1.7, -1.7, -0.75], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, -0.2], true, [3, -8, 7], tex3DMipmapUint, es3fShaderTextureFunctionTests.evalTexture3DProjGradOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT),
+
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.2, 0.6, 0.0, -1.5], [-2.25, -3.45, -1.5, -1.5], [0.0, 0.0, 0.0], [0.2, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], true, [-8, 7, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowProjGradOffset, es3fShaderTextureFunctionTests.CaseFlags.VERTEX),
+ es3fShaderTextureFunctionTests.getGradCaseSpec('sampler2dshadow', es3fShaderTextureFunctionTests.TexFunction.TEXTUREPROJGRAD, [0.2, 0.6, 0.0, -1.5], [-2.25, -3.45, -1.5, -1.5], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, -0.2, 0.0], true, [7, -8, 0], tex2DMipmapShadow, es3fShaderTextureFunctionTests.evalTexture2DShadowProjGradOffset, es3fShaderTextureFunctionTests.CaseFlags.FRAGMENT)
+ ];
+ es3fShaderTextureFunctionTests.createCaseGroup(this, 'textureprojgradoffset', 'textureProjGradOffset() Tests', textureProjGradOffsetCases);
+
+ // texelFetch() cases
+ // \note Level is constant across quad
+ /** @type {Array<es3fShaderTextureFunctionTests.TexFuncCaseSpec>} */ var texelFetchCases = [
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [0.0, 0.0, 0.0, 0.0], [255.9, 255.9, 0.0, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DTexelFetchFixed, es3fShaderTextureFunctionTests.evalTexelFetch2D, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_float', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [0.0, 0.0, 0.0, 0.0], [127.9, 127.9, 0.0, 0.0], false, 1.0, 1.0, false, [0, 0, 0], tex2DTexelFetchFloat, es3fShaderTextureFunctionTests.evalTexelFetch2D, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [0.0, 0.0, 0.0, 0.0], [63.9, 63.9, 0.0, 0.0], false, 2.0, 2.0, false, [0, 0, 0], tex2DTexelFetchInt, es3fShaderTextureFunctionTests.evalTexelFetch2D, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [0.0, 0.0, 0.0, 0.0], [15.9, 15.9, 0.0, 0.0], false, 4.0, 4.0, false, [0, 0, 0], tex2DTexelFetchUint, es3fShaderTextureFunctionTests.evalTexelFetch2D, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [0.0, 0.0, 0.0, 0.0], [127.9, 127.9, 3.9, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex2DArrayTexelFetchFixed, es3fShaderTextureFunctionTests.evalTexelFetch2DArray, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_float', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [0.0, 0.0, 0.0, 0.0], [63.9, 63.9, 3.9, 0.0], false, 1.0, 1.0, false, [0, 0, 0], tex2DArrayTexelFetchFloat, es3fShaderTextureFunctionTests.evalTexelFetch2DArray, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [0.0, 0.0, 0.0, 0.0], [31.9, 31.9, 3.9, 0.0], false, 2.0, 2.0, false, [0, 0, 0], tex2DArrayTexelFetchInt, es3fShaderTextureFunctionTests.evalTexelFetch2DArray, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [0.0, 0.0, 0.0, 0.0], [15.9, 15.9, 3.9, 0.0], false, 3.0, 3.0, false, [0, 0, 0], tex2DArrayTexelFetchUint, es3fShaderTextureFunctionTests.evalTexelFetch2DArray, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [0.0, 0.0, 0.0, 0.0], [63.9, 31.9, 31.9, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex3DTexelFetchFixed, es3fShaderTextureFunctionTests.evalTexelFetch3D, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [0.0, 0.0, 0.0, 0.0], [31.9, 15.9, 15.9, 0.0], false, 1.0, 1.0, false, [0, 0, 0], tex3DTexelFetchFloat, es3fShaderTextureFunctionTests.evalTexelFetch3D, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [0.0, 0.0, 0.0, 0.0], [15.9, 7.9, 7.9, 0.0], false, 2.0, 2.0, false, [0, 0, 0], tex3DTexelFetchInt, es3fShaderTextureFunctionTests.evalTexelFetch3D, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [0.0, 0.0, 0.0, 0.0], [63.9, 31.9, 31.9, 0.0], false, 0.0, 0.0, false, [0, 0, 0], tex3DTexelFetchUint, es3fShaderTextureFunctionTests.evalTexelFetch3D, es3fShaderTextureFunctionTests.CaseFlags.BOTH)
+ ];
+ es3fShaderTextureFunctionTests.createCaseGroup(this, 'texelfetch', 'texelFetch() Tests', texelFetchCases);
+
+ // texelFetchOffset() cases
+ /** @type {Array<es3fShaderTextureFunctionTests.TexFuncCaseSpec>} */ var texelFetchOffsetCases = [
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [8.0, -7.0, 0.0, 0.0], [263.9, 248.9, 0.0, 0.0], false, 0.0, 0.0, true, [-8, 7, 0], tex2DTexelFetchFixed, es3fShaderTextureFunctionTests.evalTexelFetch2D, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2d_float', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [-7.0, 8.0, 0.0, 0.0], [120.9, 135.9, 0.0, 0.0], false, 1.0, 1.0, true, [7, -8, 0], tex2DTexelFetchFloat, es3fShaderTextureFunctionTests.evalTexelFetch2D, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [8.0, -7.0, 0.0, 0.0], [71.9, 56.9, 0.0, 0.0], false, 2.0, 2.0, true, [-8, 7, 0], tex2DTexelFetchInt, es3fShaderTextureFunctionTests.evalTexelFetch2D, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2d', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [-7.0, 8.0, 0.0, 0.0], [8.9, 23.9, 0.0, 0.0], false, 4.0, 4.0, true, [7, -8, 0], tex2DTexelFetchUint, es3fShaderTextureFunctionTests.evalTexelFetch2D, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [8.0, -7.0, 0.0, 0.0], [135.9, 120.9, 3.9, 0.0], false, 0.0, 0.0, true, [-8, 7, 0], tex2DArrayTexelFetchFixed, es3fShaderTextureFunctionTests.evalTexelFetch2DArray, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler2darray_float', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [-7.0, 8.0, 0.0, 0.0], [56.9, 71.9, 3.9, 0.0], false, 1.0, 1.0, true, [7, -8, 0], tex2DArrayTexelFetchFloat, es3fShaderTextureFunctionTests.evalTexelFetch2DArray, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [8.0, -7.0, 0.0, 0.0], [39.9, 24.9, 3.9, 0.0], false, 2.0, 2.0, true, [-8, 7, 0], tex2DArrayTexelFetchInt, es3fShaderTextureFunctionTests.evalTexelFetch2DArray, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler2darray', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [-7.0, 8.0, 0.0, 0.0], [8.9, 23.9, 3.9, 0.0], false, 3.0, 3.0, true, [7, -8, 0], tex2DArrayTexelFetchUint, es3fShaderTextureFunctionTests.evalTexelFetch2DArray, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_fixed', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [8.0, -7.0, -3.0, 0.0], [71.9, 24.9, 28.9, 0.0], false, 0.0, 0.0, true, [-8, 7, 3], tex3DTexelFetchFixed, es3fShaderTextureFunctionTests.evalTexelFetch3D, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('sampler3d_float', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [-7.0, -3.0, 8.0, 0.0], [24.9, 12.9, 23.9, 0.0], false, 1.0, 1.0, true, [7, 3, -8], tex3DTexelFetchFloat, es3fShaderTextureFunctionTests.evalTexelFetch3D, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('isampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [-3.0, 8.0, -7.0, 0.0], [12.9, 15.9, 0.9, 0.0], false, 2.0, 2.0, true, [3, -8, 7], tex3DTexelFetchInt, es3fShaderTextureFunctionTests.evalTexelFetch3D, es3fShaderTextureFunctionTests.CaseFlags.BOTH),
+ es3fShaderTextureFunctionTests.getCaseSpec('usampler3d', es3fShaderTextureFunctionTests.TexFunction.TEXELFETCH, [8.0, -7.0, -3.0, 0.0], [71.9, 24.9, 28.9, 0.0], false, 0.0, 0.0, true, [-8, 7, 3], tex3DTexelFetchUint, es3fShaderTextureFunctionTests.evalTexelFetch3D, es3fShaderTextureFunctionTests.CaseFlags.BOTH)
+ ];
+ es3fShaderTextureFunctionTests.createCaseGroup(this, 'texelfetchoffset', 'texelFetchOffset() Tests', texelFetchOffsetCases);
+
+ // textureSize() cases
+ /**
+ * @struct
+ * @constructor
+ * @param {string} name
+ * @param {string} samplerName
+ * @param {es3fShaderTextureFunctionTests.TextureSpec} textureSpec
+ */
+ var TextureSizeCaseSpec = function(name, samplerName, textureSpec) {
+ /** @type {string} */ this.name = name;
+ /** @type {string} */ this.samplerName = samplerName;
+ /** @type {es3fShaderTextureFunctionTests.TextureSpec} */ this.textureSpec = textureSpec;
+ };
+
+ /** @type {Array<TextureSizeCaseSpec>} */ var textureSizeCases = [
+ new TextureSizeCaseSpec('sampler2d_fixed', 'sampler2D', tex2DFixed),
+ new TextureSizeCaseSpec('sampler2d_float', 'sampler2D', tex2DFloat),
+ new TextureSizeCaseSpec('isampler2d', 'isampler2D', tex2DInt),
+ new TextureSizeCaseSpec('usampler2d', 'usampler2D', tex2DUint),
+ new TextureSizeCaseSpec('sampler2dshadow', 'sampler2DShadow', tex2DShadow),
+ new TextureSizeCaseSpec('sampler3d_fixed', 'sampler3D', tex3DFixed),
+ new TextureSizeCaseSpec('sampler3d_float', 'sampler3D', tex3DFloat),
+ new TextureSizeCaseSpec('isampler3d', 'isampler3D', tex3DInt),
+ new TextureSizeCaseSpec('usampler3d', 'usampler3D', tex3DUint),
+ new TextureSizeCaseSpec('samplercube_fixed', 'samplerCube', texCubeFixed),
+ new TextureSizeCaseSpec('samplercube_float', 'samplerCube', texCubeFloat),
+ new TextureSizeCaseSpec('isamplercube', 'isamplerCube', texCubeInt),
+ new TextureSizeCaseSpec('usamplercube', 'usamplerCube', texCubeUint),
+ new TextureSizeCaseSpec('samplercubeshadow', 'samplerCubeShadow', texCubeShadow),
+ new TextureSizeCaseSpec('sampler2darray_fixed', 'sampler2DArray', tex2DArrayFixed),
+ new TextureSizeCaseSpec('sampler2darray_float', 'sampler2DArray', tex2DArrayFloat),
+ new TextureSizeCaseSpec('isampler2darray', 'isampler2DArray', tex2DArrayInt),
+ new TextureSizeCaseSpec('usampler2darray', 'usampler2DArray', tex2DArrayUint),
+ new TextureSizeCaseSpec('sampler2darrayshadow', 'sampler2DArrayShadow', tex2DArrayShadow)
+ ];
+
+ /** @type {tcuTestCase.DeqpTest} */ var group = tcuTestCase.newTest('texturesize', 'textureSize() Tests');
+ testGroup.addChild(group);
+
+ for (var ndx = 0; ndx < textureSizeCases.length; ++ndx) {
+ group.addChild(new es3fShaderTextureFunctionTests.TextureSizeCase(textureSizeCases[ndx].name + '_vertex', '', textureSizeCases[ndx].samplerName, textureSizeCases[ndx].textureSpec, true));
+ group.addChild(new es3fShaderTextureFunctionTests.TextureSizeCase(textureSizeCases[ndx].name + '_fragment', '', textureSizeCases[ndx].samplerName, textureSizeCases[ndx].textureSpec, false));
+ }
+
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ * @param {Array<number>=} range Test range
+ */
+ es3fShaderTextureFunctionTests.run = function(context, range) {
+ gl = context;
+
+ const canvas = gl.canvas;
+ canvas.width = canvasWH;
+ canvas.height = canvasWH;
+
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fShaderTextureFunctionTests.ShaderTextureFunctionTests());
+ if (range)
+ state.setRange(range);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fShaderTextureFunctionTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fStringQueryTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fStringQueryTests.js
new file mode 100644
index 0000000000..8e90ff576b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fStringQueryTests.js
@@ -0,0 +1,111 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fStringQueryTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('functional.gles3.es3fApiCase');
+
+goog.scope(function() {
+ var es3fStringQueryTests = functional.gles3.es3fStringQueryTests;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var es3fApiCase = functional.gles3.es3fApiCase;
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fStringQueryTests.StringQueryTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'string', 'String Query tests');
+ };
+
+ es3fStringQueryTests.StringQueryTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fStringQueryTests.StringQueryTests.prototype.constructor = es3fStringQueryTests.StringQueryTests;
+
+ es3fStringQueryTests.StringQueryTests.prototype.init = function() {
+ this.addChild(new es3fApiCase.ApiCaseCallback('renderer', 'RENDERER', gl, function() {
+ var string = /** @type {string} */ (gl.getParameter(gl.RENDERER));
+ this.check(string !== null,
+ 'Got invalid string: ' + string);
+ }));
+
+ this.addChild(new es3fApiCase.ApiCaseCallback('vendor', 'VENDOR', gl, function() {
+ var string = /** @type {string} */ (gl.getParameter(gl.VENDOR));
+ this.check(string !== null,
+ 'Got invalid string: ' + string);
+ }));
+
+ this.addChild(new es3fApiCase.ApiCaseCallback('version', 'VERSION', gl, function() {
+ var string = /** @type {string} */ (gl.getParameter(gl.VERSION));
+ /** @type {string} */ var referenceString = 'WebGL 2.0';
+
+ this.check(string !== null && string.indexOf(referenceString) === 0,
+ 'Got invalid string prefix: ' + string + ' expected: ' + referenceString);
+ }));
+
+ this.addChild(new es3fApiCase.ApiCaseCallback('shading_language_version', 'SHADING_LANGUAGE_VERSION', gl, function() {
+ var string = /** @type {string} */ (gl.getParameter(gl.SHADING_LANGUAGE_VERSION));
+ /** @type {string} */ var referenceString = 'WebGL GLSL ES 3.00';
+
+ this.check(string !== null, 'Got invalid string');
+ this.check(string.indexOf(referenceString) === 0, 'Got invalid string prefix');
+ }));
+
+ this.addChild(new es3fApiCase.ApiCaseCallback('extensions', 'EXTENSIONS', gl, function() {
+ /** @type {Array<string>} */ var extensions = gl.getSupportedExtensions();
+ this.check(extensions !== null, 'Got invalid string');
+
+ // [dag] check that all extensions from gl.getSupportedExtensions() are found using gl.getExtension()
+ for (var i in extensions) {
+ /** @type {Object} */ var extension = gl.getExtension(extensions[i]);
+ this.check(extension !== null, 'Advertised extension ' + extensions[i] + ' not found');
+ }
+
+ // [dag] check that gl.getExtension() returns null for items not in gl.getSupportedExtensions()
+ this.check(gl.getExtension('Random_String') === null, 'Extension query methods are not consistent.');
+ }));
+
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fStringQueryTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fStringQueryTests.StringQueryTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fStringQueryTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fSyncTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fSyncTests.js
new file mode 100644
index 0000000000..bd18845d9e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fSyncTests.js
@@ -0,0 +1,330 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fSyncTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluShaderProgram');
+
+goog.scope(function() {
+ var es3fSyncTests = functional.gles3.es3fSyncTests;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var deRandom = framework.delibs.debase.deRandom;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var deString = framework.delibs.debase.deString;
+
+ /** @const {number} */ es3fSyncTests.NUM_CASE_ITERATIONS = 5;
+ /** @const {number} */ es3fSyncTests.MAX_VERIFY_WAIT = 5;
+
+ /**
+ * @enum
+ */
+ es3fSyncTests.WaitCommand = {
+ WAIT_SYNC: 1,
+ CLIENT_WAIT_SYNC: 2
+ };
+
+ /** @enum
+ */
+ es3fSyncTests.CaseOptions = {
+ FLUSH_BEFORE_WAIT: 1,
+ FINISH_BEFORE_WAIT: 2
+ };
+
+ /** @enum
+ */
+ es3fSyncTests.State = {
+ DRAW: 0,
+ VERIFY: 1,
+ FINISH: 2
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} numPrimitives
+ * @param {number} waitCommand
+ * @param {number} waitFlags
+ * @param {number} timeout
+ * @param {number} options
+ */
+ es3fSyncTests.FenceSyncCase = function(name, description, numPrimitives, waitCommand, waitFlags, timeout, options) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ /** @type {number} */ this.m_numPrimitives = numPrimitives;
+ /** @type {number} */ this.m_waitCommand = waitCommand;
+ /** @type {number} */ this.m_waitFlags = waitFlags;
+ /** @type {number} */ this.m_timeout = timeout;
+ /** @type {number} */ this.m_caseOptions = options;
+
+ /** @type {gluShaderProgram.ShaderProgram} */ this.m_program = null;
+ /** @type {WebGLSync} */ this.m_syncObject = null;
+ /** @type {number} */ this.m_iterNdx = 0;
+ /** @type {deRandom.Random} */ this.m_rnd = new deRandom.Random(deString.deStringHash(this.name));
+ /** @type {es3fSyncTests.State} */ this.m_state = es3fSyncTests.State.DRAW;
+ };
+
+ es3fSyncTests.FenceSyncCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fSyncTests.FenceSyncCase.prototype.constructor = es3fSyncTests.FenceSyncCase;
+
+ /**
+ * @param {number} numPrimitives
+ * @param {deRandom.Random} rnd
+ * @return {Array<number>}
+ */
+ es3fSyncTests.generateVertices = function(numPrimitives, rnd) {
+ /** @type {Array<number>} */ var dst = [];
+ /** @type {number} */ var numVertices = 3 * numPrimitives;
+
+ for (var i = 0; i < numVertices; i++) {
+ dst.push(rnd.getFloat(-1.0, 1.0)); // x
+ dst.push(rnd.getFloat(-1.0, 1.0)); // y
+ dst.push(rnd.getFloat(0.0, 1.0)); // z
+ dst.push(1.0); // w
+ }
+ return dst;
+ };
+
+ es3fSyncTests.FenceSyncCase.prototype.init = function() {
+ /** @type {string} */ var vertShaderSource = '#version 300 es\n' +
+ 'layout(location = 0) in mediump vec4 a_position;\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' gl_Position = a_position;\n' +
+ '}\n';
+
+ /** @type {string} */ var fragShaderSource = '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ '\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ ' o_color = vec4(0.25, 0.5, 0.75, 1.0);\n' +
+ '}\n';
+
+ assertMsgOptions(!this.m_program, 'Program should be null.', false, true);
+ this.m_program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertShaderSource, fragShaderSource));
+
+ if (!this.m_program.isOk())
+ throw new Error('Failed to compile shader program');
+ };
+
+ es3fSyncTests.FenceSyncCase.prototype.deinit = function() {
+ if (this.m_program)
+ this.m_program = null;
+
+ if (this.m_syncObject) {
+ gl.deleteSync(this.m_syncObject);
+ this.m_syncObject = null;
+ }
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fSyncTests.FenceSyncCase.prototype.draw = function() {
+ /** @type {Array<number>} */ var vertices = [];
+
+ /** @type {string} */ var header = 'Case iteration ' + (this.m_iterNdx + 1) + ' / ' + es3fSyncTests.NUM_CASE_ITERATIONS;
+ bufferedLogToConsole(header);
+
+ assertMsgOptions(this.m_program !== null, 'Expected program', false, true);
+ gl.useProgram(this.m_program.getProgram());
+ gl.enable(gl.DEPTH_TEST);
+ gl.clearColor(0.3, 0.3, 0.3, 1.0);
+ gl.clearDepth(1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+
+ // Generate vertices
+
+ gl.enableVertexAttribArray(0);
+ vertices = es3fSyncTests.generateVertices(this.m_numPrimitives, this.m_rnd);
+
+ /** @type {WebGLBuffer} */ var vertexGLBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexGLBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
+ gl.vertexAttribPointer(0, 4, gl.FLOAT, false, 0, 0);
+
+ // Draw
+
+ gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 4);
+ bufferedLogToConsole('Primitives drawn.');
+
+ // Create sync object
+
+ this.m_syncObject = gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE, 0);
+ bufferedLogToConsole('Sync object created');
+
+ if (this.m_caseOptions & es3fSyncTests.CaseOptions.FLUSH_BEFORE_WAIT)
+ gl.flush();
+ if (this.m_caseOptions & es3fSyncTests.CaseOptions.FINISH_BEFORE_WAIT)
+ gl.finish();
+ this.m_state = es3fSyncTests.State.VERIFY;
+ };
+
+
+ es3fSyncTests.FenceSyncCase.prototype.verify = function() {
+ /** @type {number} */ var waitValue = 0;
+ /** @type {boolean} */ var testOk = true;
+
+ // Wait for sync object
+ if (this.m_waitCommand & es3fSyncTests.WaitCommand.WAIT_SYNC) {
+ assertMsgOptions(this.m_timeout === gl.TIMEOUT_IGNORED, 'Expected TIMEOUT_IGNORED', false, true);
+ assertMsgOptions(this.m_waitFlags === 0, 'Expected waitFlags = 0', false, true);
+ gl.waitSync(this.m_syncObject, this.m_waitFlags, this.m_timeout);
+ bufferedLogToConsole('Wait command glWaitSync called with GL_TIMEOUT_IGNORED.');
+ }
+
+ if (this.m_waitCommand & es3fSyncTests.WaitCommand.CLIENT_WAIT_SYNC) {
+ waitValue = gl.clientWaitSync(this.m_syncObject, this.m_waitFlags, this.m_timeout);
+ bufferedLogToConsole('glClientWaitSync return value:');
+ switch (waitValue) {
+ case gl.ALREADY_SIGNALED:
+ bufferedLogToConsole('gl.ALREADY_SIGNALED');
+ break;
+ case gl.TIMEOUT_EXPIRED:
+ bufferedLogToConsole('gl.TIMEOUT_EXPIRED');
+ break;
+ case gl.CONDITION_SATISFIED:
+ bufferedLogToConsole('gl.CONDITION_SATISFIED');
+ break;
+ case gl.WAIT_FAILED:
+ bufferedLogToConsole('gl.WAIT_FAILED');
+ testOk = false;
+ break;
+ default:
+ bufferedLogToConsole('Illegal return value!');
+ }
+ }
+
+ gl.finish();
+
+ // Delete sync object
+
+ if (this.m_syncObject && testOk) {
+ gl.deleteSync(this.m_syncObject);
+ this.m_syncObject = null;
+ bufferedLogToConsole('Sync object deleted.');
+ }
+
+ // Evaluate test result
+
+ bufferedLogToConsole('Test result: ' + (testOk ? 'Passed!' : 'Failed!'));
+
+ if (!testOk) {
+ if (!this.m_verifyStart)
+ this.m_verifyStart = new Date();
+ else {
+ var current = new Date();
+ var elapsedTime = 0.001 * (current.getTime() - this.m_verifyStart.getTime());
+ if (elapsedTime > es3fSyncTests.MAX_VERIFY_WAIT) {
+ testFailedOptions('Fail', false);
+ this.m_state = es3fSyncTests.State.FINISH;
+ if (this.m_syncObject) {
+ gl.deleteSync(this.m_syncObject);
+ this.m_syncObject = null;
+ bufferedLogToConsole('Sync object deleted.');
+ }
+ }
+ }
+ } else {
+ bufferedLogToConsole('Sync objects created and deleted successfully.');
+ testPassedOptions('Pass', true);
+ this.m_state = (++this.m_iterNdx < es3fSyncTests.NUM_CASE_ITERATIONS) ? es3fSyncTests.State.DRAW : es3fSyncTests.State.FINISH;
+ }
+ };
+
+ es3fSyncTests.FenceSyncCase.prototype.iterate = function() {
+ switch (this.m_state) {
+ case es3fSyncTests.State.DRAW:
+ this.draw();
+ break;
+ case es3fSyncTests.State.VERIFY:
+ this.verify();
+ break;
+ case es3fSyncTests.State.FINISH:
+ return tcuTestCase.IterateResult.STOP;
+ default:
+ throw new Error('Invalid state: ' + this.m_state);
+ }
+
+ return tcuTestCase.IterateResult.CONTINUE;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fSyncTests.SyncTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'fence_sync', 'Fence Sync Tests');
+ };
+
+ es3fSyncTests.SyncTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fSyncTests.SyncTests.prototype.constructor = es3fSyncTests.SyncTests;
+
+ es3fSyncTests.SyncTests.prototype.init = function() {
+ // Fence sync tests.
+
+ this.addChild(new es3fSyncTests.FenceSyncCase('wait_sync_smalldraw', '', 10, es3fSyncTests.WaitCommand.WAIT_SYNC, 0, gl.TIMEOUT_IGNORED, 0));
+ this.addChild(new es3fSyncTests.FenceSyncCase('wait_sync_largedraw', '', 100000, es3fSyncTests.WaitCommand.WAIT_SYNC, 0, gl.TIMEOUT_IGNORED, 0));
+
+ this.addChild(new es3fSyncTests.FenceSyncCase('client_wait_sync_smalldraw', '', 10, es3fSyncTests.WaitCommand.CLIENT_WAIT_SYNC, 0, 0, 0));
+ this.addChild(new es3fSyncTests.FenceSyncCase('client_wait_sync_largedraw', '', 100000, es3fSyncTests.WaitCommand.CLIENT_WAIT_SYNC, 0, 0, 0));
+
+ // Originally the next two test cases' timeout is 10, but in WebGL2 that could be illegal.
+ var max = gl.getParameter(gl.MAX_CLIENT_WAIT_TIMEOUT_WEBGL) || 0;
+ this.addChild(new es3fSyncTests.FenceSyncCase('client_wait_sync_timeout_smalldraw', '', 10, es3fSyncTests.WaitCommand.CLIENT_WAIT_SYNC, 0, max, 0));
+ this.addChild(new es3fSyncTests.FenceSyncCase('client_wait_sync_timeout_largedraw', '', 100000, es3fSyncTests.WaitCommand.CLIENT_WAIT_SYNC, 0, max, 0));
+
+ this.addChild(new es3fSyncTests.FenceSyncCase('client_wait_sync_flush_auto', '', 100000, es3fSyncTests.WaitCommand.CLIENT_WAIT_SYNC, gl.SYNC_FLUSH_COMMANDS_BIT, 0, 0));
+ this.addChild(new es3fSyncTests.FenceSyncCase('client_wait_sync_flush_manual', '', 100000, es3fSyncTests.WaitCommand.CLIENT_WAIT_SYNC, 0, 0, es3fSyncTests.CaseOptions.FLUSH_BEFORE_WAIT));
+ this.addChild(new es3fSyncTests.FenceSyncCase('client_wait_sync_noflush', '', 100000, es3fSyncTests.WaitCommand.CLIENT_WAIT_SYNC, 0, 0, 0));
+ this.addChild(new es3fSyncTests.FenceSyncCase('client_wait_sync_finish', '', 100000, es3fSyncTests.WaitCommand.CLIENT_WAIT_SYNC, 0, 0, es3fSyncTests.CaseOptions.FINISH_BEFORE_WAIT));
+
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fSyncTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fSyncTests.SyncTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fSyncTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureFilteringTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureFilteringTests.js
new file mode 100644
index 0000000000..45ff09a11c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureFilteringTests.js
@@ -0,0 +1,2282 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fTextureFilteringTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuLogImage');
+goog.require('framework.common.tcuPixelFormat');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexLookupVerifier');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTexture');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('functional.gles3.es3fFboTestUtil');
+goog.require('modules.shared.glsTextureTestUtil');
+
+goog.scope(function() {
+
+ var es3fTextureFilteringTests = functional.gles3.es3fTextureFilteringTests;
+ var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluTextureUtil = framework.opengl.gluTextureUtil;
+ var tcuImageCompare = framework.common.tcuImageCompare;
+ var tcuLogImage = framework.common.tcuLogImage;
+ var tcuPixelFormat = framework.common.tcuPixelFormat;
+ var tcuRGBA = framework.common.tcuRGBA;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuTexLookupVerifier = framework.common.tcuTexLookupVerifier;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuTexture = framework.common.tcuTexture;
+ var tcuTextureUtil = framework.common.tcuTextureUtil;
+ var deMath = framework.delibs.debase.deMath;
+ var deString = framework.delibs.debase.deString;
+ var deRandom = framework.delibs.debase.deRandom;
+ var gluTexture = framework.opengl.gluTexture;
+ var glsTextureTestUtil = modules.shared.glsTextureTestUtil;
+
+ /** @type {WebGL2RenderingContext} */ var gl;
+
+ es3fTextureFilteringTests.version =
+ gluShaderUtil.getGLSLVersionString(gluShaderUtil.GLSLVersion.V300_ES);
+
+ let canvasWH = 256;
+ let viewportWH = 64;
+
+ if (tcuTestCase.isQuickMode()) {
+ canvasWH = 64;
+ viewportWH = 32;
+ }
+
+ const TEX2D_VIEWPORT_WIDTH = viewportWH;
+ const TEX2D_VIEWPORT_HEIGHT = viewportWH;
+ const TEX2D_MIN_VIEWPORT_WIDTH = viewportWH;
+ const TEX2D_MIN_VIEWPORT_HEIGHT = viewportWH;
+
+ const TEX3D_VIEWPORT_WIDTH = viewportWH;
+ const TEX3D_VIEWPORT_HEIGHT = viewportWH;
+ const TEX3D_MIN_VIEWPORT_WIDTH = viewportWH;
+ const TEX3D_MIN_VIEWPORT_HEIGHT = viewportWH;
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fTextureFilteringTests.TextureFilteringTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'filtering', 'Texture Filtering Tests');
+ };
+
+ es3fTextureFilteringTests.TextureFilteringTests.prototype =
+ Object.create(tcuTestCase.DeqpTest.prototype);
+
+ es3fTextureFilteringTests.TextureFilteringTests.prototype.constructor =
+ es3fTextureFilteringTests.TextureFilteringTests;
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} minFilter
+ * @param {number} magFilter
+ * @param {number} wrapS
+ * @param {number} wrapT
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ */
+ es3fTextureFilteringTests.Texture2DFilteringCase = function(
+ name, desc, minFilter, magFilter, wrapS, wrapT,
+ internalFormat, width, height
+ ) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ this.m_minFilter = minFilter;
+ this.m_magFilter = magFilter;
+ this.m_wrapS = wrapS;
+ this.m_wrapT = wrapT;
+ this.m_internalFormat = internalFormat;
+ this.m_width = width;
+ this.m_height = height;
+ /** @type {glsTextureTestUtil.TextureRenderer} */
+ this.m_renderer = new glsTextureTestUtil.TextureRenderer(
+ es3fTextureFilteringTests.version,
+ gluShaderUtil.precision.PRECISION_HIGHP
+ );
+ this.m_caseNdx = 0;
+ /** @type {Array<gluTexture.Texture2D>} */ this.m_textures = [];
+ this.m_cases = [];
+ };
+
+ es3fTextureFilteringTests.Texture2DFilteringCase.prototype =
+ Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fTextureFilteringTests.Texture2DFilteringCase.prototype.constructor =
+ es3fTextureFilteringTests.Texture2DFilteringCase;
+
+ /**
+ * @constructor
+ * @param {gluTexture.Texture2D} tex_
+ * @param {Array<number>} minCoord_
+ * @param {Array<number>} maxCoord_
+ */
+ es3fTextureFilteringTests.Texture2DFilteringCase.FilterCase = function(
+ tex_, minCoord_, maxCoord_
+ ) {
+ this.texture = tex_;
+ this.minCoord = minCoord_;
+ this.maxCoord = maxCoord_;
+ };
+
+ /** @typedef {{texNdx: number, lodX: number,
+ * lodY: number, oX: number, oY: number}} */
+ es3fTextureFilteringTests.Cases;
+
+ /**
+ * init
+ */
+ es3fTextureFilteringTests.Texture2DFilteringCase.prototype.init =
+ function() {
+ try {
+ // Create 2 textures.
+ for (var ndx = 0; ndx < 2; ndx++)
+ this.m_textures.push(
+ gluTexture.texture2DFromInternalFormat(
+ gl, this.m_internalFormat,
+ this.m_width, this.m_height
+ )
+ );
+
+ var mipmaps = true;
+ var numLevels = mipmaps ? deMath.logToFloor(
+ Math.max(this.m_width, this.m_height)
+ ) + 1 : 1;
+
+ /** @type {tcuTextureUtil.TextureFormatInfo} */
+ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(
+ this.m_textures[0].getRefTexture().getFormat()
+ );
+ /** @type {Array<number>} */ var cBias = fmtInfo.valueMin;
+ /** @type {Array<number>} */
+ var cScale = deMath.subtract(
+ fmtInfo.valueMax, fmtInfo.valueMin
+ );
+
+ // Fill first gradient texture.
+ for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ /** @type {Array<number>} */ var gMin = deMath.add(
+ deMath.multiply([0.0, 0.0, 0.0, 1.0], cScale), cBias
+ );
+ /** @type {Array<number>} */ var gMax = deMath.add(
+ deMath.multiply([1.0, 1.0, 1.0, 0.0], cScale), cBias
+ );
+
+ this.m_textures[0].getRefTexture().allocLevel(levelNdx);
+ tcuTextureUtil.fillWithComponentGradients(
+ this.m_textures[0].getRefTexture().getLevel(levelNdx),
+ gMin, gMax
+ );
+ }
+
+ // Fill second with grid texture.
+ for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ /** @type {number} */ var step = 0x00ffffff / numLevels;
+ /** @type {number} */ var rgb = step * levelNdx;
+ /** @type {number} */ var colorA = deMath.binaryOp(
+ 0xff000000, rgb, deMath.BinaryOp.OR
+ );
+ /** @type {number} */ var colorB = deMath.binaryOp(
+ 0xff000000, deMath.binaryNot(rgb), deMath.BinaryOp.OR
+ );
+
+ this.m_textures[1].getRefTexture().allocLevel(levelNdx);
+ tcuTextureUtil.fillWithGrid(
+ this.m_textures[1].getRefTexture().getLevel(levelNdx),
+ 4,
+ deMath.add(deMath.multiply(
+ tcuRGBA.newRGBAFromValue(colorA).toVec(), cScale),
+ cBias
+ ),
+ deMath.add(deMath.multiply(
+ tcuRGBA.newRGBAFromValue(colorB).toVec(), cScale),
+ cBias
+ )
+ );
+ }
+
+ // Upload.
+ for (var i = 0; i < this.m_textures.length; i++)
+ this.m_textures[i].upload();
+
+ // Compute cases.
+
+ /** @type {Array<es3fTextureFilteringTests.Cases>} */
+ var cases = [{
+ texNdx: 0, lodX: 1.6, lodY: 2.9, oX: -1.0, oY: -2.7
+ }, {
+ texNdx: 0, lodX: -2.0, lodY: -1.35, oX: -0.2, oY: 0.7
+ }, {
+ texNdx: 1, lodX: 0.14, lodY: 0.275, oX: -1.5, oY: -1.1
+ }, {
+ texNdx: 1, lodX: -0.92, lodY: -2.64, oX: 0.4, oY: -0.1
+ }
+ ];
+
+ var viewportW = Math.min(
+ TEX2D_VIEWPORT_WIDTH, gl.canvas.width
+ );
+ var viewportH = Math.min(
+ TEX2D_VIEWPORT_HEIGHT, gl.canvas.height
+ );
+
+ for (var caseNdx = 0; caseNdx < cases.length; caseNdx++) {
+ /** @type {number} */ var texNdx = deMath.clamp(
+ cases[caseNdx].texNdx, 0, this.m_textures.length - 1
+ );
+ /** @type {number} */ var lodX = cases[caseNdx].lodX;
+ /** @type {number} */ var lodY = cases[caseNdx].lodY;
+ /** @type {number} */ var oX = cases[caseNdx].oX;
+ /** @type {number} */ var oY = cases[caseNdx].oY;
+ /** @type {number} */ var sX = Math.exp(lodX * Math.log(2)) * viewportW /
+ this.m_textures[texNdx].getRefTexture().getWidth();
+ /** @type {number} */ var sY = Math.exp(lodY * Math.log(2)) * viewportH /
+ this.m_textures[texNdx].getRefTexture().getHeight();
+
+ this.m_cases.push(
+ new
+ es3fTextureFilteringTests.Texture2DFilteringCase.FilterCase(
+ this.m_textures[texNdx], [oX, oY], [oX + sX, oY + sY]
+ )
+ );
+ }
+
+ this.m_caseNdx = 0;
+ }
+ catch (e) {
+ // Clean up to save memory.
+ this.deinit();
+ throw e;
+ }
+ };
+
+ /**
+ * deinit
+ */
+ es3fTextureFilteringTests.Texture2DFilteringCase.prototype.deinit =
+ function() {
+ while (this.m_textures.length > 0) {
+ gl.deleteTexture(this.m_textures[0].getGLTexture());
+ this.m_textures.splice(0, 1);
+ }
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fTextureFilteringTests.Texture2DFilteringCase.prototype.iterate =
+ function() {
+ /** @type {glsTextureTestUtil.RandomViewport} */
+ var viewport = new glsTextureTestUtil.RandomViewport(
+ gl.canvas, TEX2D_VIEWPORT_WIDTH,
+ TEX2D_VIEWPORT_HEIGHT, deMath.binaryOp(
+ deString.deStringHash(this.fullName()),
+ deMath.deMathHash(this.m_caseNdx),
+ deMath.BinaryOp.XOR
+ )
+ );
+ /** @type {tcuTexture.TextureFormat} */
+ var texFmt = this.m_textures[0].getRefTexture().getFormat();
+
+ /** @type {tcuTextureUtil.TextureFormatInfo} */
+ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
+ var curCase = this.m_cases[this.m_caseNdx];
+ bufferedLogToConsole('Test ' + this.m_caseNdx);
+ var refParams = new glsTextureTestUtil.ReferenceParams(
+ glsTextureTestUtil.textureType.TEXTURETYPE_2D
+ );
+ var rendered = new tcuSurface.Surface(viewport.width, viewport.height);
+ var texCoord = [0, 0];
+
+ if (viewport.width < TEX2D_MIN_VIEWPORT_WIDTH ||
+ viewport.height < TEX2D_MIN_VIEWPORT_HEIGHT)
+ throw new Error('Too small render target');
+
+ // Setup params for reference.
+ refParams.sampler = gluTextureUtil.mapGLSamplerWrapST(
+ this.m_wrapS, this.m_wrapT, this.m_minFilter, this.m_magFilter
+ );
+ refParams.samplerType = glsTextureTestUtil.getSamplerType(texFmt);
+ refParams.lodMode = glsTextureTestUtil.lodMode.EXACT;
+ refParams.colorBias = fmtInfo.lookupBias;
+ refParams.colorScale = fmtInfo.lookupScale;
+
+ // Compute texture coordinates.
+ bufferedLogToConsole(
+ 'Texture coordinates: ' + curCase.minCoord +
+ ' -> ' + curCase.maxCoord
+ );
+ texCoord = glsTextureTestUtil.computeQuadTexCoord2D(
+ curCase.minCoord, curCase.maxCoord
+ );
+
+ gl.bindTexture(gl.TEXTURE_2D, curCase.texture.getGLTexture());
+ gl.texParameteri(
+ gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.m_minFilter
+ );
+ gl.texParameteri(
+ gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.m_magFilter
+ );
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, this.m_wrapS);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, this.m_wrapT);
+
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+
+ this.m_renderer.renderQuad(0, texCoord, refParams);
+ rendered.readViewport(
+ gl, [viewport.x, viewport.y, viewport.width, viewport.height]
+ );
+
+ /** @type {boolean} */ var isNearestOnly =
+ this.m_minFilter == gl.NEAREST && this.m_magFilter == gl.NEAREST;
+ /** @type {tcuPixelFormat.PixelFormat} */
+ var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
+
+ //(iVec4)
+ var colorBits = deMath.max(
+ deMath.addScalar(
+ glsTextureTestUtil.getBitsVec(pixelFormat),
+ // 1 inaccurate bit if nearest only, 2 otherwise
+ -1 * (isNearestOnly ? 1 : 2)
+ ),
+ [0, 0, 0, 0]
+ );
+
+ /** @type {tcuTexLookupVerifier.LodPrecision} */
+ var lodPrecision = new tcuTexLookupVerifier.LodPrecision();
+ /** @type {tcuTexLookupVerifier.LookupPrecision} */
+ var lookupPrecision = new tcuTexLookupVerifier.LookupPrecision();
+
+ lodPrecision.derivateBits = 18;
+ lodPrecision.lodBits = 6;
+ lookupPrecision.colorThreshold = deMath.divide(
+ tcuTexLookupVerifier.computeFixedPointThreshold(colorBits),
+ refParams.colorScale
+ );
+ lookupPrecision.coordBits = [20, 20, 0];
+ lookupPrecision.uvwBits = [7, 7, 0];
+ lookupPrecision.colorMask =
+ glsTextureTestUtil.getCompareMask(pixelFormat);
+
+ var isHighQuality = glsTextureTestUtil.verifyTexture2DResult(
+ rendered.getAccess(), curCase.texture.getRefTexture(),
+ texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat
+ );
+
+ if (!isHighQuality) {
+ // Evaluate against lower precision requirements.
+ lodPrecision.lodBits = 4;
+ lookupPrecision.uvwBits = [4, 4, 0];
+
+ bufferedLogToConsole('Warning: Verification against high ' +
+ 'precision requirements failed, trying with lower ' +
+ 'requirements.'
+ );
+
+ var isOk = glsTextureTestUtil.verifyTexture2DResult(
+ rendered.getAccess(), curCase.texture.getRefTexture(),
+ texCoord, refParams, lookupPrecision, lodPrecision,
+ pixelFormat
+ );
+
+ if (!isOk) {
+ bufferedLogToConsole(
+ 'ERROR: Verification against low ' +
+ 'precision requirements failed, failing test case.'
+ );
+ testFailedOptions('Image verification failed', false);
+ //In JS version, one mistake and you're out
+ return tcuTestCase.IterateResult.STOP;
+ } else
+ checkMessage(
+ false,
+ 'Low-quality filtering result in iteration no. ' +
+ this.m_caseNdx
+ );
+ }
+
+ this.m_caseNdx += 1;
+ if (this.m_caseNdx < this.m_cases.length)
+ return tcuTestCase.IterateResult.CONTINUE;
+
+ testPassed('Verified');
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} minFilter
+ * @param {number} magFilter
+ * @param {number} wrapS
+ * @param {number} wrapT
+ * @param {boolean} onlySampleFaceInterior
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ */
+ es3fTextureFilteringTests.TextureCubeFilteringCase = function(
+ name, desc, minFilter, magFilter, wrapS, wrapT, onlySampleFaceInterior,
+ internalFormat, width, height
+ ) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ this.m_minFilter = minFilter;
+ this.m_magFilter = magFilter;
+ this.m_wrapS = wrapS;
+ this.m_wrapT = wrapT;
+ /** @type {boolean}*/
+ this.m_onlySampleFaceInterior = onlySampleFaceInterior;
+ this.m_internalFormat = internalFormat;
+ this.m_width = width;
+ this.m_height = height;
+ /** @type {glsTextureTestUtil.TextureRenderer} */
+ this.m_renderer = new glsTextureTestUtil.TextureRenderer(
+ es3fTextureFilteringTests.version,
+ gluShaderUtil.precision.PRECISION_HIGHP
+ );
+ this.m_caseNdx = 0;
+ /** @type {Array<gluTexture.TextureCube>} */ this.m_textures = [];
+ /** @type {Array<es3fTextureFilteringTests.
+ * TextureCubeFilteringCase.FilterCase>}
+ */
+ this.m_cases = [];
+ };
+
+ /**
+ * @constructor
+ * @param {gluTexture.TextureCube} tex_
+ * @param {Array<number>} bottomLeft_
+ * @param {Array<number>} topRight_
+ */
+ es3fTextureFilteringTests.TextureCubeFilteringCase.FilterCase = function(
+ tex_, bottomLeft_, topRight_
+ ) {
+ this.texture = tex_;
+ this.bottomLeft = bottomLeft_;
+ this.topRight = topRight_;
+ };
+
+ es3fTextureFilteringTests.TextureCubeFilteringCase.prototype =
+ Object.create(tcuTestCase.DeqpTest.prototype);
+
+ es3fTextureFilteringTests.TextureCubeFilteringCase.prototype.constructor =
+ es3fTextureFilteringTests.TextureCubeFilteringCase;
+
+ /**
+ * init
+ */
+ es3fTextureFilteringTests.TextureCubeFilteringCase.prototype.init =
+ function() {
+ try {
+ assertMsgOptions(
+ this.m_width == this.m_height, 'Texture has to be squared',
+ false, true
+ );
+ for (var ndx = 0; ndx < 2; ndx++)
+ this.m_textures.push(gluTexture.cubeFromInternalFormat(
+ gl, this.m_internalFormat, this.m_width
+ ));
+
+ var numLevels = deMath.logToFloor(
+ Math.max(this.m_width, this.m_height)
+ ) + 1;
+ /** @type {tcuTextureUtil.TextureFormatInfo} */
+ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(
+ this.m_textures[0].getRefTexture().getFormat()
+ );
+ /** @type {Array<number>} */
+ var cBias = fmtInfo.valueMin;
+ /** @type {Array<number>} */
+ var cScale = deMath.subtract(
+ fmtInfo.valueMax, fmtInfo.valueMin
+ );
+
+ // Fill first with gradient texture.
+ /** @type {Array<Array<Array<number>>>}
+ * (array of 4 component vectors)
+ */
+ var gradients = [
+ [ // negative x
+ [0.0, 0.0, 0.0, 1.0], [1.0, 1.0, 1.0, 0.0]
+ ], [ // positive x
+ [0.5, 0.0, 0.0, 1.0], [1.0, 1.0, 1.0, 0.0]
+ ], [ // negative y
+ [0.0, 0.5, 0.0, 1.0], [1.0, 1.0, 1.0, 0.0]
+ ], [ // positive y
+ [0.0, 0.0, 0.5, 1.0], [1.0, 1.0, 1.0, 0.0]
+ ], [ // negative z
+ [0.0, 0.0, 0.0, 0.5], [1.0, 1.0, 1.0, 1.0]
+ ], [ // positive z
+ [0.5, 0.5, 0.5, 1.0], [1.0, 1.0, 1.0, 0.0]
+ ]
+ ];
+ for (var face = 0;
+ face < Object.keys(tcuTexture.CubeFace).length;
+ face++) {
+ for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ this.m_textures[0].getRefTexture().allocLevel(
+ face, levelNdx
+ );
+ tcuTextureUtil.fillWithComponentGradients(
+ this.m_textures[0].getRefTexture().getLevelFace(
+ levelNdx, face
+ ),
+ deMath.add(deMath.multiply(
+ gradients[face][0], cScale
+ ), cBias),
+ deMath.add(deMath.multiply(
+ gradients[face][1], cScale
+ ), cBias)
+ );
+ }
+ }
+
+ // Fill second with grid texture.
+ for (var face = 0;
+ face < Object.keys(tcuTexture.CubeFace).length;
+ face++) {
+ for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ var step = 0x00ffffff / (
+ numLevels * Object.keys(tcuTexture.CubeFace).length
+ );
+ var rgb = step * levelNdx * face;
+ /** @type {number} */ var colorA = deMath.binaryOp(
+ 0xff000000, rgb, deMath.BinaryOp.OR
+ );
+ /** @type {number} */ var colorB = deMath.binaryOp(
+ 0xff000000, deMath.binaryNot(rgb),
+ deMath.BinaryOp.OR
+ );
+
+ this.m_textures[1].getRefTexture().allocLevel(
+ face, levelNdx
+ );
+ tcuTextureUtil.fillWithGrid(
+ this.m_textures[1].getRefTexture().getLevelFace(
+ levelNdx, face
+ ), 4, deMath.add(
+ deMath.multiply(
+ tcuRGBA.newRGBAFromValue(colorA).toVec(),
+ cScale
+ ), cBias
+ ), deMath.add(
+ deMath.multiply(
+ tcuRGBA.newRGBAFromValue(colorB).toVec(),
+ cScale
+ ), cBias
+ )
+ );
+ }
+ }
+
+ // Upload.
+ for (var i = 0; i < this.m_textures.length; i++)
+ this.m_textures[i].upload();
+
+ // Compute cases
+ /** @type {gluTexture.TextureCube} */
+ var tex0 = this.m_textures[0];
+ /** @type {gluTexture.TextureCube} */
+ var tex1 = this.m_textures.length > 1 ? this.m_textures[1] : tex0;
+
+ if (this.m_onlySampleFaceInterior) {
+ // minification
+ this.m_cases.push(new es3fTextureFilteringTests.
+ TextureCubeFilteringCase.FilterCase(
+ tex0, [-0.8, -0.8], [0.8, 0.8]
+ ));
+ // magnification
+ this.m_cases.push(new es3fTextureFilteringTests.
+ TextureCubeFilteringCase.FilterCase(
+ tex0, [0.5, 0.65], [0.8, 0.8]
+ ));
+ // minification
+ this.m_cases.push(new es3fTextureFilteringTests.
+ TextureCubeFilteringCase.FilterCase(
+ tex1, [-0.8, -0.8], [0.8, 0.8]
+ ));
+ // magnification
+ this.m_cases.push(new es3fTextureFilteringTests.
+ TextureCubeFilteringCase.FilterCase(
+ tex1, [0.2, 0.2], [0.6, 0.5]
+ ));
+ } else {
+ // minification
+ if (gl.getParameter(gl.SAMPLES) == 0)
+ this.m_cases.push(
+ new es3fTextureFilteringTests.TextureCubeFilteringCase.
+ FilterCase(
+ tex0, [-1.25, -1.2], [1.2, 1.25]
+ )
+ );
+ // minification - w/ tweak to avoid hitting triangle
+ // edges with face switchpoint.
+ else
+ this.m_cases.push(
+ new es3fTextureFilteringTests.TextureCubeFilteringCase.
+ FilterCase(
+ tex0, [-1.19, -1.3], [1.1, 1.35]
+ )
+ );
+
+ // magnification
+ this.m_cases.push(
+ new es3fTextureFilteringTests.TextureCubeFilteringCase.
+ FilterCase(
+ tex0, [0.8, 0.8], [1.25, 1.20]
+ )
+ );
+ // minification
+ this.m_cases.push(
+ new es3fTextureFilteringTests.TextureCubeFilteringCase.
+ FilterCase(
+ tex1, [-1.19, -1.3], [1.1, 1.35]
+ )
+ );
+ // magnification
+ this.m_cases.push(
+ new es3fTextureFilteringTests.TextureCubeFilteringCase.
+ FilterCase(
+ tex1, [-1.2, -1.1], [-0.8, -0.8]
+ )
+ );
+ }
+
+ this.m_caseNdx = 0;
+ }
+ catch (e) {
+ // Clean up to save memory.
+ this.deinit();
+ throw e;
+ }
+ };
+
+ /**
+ * deinit
+ */
+ es3fTextureFilteringTests.TextureCubeFilteringCase.prototype.deinit =
+ function() {
+ while (this.m_textures.length > 0) {
+ gl.deleteTexture(this.m_textures[0].getGLTexture());
+ this.m_textures.splice(0, 1);
+ }
+ };
+
+ /**
+ * @param {tcuTexture.CubeFace} face
+ * @return {string}
+ */
+ es3fTextureFilteringTests.getFaceDesc = function(face) {
+ switch (face) {
+ case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X: return '-X';
+ case tcuTexture.CubeFace.CUBEFACE_POSITIVE_X: return '+X';
+ case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Y: return '-Y';
+ case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Y: return '+Y';
+ case tcuTexture.CubeFace.CUBEFACE_NEGATIVE_Z: return '-Z';
+ case tcuTexture.CubeFace.CUBEFACE_POSITIVE_Z: return '+Z';
+ default:
+ throw new Error('Invalid cube face specified');
+ }
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fTextureFilteringTests.TextureCubeFilteringCase.prototype.iterate =
+ function() {
+ var viewportSize = 28;
+ /** @type {glsTextureTestUtil.RandomViewport} */
+ var viewport = new glsTextureTestUtil.RandomViewport(
+ gl.canvas, viewportSize,
+ viewportSize, deMath.binaryOp(
+ deString.deStringHash(this.fullName()),
+ deMath.deMathHash(this.m_caseNdx),
+ deMath.BinaryOp.XOR
+ )
+ );
+ bufferedLogToConsole('Test' + this.m_caseNdx);
+ /** @type {es3fTextureFilteringTests.
+ * TextureCubeFilteringCase.FilterCase}
+ */
+ var curCase = this.m_cases[this.m_caseNdx];
+ /** @type {tcuTexture.TextureFormat} */
+ var texFmt = curCase.texture.getRefTexture().getFormat();
+ /** @type {tcuTextureUtil.TextureFormatInfo} */
+ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
+ /** @type {glsTextureTestUtil.ReferenceParams} */
+ var sampleParams = new glsTextureTestUtil.ReferenceParams(
+ glsTextureTestUtil.textureType.TEXTURETYPE_CUBE
+ );
+
+ if (viewport.width < viewportSize || viewport.height < viewportSize)
+ throw new Error('Too small render target');
+
+ // Setup texture
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, curCase.texture.getGLTexture());
+ gl.texParameteri(
+ gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, this.m_minFilter
+ );
+ gl.texParameteri(
+ gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, this.m_magFilter
+ );
+ gl.texParameteri(
+ gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, this.m_wrapS
+ );
+ gl.texParameteri(
+ gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, this.m_wrapT
+ );
+
+ // Other state
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+
+ // Params for reference computation.
+ sampleParams.sampler = gluTextureUtil.mapGLSamplerWrapST(
+ gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE,
+ this.m_minFilter, this.m_magFilter
+ );
+ sampleParams.sampler.seamlessCubeMap = true;
+ sampleParams.samplerType = glsTextureTestUtil.getSamplerType(texFmt);
+ sampleParams.colorBias = fmtInfo.lookupBias;
+ sampleParams.colorScale = fmtInfo.lookupScale;
+ sampleParams.lodMode = glsTextureTestUtil.lodMode.EXACT;
+
+ bufferedLogToConsole(
+ 'Coordinates: ' + curCase.bottomLeft + ' -> ' + curCase.topRight
+ );
+
+ for (var faceNdx = 0;
+ faceNdx < Object.keys(tcuTexture.CubeFace).length;
+ faceNdx++) {
+ var face = /** @type {tcuTexture.CubeFace} */ (faceNdx);
+ /** @type {tcuSurface.Surface} */
+ var result = new tcuSurface.Surface(
+ viewport.width, viewport.height
+ );
+ /** @type {Array<number>} */ var texCoord;
+
+ texCoord = glsTextureTestUtil.computeQuadTexCoordCubeFace(
+ face, curCase.bottomLeft, curCase.topRight
+ );
+
+ bufferedLogToConsole(
+ 'Face ' + es3fTextureFilteringTests.getFaceDesc(face)
+ );
+
+ // \todo Log texture coordinates.
+
+ this.m_renderer.renderQuad(0, texCoord, sampleParams);
+
+ result.readViewport(
+ gl, [viewport.x, viewport.y, viewport.width, viewport.height]
+ );
+
+ /** @type {boolean} */
+ var isNearestOnly = this.m_minFilter == gl.NEAREST &&
+ this.m_magFilter == gl.NEAREST;
+ /** @type {tcuPixelFormat.PixelFormat} */
+ var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
+
+ //(iVec4)
+ var colorBits = deMath.max(
+ deMath.addScalar(
+ glsTextureTestUtil.getBitsVec(pixelFormat),
+ // 1 inaccurate bit if nearest only, 2 otherwise
+ -1 * (isNearestOnly ? 1 : 2)
+ ),
+ [0, 0, 0, 0]
+ );
+ /** @type {tcuTexLookupVerifier.LodPrecision} */
+ var lodPrecision = new tcuTexLookupVerifier.LodPrecision();
+ /** @type {tcuTexLookupVerifier.LookupPrecision} */
+ var lookupPrecision = new tcuTexLookupVerifier.LookupPrecision();
+
+ lodPrecision.derivateBits = 10;
+ lodPrecision.lodBits = 5;
+ lookupPrecision.colorThreshold = deMath.divide(
+ tcuTexLookupVerifier.computeFixedPointThreshold(colorBits),
+ sampleParams.colorScale
+ );
+ lookupPrecision.coordBits = [10, 10, 10];
+ lookupPrecision.uvwBits = [6, 6, 0];
+ lookupPrecision.colorMask =
+ glsTextureTestUtil.getCompareMask(pixelFormat);
+
+ var isHighQuality = glsTextureTestUtil.verifyTextureCubeResult(
+ result.getAccess(), curCase.texture.getRefTexture(),
+ texCoord, sampleParams, lookupPrecision, lodPrecision,
+ pixelFormat
+ );
+
+
+ if (!isHighQuality) {
+ // Evaluate against lower precision requirements.
+ lodPrecision.lodBits = 2;
+ lookupPrecision.uvwBits = [3, 3, 0];
+
+ bufferedLogToConsole('Warning: Verification against high ' +
+ 'precision requirements failed, trying with lower ' +
+ 'requirements.');
+
+ var isOk = glsTextureTestUtil.verifyTextureCubeResult(
+ result.getAccess(), curCase.texture.getRefTexture(),
+ texCoord, sampleParams, lookupPrecision, lodPrecision,
+ pixelFormat
+ );
+
+ if (!isOk) {
+ bufferedLogToConsole('ERROR: Verification against low' +
+ 'precision requirements failed, failing test case.');
+ testFailedOptions('Image verification failed', false);
+ //In JS version, one mistake and you're out
+ return tcuTestCase.IterateResult.STOP;
+ } else
+ checkMessage(
+ false,
+ 'Low-quality filtering result in iteration no. ' +
+ this.m_caseNdx
+ );
+ }
+ }
+
+ this.m_caseNdx += 1;
+ if (this.m_caseNdx < this.m_cases.length)
+ return tcuTestCase.IterateResult.CONTINUE;
+
+ testPassed('Verified');
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ // 2D array filtering
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} minFilter
+ * @param {number} magFilter
+ * @param {number} wrapS
+ * @param {number} wrapT
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} numLayers
+ */
+ es3fTextureFilteringTests.Texture2DArrayFilteringCase = function(
+ name, desc, minFilter, magFilter, wrapS, wrapT,
+ internalFormat, width, height, numLayers
+ ) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ this.m_minFilter = minFilter;
+ this.m_magFilter = magFilter;
+ this.m_wrapS = wrapS;
+ this.m_wrapT = wrapT;
+ this.m_internalFormat = internalFormat;
+ this.m_width = width;
+ this.m_height = height;
+ this.m_numLayers = numLayers;
+ this.m_gradientTex = null;
+ this.m_gridTex = null;
+ /** @type {glsTextureTestUtil.TextureRenderer} */
+ this.m_renderer = new glsTextureTestUtil.TextureRenderer(
+ es3fTextureFilteringTests.version,
+ gluShaderUtil.precision.PRECISION_HIGHP
+ );
+ this.m_textures = [];
+ this.m_caseNdx = 0;
+ this.m_cases = [];
+ };
+
+ es3fTextureFilteringTests.Texture2DArrayFilteringCase.prototype =
+ Object.create(tcuTestCase.DeqpTest.prototype);
+
+ es3fTextureFilteringTests.Texture2DArrayFilteringCase.prototype.
+ constructor = es3fTextureFilteringTests.Texture2DArrayFilteringCase;
+
+ /**
+ * @constructor
+ * @param {gluTexture.Texture2DArray} tex_
+ * @param {Array<number>} lod_
+ * @param {Array<number>} offset_
+ * @param {Array<number>} layerRange_
+ */
+ es3fTextureFilteringTests.Texture2DArrayFilteringCase.FilterCase =
+ function(
+ tex_, lod_, offset_, layerRange_
+ ) {
+ this.texture = tex_;
+ this.lod = lod_;
+ this.offset = offset_;
+ this.layerRange = layerRange_;
+ };
+
+ /*
+ * init
+ */
+ es3fTextureFilteringTests.Texture2DArrayFilteringCase.prototype.init =
+ function() {
+ try {
+ /** @type {tcuTexture.TextureFormat} */
+ var texFmt = gluTextureUtil.mapGLInternalFormat(
+ this.m_internalFormat
+ );
+ /** @type {tcuTextureUtil.TextureFormatInfo} */
+ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
+ var cScale = deMath.subtract(
+ fmtInfo.valueMax, fmtInfo.valueMin
+ );
+ var cBias = fmtInfo.valueMin;
+ var numLevels = deMath.logToFloor(
+ Math.max(this.m_width, this.m_height)
+ ) + 1;
+
+ // Create textures.
+ this.m_gradientTex = gluTexture.texture2DArrayFromInternalFormat(
+ gl,
+ this.m_internalFormat, this.m_width,
+ this.m_height, this.m_numLayers
+ );
+
+ this.m_gridTex = gluTexture.texture2DArrayFromInternalFormat(
+ gl,
+ this.m_internalFormat, this.m_width,
+ this.m_height, this.m_numLayers
+ );
+
+ var levelSwz = [
+ [0, 1, 2, 3],
+ [2, 1, 3, 0],
+ [3, 0, 1, 2],
+ [1, 3, 2, 0]
+ ];
+
+ // Fill first gradient texture
+ // (gradient direction varies between layers).
+ for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ this.m_gradientTex.getRefTexture().allocLevel(levelNdx);
+
+ var levelBuf =
+ this.m_gradientTex.getRefTexture().getLevel(levelNdx);
+
+ for (var layerNdx = 0;
+ layerNdx < this.m_numLayers;
+ layerNdx++) {
+ var swz = levelSwz[layerNdx % levelSwz.length];
+ var gMin = deMath.add(deMath.multiply(deMath.swizzle(
+ [0.0, 0.0, 0.0, 1.0], [swz[0], swz[1], swz[2], swz[3]]
+ ), cScale), cBias);
+ var gMax = deMath.add(deMath.multiply(deMath.swizzle(
+ [1.0, 1.0, 1.0, 0.0], [swz[0], swz[1], swz[2], swz[3]]
+ ), cScale), cBias);
+
+ tcuTextureUtil.fillWithComponentGradients2D(
+ tcuTextureUtil.getSubregion(
+ levelBuf, 0, 0, layerNdx, levelBuf.getWidth(),
+ levelBuf.getHeight(), 1
+ ), gMin, gMax
+ );
+ }
+ }
+
+ // Fill second with grid texture (each layer has unique colors).
+ for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ this.m_gridTex.getRefTexture().allocLevel(levelNdx);
+
+ /** @type {tcuTexture.PixelBufferAccess} */ var levelBuf =
+ this.m_gridTex.getRefTexture().getLevel(levelNdx);
+
+ for (
+ var layerNdx = 0;
+ layerNdx < this.m_numLayers;
+ layerNdx++) {
+ var step = 0x00ffffff / (numLevels * this.m_numLayers - 1);
+ var rgb = step * (levelNdx + layerNdx * numLevels);
+ /** @type {number} */ var colorA = deMath.binaryOp(
+ 0xff000000, rgb, deMath.BinaryOp.OR
+ );
+ /** @type {number} */ var colorB = deMath.binaryOp(
+ 0xff000000, deMath.binaryNot(rgb), deMath.BinaryOp.OR
+ );
+
+ tcuTextureUtil.fillWithGrid(
+ tcuTextureUtil.getSubregion(
+ levelBuf, 0, 0, layerNdx, levelBuf.getWidth(),
+ levelBuf.getHeight(), 1
+ ), 4,
+ deMath.add(
+ deMath.multiply(
+ tcuRGBA.newRGBAFromValue(colorA).toVec(),
+ cScale
+ ), cBias
+ ),
+ deMath.add(
+ deMath.multiply(
+ tcuRGBA.newRGBAFromValue(colorB).toVec(),
+ cScale
+ ), cBias
+ )
+ );
+ }
+ }
+
+ // Upload.
+ this.m_gradientTex.upload();
+ this.m_gridTex.upload();
+
+ // Test cases
+ this.m_cases.push(
+ new es3fTextureFilteringTests.
+ Texture2DArrayFilteringCase.FilterCase(
+ this.m_gradientTex, [1.5, 2.8], [-1.0, -2.7],
+ [-0.5, this.m_numLayers + 0.5]
+ )
+ );
+ this.m_cases.push(
+ new es3fTextureFilteringTests.
+ Texture2DArrayFilteringCase.FilterCase(
+ this.m_gridTex, [0.2, 0.175], [-2.0, -3.7],
+ [-0.5, this.m_numLayers + 0.5]
+ )
+ );
+ this.m_cases.push(
+ new es3fTextureFilteringTests.
+ Texture2DArrayFilteringCase.FilterCase(
+ this.m_gridTex, [-0.8, -2.3], [0.2, -0.1],
+ [this.m_numLayers + 0.5, -0.5]
+ )
+ );
+
+ // Level rounding - only in single-sample configs as
+ // multisample configs may produce smooth transition at the middle.
+ if (gl.getParameter(gl.SAMPLES) == 0)
+ this.m_cases.push(
+ new es3fTextureFilteringTests.
+ Texture2DArrayFilteringCase.FilterCase(
+ this.m_gradientTex, [-2.0, -1.5], [-0.1, 0.9],
+ [1.50001, 1.49999]
+ )
+ );
+
+ this.m_caseNdx = 0;
+ }
+ catch (e) {
+ // Clean up to save memory.
+ this.deinit();
+ throw e;
+ }
+ };
+
+ /**
+ * deinit
+ */
+ es3fTextureFilteringTests.Texture2DArrayFilteringCase.prototype.deinit =
+ function() {
+ if (this.m_gradientTex)
+ gl.deleteTexture(this.m_gradientTex.getGLTexture());
+ if (this.m_gridTex)
+ gl.deleteTexture(this.m_gridTex.getGLTexture());
+
+ this.m_gradientTex = null;
+ this.m_gridTex = null;
+ };
+
+ /**
+ * iterate
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fTextureFilteringTests.Texture2DArrayFilteringCase.prototype.iterate =
+ function() {
+ /** @type {glsTextureTestUtil.RandomViewport} */
+ var viewport = new glsTextureTestUtil.RandomViewport(
+ gl.canvas, TEX3D_VIEWPORT_WIDTH,
+ TEX3D_VIEWPORT_HEIGHT, deMath.binaryOp(
+ deString.deStringHash(this.fullName()),
+ deMath.deMathHash(this.m_caseNdx),
+ deMath.BinaryOp.XOR
+ )
+ );
+
+ /** @type {es3fTextureFilteringTests.Texture2DArrayFilteringCase.
+ * FilterCase} */ var curCase = this.m_cases[this.m_caseNdx];
+
+ /** @type {tcuTexture.TextureFormat} */
+ var texFmt = curCase.texture.getRefTexture().getFormat();
+ /** @type {tcuTextureUtil.TextureFormatInfo} */
+ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
+
+ bufferedLogToConsole('Test' + this.m_caseNdx);
+
+ /** @type {glsTextureTestUtil.ReferenceParams} */
+ var refParams = new glsTextureTestUtil.ReferenceParams(
+ glsTextureTestUtil.textureType.TEXTURETYPE_2D_ARRAY
+ );
+
+ /** @type {tcuSurface.Surface} */
+ var rendered = new tcuSurface.Surface(viewport.width, viewport.height);
+
+ if (viewport.width < TEX3D_MIN_VIEWPORT_WIDTH ||
+ viewport.height < TEX3D_MIN_VIEWPORT_HEIGHT)
+ throw new Error('Too small render target');
+
+ // Setup params for reference.
+ refParams.sampler = gluTextureUtil.mapGLSampler(
+ this.m_wrapS, this.m_wrapT, this.m_wrapT,
+ this.m_minFilter, this.m_magFilter
+ );
+ refParams.samplerType = glsTextureTestUtil.getSamplerType(texFmt);
+ refParams.lodMode = glsTextureTestUtil.lodMode.EXACT;
+ refParams.colorBias = fmtInfo.lookupBias;
+ refParams.colorScale = fmtInfo.lookupScale;
+
+ // Compute texture coordinates.
+ bufferedLogToConsole(
+ 'Approximate lod per axis = ' + curCase.lod +
+ ', offset = ' + curCase.offset
+ );
+
+ /** @type {number} */ var lodX = curCase.lod[0];
+ /** @type {number} */ var lodY = curCase.lod[1];
+ /** @type {number} */ var oX = curCase.offset[0];
+ /** @type {number} */ var oY = curCase.offset[1];
+ /** @type {number} */ var sX = Math.pow(2, lodX) * viewport.width /
+ this.m_gradientTex.getRefTexture().getWidth();
+ /** @type {number} */ var sY = Math.pow(2, lodY) * viewport.height /
+ this.m_gradientTex.getRefTexture().getHeight();
+ /** @type {number} */ var l0 = curCase.layerRange[0];
+ /** @type {number} */ var l1 = curCase.layerRange[1];
+
+ /** @type {Array<number>}*/
+ var texCoord = [
+ oX, oY, l0,
+ oX, oY + sY, l0 * 0.5 + l1 * 0.5,
+ oX + sX, oY, l0 * 0.5 + l1 * 0.5,
+ oX + sX, oY + sY, l1
+ ];
+
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, curCase.texture.getGLTexture());
+ gl.texParameteri(
+ gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, this.m_minFilter
+ );
+ gl.texParameteri(
+ gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, this.m_magFilter
+ );
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_S, this.m_wrapS);
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_T, this.m_wrapT);
+
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+ this.m_renderer.renderQuad(
+ 0, texCoord,
+ refParams
+ );
+ rendered.readViewport(
+ gl, [viewport.x, viewport.y, viewport.width, viewport.height]
+ );
+
+ /** @type {boolean} */
+ var isNearestOnly = this.m_minFilter == gl.NEAREST &&
+ this.m_magFilter == gl.NEAREST;
+ /** @type {tcuPixelFormat.PixelFormat} */
+ var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
+ //(iVec4)
+ var colorBits = deMath.max(
+ deMath.addScalar(
+ glsTextureTestUtil.getBitsVec(pixelFormat),
+ // 1 inaccurate bit if nearest only, 2 otherwise
+ -1 * (isNearestOnly ? 1 : 2)
+ ),
+ [0, 0, 0, 0]
+ );
+ /** @type {tcuTexLookupVerifier.LodPrecision} */
+ var lodPrecision = new tcuTexLookupVerifier.LodPrecision();
+ /** @type {tcuTexLookupVerifier.LookupPrecision} */
+ var lookupPrecision = new tcuTexLookupVerifier.LookupPrecision();
+
+ lodPrecision.derivateBits = 18;
+ lodPrecision.lodBits = 6;
+ lookupPrecision.colorThreshold = deMath.divide(
+ tcuTexLookupVerifier.computeFixedPointThreshold(colorBits),
+ refParams.colorScale
+ );
+ lookupPrecision.coordBits = [20, 20, 20];
+ lookupPrecision.uvwBits = [7, 7, 0];
+ lookupPrecision.colorMask =
+ glsTextureTestUtil.getCompareMask(pixelFormat);
+
+ var isHighQuality = glsTextureTestUtil.verifyTexture2DArrayResult(
+ rendered.getAccess(), curCase.texture.getRefTexture().getView(),
+ texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat);
+
+ if (!isHighQuality) {
+ // Evaluate against lower precision requirements.
+ lodPrecision.lodBits = 3;
+ lookupPrecision.uvwBits = [3, 3, 0];
+
+ bufferedLogToConsole(
+ 'Warning: Verification against high ' +
+ 'precision requirements failed, ' +
+ 'trying with lower requirements.'
+ );
+
+ var isOk = glsTextureTestUtil.verifyTexture2DArrayResult(
+ rendered.getAccess(), curCase.texture.getRefTexture().getView(),
+ texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat
+ );
+
+ if (!isOk) {
+ bufferedLogToConsole(
+ 'ERROR: Verification against low precision requirements ' +
+ 'failed, failing test case.'
+ );
+ testFailedOptions('Image verification failed', false);
+ //In JS version, one mistake and you're out
+ return tcuTestCase.IterateResult.STOP;
+ } else
+ checkMessage(
+ false,
+ 'Low-quality filtering result in iteration no. ' +
+ this.m_caseNdx
+ );
+ }
+
+ this.m_caseNdx += 1;
+ if (this.m_caseNdx < this.m_cases.length)
+ return tcuTestCase.IterateResult.CONTINUE;
+
+ testPassed('Verified');
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ // 3D filtering
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} minFilter
+ * @param {number} magFilter
+ * @param {number} wrapS
+ * @param {number} wrapT
+ * @param {number} wrapR
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} depth
+ */
+ es3fTextureFilteringTests.Texture3DFilteringCase = function(
+ name, desc, minFilter, magFilter, wrapS, wrapT, wrapR, internalFormat,
+ width, height, depth
+ ) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ this.m_minFilter = minFilter;
+ this.m_magFilter = magFilter;
+ this.m_wrapS = wrapS;
+ this.m_wrapT = wrapT;
+ this.m_wrapR = wrapR;
+ this.m_internalFormat = internalFormat;
+ this.m_width = width;
+ this.m_height = height;
+ this.m_depth = depth;
+ this.m_gradientTex = null;
+ this.m_gridTex = null;
+ /** @type {glsTextureTestUtil.TextureRenderer} */
+ this.m_renderer = new glsTextureTestUtil.TextureRenderer(
+ es3fTextureFilteringTests.version,
+ gluShaderUtil.precision.PRECISION_HIGHP
+ );
+ this.m_caseNdx = 0;
+ this.m_cases = [];
+ };
+
+ es3fTextureFilteringTests.Texture3DFilteringCase.prototype =
+ Object.create(tcuTestCase.DeqpTest.prototype);
+
+ es3fTextureFilteringTests.Texture3DFilteringCase.prototype.constructor =
+ es3fTextureFilteringTests.Texture3DFilteringCase;
+
+ /**
+ * @constructor
+ * @param {gluTexture.Texture3D} tex_
+ * @param {Array<number>} lod_
+ * @param {Array<number>} offset_
+ */
+ es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase = function(
+ tex_, lod_, offset_
+ ) {
+ this.texture = tex_;
+ this.lod = lod_;
+ this.offset = offset_;
+ };
+
+ /**
+ * init
+ */
+ es3fTextureFilteringTests.Texture3DFilteringCase.prototype.init = function(
+ ) {
+ try {
+ /** @type {tcuTexture.TextureFormat} */
+ var texFmt =
+ gluTextureUtil.mapGLInternalFormat(this.m_internalFormat);
+ /** @type {tcuTextureUtil.TextureFormatInfo} */
+ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
+ var cScale = deMath.subtract(
+ fmtInfo.valueMax, fmtInfo.valueMin
+ );
+ var cBias = fmtInfo.valueMin;
+ var numLevels = deMath.logToFloor(
+ Math.max(Math.max(this.m_width, this.m_height), this.m_depth)
+ ) + 1;
+
+ // Create textures.
+ this.m_gradientTex = gluTexture.texture3DFromInternalFormat(
+ gl, this.m_internalFormat,
+ this.m_width, this.m_height, this.m_depth
+ );
+
+ this.m_gridTex = gluTexture.texture3DFromInternalFormat(
+ gl, this.m_internalFormat,
+ this.m_width, this.m_height, this.m_depth
+ );
+
+ // Fill first gradient texture.
+ for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ var gMin = deMath.add(
+ deMath.multiply([0.0, 0.0, 0.0, 1.0], cScale), cBias
+ );
+
+ var gMax = deMath.add(
+ deMath.multiply([1.0, 1.0, 1.0, 0.0], cScale), cBias
+ );
+
+ this.m_gradientTex.getRefTexture().allocLevel(levelNdx);
+ tcuTextureUtil.fillWithComponentGradients(
+ this.m_gradientTex.getRefTexture().getLevel(levelNdx),
+ gMin, gMax
+ );
+ }
+
+ // Fill second with grid texture.
+ for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ /** @type {number} */ var step = 0x00ffffff / numLevels;
+ /** @type {number} */ var rgb = step * levelNdx;
+ /** @type {number} */ var colorA = deMath.binaryOp(
+ 0xff000000, rgb, deMath.BinaryOp.OR
+ );
+ /** @type {number} */ var colorB = deMath.binaryOp(
+ 0xff000000, deMath.binaryNot(rgb), deMath.BinaryOp.OR
+ );
+
+ this.m_gridTex.getRefTexture().allocLevel(levelNdx);
+ tcuTextureUtil.fillWithGrid(
+ this.m_gridTex.getRefTexture().getLevel(levelNdx), 4,
+ deMath.add(
+ deMath.multiply(
+ tcuRGBA.newRGBAFromValue(colorA).toVec(),
+ cScale
+ ),
+ cBias
+ ),
+ deMath.add(
+ deMath.multiply(
+ tcuRGBA.newRGBAFromValue(colorB).toVec(),
+ cScale
+ ),
+ cBias
+ )
+ );
+ }
+
+ // Upload.
+ this.m_gradientTex.upload();
+ this.m_gridTex.upload();
+
+ // Test cases
+ this.m_cases.push(
+ new es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase(
+ this.m_gradientTex, [1.5, 2.8, 1.0], [-1.0, -2.7, -2.275]
+ )
+ );
+ this.m_cases.push(
+ new es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase(
+ this.m_gradientTex, [-2.0, -1.5, -1.8], [-0.1, 0.9, -0.25]
+ )
+ );
+ this.m_cases.push(
+ new es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase(
+ this.m_gridTex, [0.2, 0.175, 0.3], [-2.0, -3.7, -1.825]
+ )
+ );
+ this.m_cases.push(
+ new es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase(
+ this.m_gridTex, [-0.8, -2.3, -2.5], [0.2, -0.1, 1.325]
+ )
+ );
+
+ this.m_caseNdx = 0;
+ }
+ catch (e) {
+ // Clean up to save memory.
+ this.deinit();
+ throw e;
+ }
+ };
+
+ /**
+ * deinit
+ */
+ es3fTextureFilteringTests.Texture3DFilteringCase.prototype.deinit =
+ function() {
+ if (this.m_gradientTex)
+ gl.deleteTexture(this.m_gradientTex.getGLTexture());
+ if (this.m_gridTex)
+ gl.deleteTexture(this.m_gridTex.getGLTexture());
+
+ this.m_gradientTex = null;
+ this.m_gridTex = null;
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fTextureFilteringTests.Texture3DFilteringCase.prototype.iterate =
+ function() {
+ /** @type {glsTextureTestUtil.RandomViewport} */
+ var viewport = new glsTextureTestUtil.RandomViewport(
+ gl.canvas, TEX3D_VIEWPORT_WIDTH,
+ TEX3D_VIEWPORT_HEIGHT, deMath.binaryOp(
+ deString.deStringHash(this.fullName()),
+ deMath.deMathHash(this.m_caseNdx),
+ deMath.BinaryOp.XOR
+ )
+ );
+
+ /** @type {es3fTextureFilteringTests.Texture3DFilteringCase.FilterCase}
+ */ var curCase = this.m_cases[this.m_caseNdx];
+
+ /** @type {tcuTexture.TextureFormat} */
+ var texFmt = curCase.texture.getRefTexture().getFormat();
+ /** @type {tcuTextureUtil.TextureFormatInfo} */
+ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
+
+ bufferedLogToConsole('Test' + this.m_caseNdx);
+ /** @type {glsTextureTestUtil.ReferenceParams} */
+ var refParams = new glsTextureTestUtil.ReferenceParams(
+ glsTextureTestUtil.textureType.TEXTURETYPE_3D
+ );
+
+ /** @type {tcuSurface.Surface} */
+ var rendered = new tcuSurface.Surface(viewport.width, viewport.height);
+ /** @type {Array<number>}*/
+ var texCoord = [];
+
+ if (viewport.width < TEX3D_MIN_VIEWPORT_WIDTH ||
+ viewport.height < TEX3D_MIN_VIEWPORT_HEIGHT)
+ throw new Error('Too small render target');
+
+ // Setup params for reference.
+ refParams.sampler = gluTextureUtil.mapGLSampler(
+ this.m_wrapS, this.m_wrapT, this.m_wrapR,
+ this.m_minFilter, this.m_magFilter
+ );
+
+ // Setup params for reference.
+ refParams.samplerType = glsTextureTestUtil.getSamplerType(texFmt);
+ refParams.lodMode = glsTextureTestUtil.lodMode.EXACT;
+ refParams.colorBias = fmtInfo.lookupBias;
+ refParams.colorScale = fmtInfo.lookupScale;
+
+ // Compute texture coordinates.
+ bufferedLogToConsole('Approximate lod per axis = ' + curCase.lod +
+ ', offset = ' + curCase.offset);
+
+ /** @type {number} */ var lodX = curCase.lod[0];
+ /** @type {number} */ var lodY = curCase.lod[1];
+ /** @type {number} */ var lodZ = curCase.lod[2];
+ /** @type {number} */ var oX = curCase.offset[0];
+ /** @type {number} */ var oY = curCase.offset[1];
+ /** @type {number} */ var oZ = curCase.offset[2];
+ /** @type {number} */ var sX = Math.pow(2, lodX) * viewport.width /
+ this.m_gradientTex.getRefTexture().getWidth();
+ /** @type {number} */ var sY = Math.pow(2, lodY) * viewport.height /
+ this.m_gradientTex.getRefTexture().getHeight();
+ /** @type {number} */ var sZ = Math.pow(2, lodZ) *
+ Math.max(viewport.width, viewport.height) /
+ this.m_gradientTex.getRefTexture().getDepth();
+
+ texCoord[0] = oX; texCoord[1] = oY; texCoord[2] = oZ;
+ texCoord[3] = oX; texCoord[4] = oY + sY; texCoord[5] = oZ + sZ * 0.5;
+ texCoord[6] = oX + sX; texCoord[7] = oY; texCoord[8] = oZ + sZ * 0.5;
+ texCoord[9] = oX + sX; texCoord[10] = oY + sY; texCoord[11] = oZ + sZ;
+
+ gl.bindTexture(gl.TEXTURE_3D, curCase.texture.getGLTexture());
+ gl.texParameteri(
+ gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, this.m_minFilter
+ );
+ gl.texParameteri(
+ gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, this.m_magFilter
+ );
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, this.m_wrapS);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, this.m_wrapT);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_R, this.m_wrapR);
+
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+ this.m_renderer.renderQuad(0, texCoord, refParams);
+ rendered.readViewport(
+ gl, [viewport.x, viewport.y, viewport.width, viewport.height]
+ );
+
+ var isNearestOnly = this.m_minFilter == gl.NEAREST &&
+ this.m_magFilter == gl.NEAREST;
+ /** @type {tcuPixelFormat.PixelFormat} */
+ var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
+ //(iVec4)
+ var colorBits = deMath.max(
+ deMath.addScalar(
+ glsTextureTestUtil.getBitsVec(pixelFormat),
+ // 1 inaccurate bit if nearest only, 2 otherwise
+ -1 * (isNearestOnly ? 1 : 2)
+ ),
+ [0, 0, 0, 0]
+ );
+ /** @type {tcuTexLookupVerifier.LodPrecision} */
+ var lodPrecision = new tcuTexLookupVerifier.LodPrecision();
+ /** @type {tcuTexLookupVerifier.LookupPrecision} */
+ var lookupPrecision = new tcuTexLookupVerifier.LookupPrecision();
+
+ lodPrecision.derivateBits = 18;
+ lodPrecision.lodBits = 6;
+ lookupPrecision.colorThreshold = deMath.divide(
+ tcuTexLookupVerifier.computeFixedPointThreshold(colorBits),
+ refParams.colorScale
+ );
+ lookupPrecision.coordBits = [20, 20, 20];
+ lookupPrecision.uvwBits = [7, 7, 7];
+ lookupPrecision.colorMask =
+ glsTextureTestUtil.getCompareMask(pixelFormat);
+
+ var isHighQuality = glsTextureTestUtil.verifyTexture3DResult(
+ rendered.getAccess(), curCase.texture.getRefTexture(),
+ texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat
+ );
+
+ if (!isHighQuality) {
+ // Evaluate against lower precision requirements.
+ lodPrecision.lodBits = 4;
+ lookupPrecision.uvwBits = [4, 4, 4];
+
+ bufferedLogToConsole(
+ 'Warning: Verification against high precision ' +
+ 'requirements failed, trying with lower requirements.'
+ );
+
+ var isOk = glsTextureTestUtil.verifyTexture3DResult(
+ rendered.getAccess(), curCase.texture.getRefTexture(),
+ texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat
+ );
+
+ if (!isOk) {
+ bufferedLogToConsole('ERROR: Verification against low ' +
+ 'precision requirements failed, failing test case.'
+ );
+ testFailedOptions('Image verification failed', false);
+ //In JS version, one mistake and you're out
+ return tcuTestCase.IterateResult.STOP;
+ } else
+ checkMessage(
+ false,
+ 'Low-quality filtering result in iteration no. ' +
+ this.m_caseNdx
+ );
+ }
+
+ this.m_caseNdx += 1;
+ if (this.m_caseNdx < this.m_cases.length)
+ return tcuTestCase.IterateResult.CONTINUE;
+
+ testPassed('Verified');
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /** @typedef {{name: string, mode: number}} */
+ es3fTextureFilteringTests.WrapMode;
+
+ /** @typedef {{name: string, mode: number}} */
+ es3fTextureFilteringTests.MinFilterMode;
+
+ /** @typedef {{name: string, mode: number}} */
+ es3fTextureFilteringTests.MagFilterModes;
+
+ /** @typedef {{width: number, height: number}} */
+ es3fTextureFilteringTests.Sizes2D;
+
+ /** @typedef {{width: number, height: number}} */
+ es3fTextureFilteringTests.SizesCube;
+
+ /** @typedef {{width: number, height: number, numLayers: number}} */
+ es3fTextureFilteringTests.Sizes2DArray;
+
+ /** @typedef {{width: number, height: number, depth: number}} */
+ es3fTextureFilteringTests.Sizes3D;
+
+ /** @typedef {{name: string, format: number}} */
+ es3fTextureFilteringTests.FilterableFormatsByType;
+
+ /**
+ * init
+ */
+ es3fTextureFilteringTests.TextureFilteringTests.prototype.init =
+ function() {
+ /** @type {Array<es3fTextureFilteringTests.WrapMode>} */
+ var wrapModes = [{
+ name: 'clamp', mode: gl.CLAMP_TO_EDGE
+ }, {
+ name: 'repeat', mode: gl.REPEAT
+ }, {
+ name: 'mirror', mode: gl.MIRRORED_REPEAT
+ }
+ ];
+
+ /** @type {Array<es3fTextureFilteringTests.MinFilterMode>} */
+ var minFilterModes = [{
+ name: 'nearest', mode: gl.NEAREST
+ }, {
+ name: 'linear', mode: gl.LINEAR
+ }, {
+ name: 'nearest_mipmap_nearest', mode: gl.NEAREST_MIPMAP_NEAREST
+ }, {
+ name: 'linear_mipmap_nearest', mode: gl.LINEAR_MIPMAP_NEAREST
+ }, {
+ name: 'nearest_mipmap_linear', mode: gl.NEAREST_MIPMAP_LINEAR
+ }, {
+ name: 'linear_mipmap_linear', mode: gl.LINEAR_MIPMAP_LINEAR
+ }
+ ];
+
+ /** @type {Array<es3fTextureFilteringTests.MagFilterModes>} */
+ var magFilterModes = [{
+ name: 'nearest', mode: gl.NEAREST
+ }, {
+ name: 'linear', mode: gl.LINEAR
+ }
+ ];
+
+ /** @type {Array<es3fTextureFilteringTests.Sizes2D>} */
+ var sizes2D = [{
+ width: 4, height: 8
+ }, {
+ width: 32, height: 64
+ }, {
+ width: 128, height: 128
+ }, {
+ width: 3, height: 7
+ }, {
+ width: 31, height: 55
+ }, {
+ width: 127, height: 99
+ }
+ ];
+
+ /** @type {Array<es3fTextureFilteringTests.SizesCube>} */
+ var sizesCube = [{
+ width: 8, height: 8
+ }, {
+ width: 64, height: 64
+ }, {
+ width: 128, height: 128
+ }, {
+ width: 7, height: 7
+ }, {
+ width: 63, height: 63
+ }
+ ];
+
+ /** @type {Array<es3fTextureFilteringTests.Sizes2DArray>} */
+ var sizes2DArray = [{
+ width: 4, height: 8, numLayers: 8
+ }, {
+ width: 32, height: 64, numLayers: 16
+ }, {
+ width: 128, height: 32, numLayers: 64
+ }, {
+ width: 3, height: 7, numLayers: 5
+ }, {
+ width: 63, height: 63, numLayers: 63
+ }
+ ];
+
+ /** @type {Array<es3fTextureFilteringTests.Sizes3D>} */
+ var sizes3D = [{
+ width: 4, height: 8, depth: 8
+ }, {
+ width: 32, height: 64, depth: 16
+ }, {
+ width: 128, height: 32, depth: 64
+ }, {
+ width: 3, height: 7, depth: 5
+ }, {
+ width: 63, height: 63, depth: 63
+ }
+ ];
+
+ /** @type {Array<es3fTextureFilteringTests.FilterableFormatsByType>} */
+ var filterableFormatsByType = [{
+ name: 'rgba16f', format: gl.RGBA16F
+ }, {
+ name: 'r11f_g11f_b10f', format: gl.R11F_G11F_B10F
+ }, {
+ name: 'rgb9_e5', format: gl.RGB9_E5
+ }, {
+ name: 'rgba8', format: gl.RGBA8
+ }, {
+ name: 'rgba8_snorm', format: gl.RGBA8_SNORM
+ }, {
+ name: 'rgb565', format: gl.RGB565
+ }, {
+ name: 'rgba4', format: gl.RGBA4
+ }, {
+ name: 'rgb5_a1', format: gl.RGB5_A1
+ }, {
+ name: 'srgb8_alpha8', format: gl.SRGB8_ALPHA8
+ }, {
+ name: 'rgb10_a2', format: gl.RGB10_A2
+ }
+ ];
+
+ // 2D texture filtering.
+
+ // Formats.
+ /** @type {tcuTestCase.DeqpTest} */
+ var formatsGroup;
+ for (var fmtNdx = 0;
+ fmtNdx < filterableFormatsByType.length;
+ fmtNdx++) {
+ formatsGroup = new tcuTestCase.DeqpTest(
+ '2d_formats', '2D Texture Formats');
+ this.addChild(formatsGroup);
+ for (var filterNdx = 0;
+ filterNdx < minFilterModes.length;
+ filterNdx++) {
+ /** @type {number} */
+ var minFilter = minFilterModes[filterNdx].mode;
+ /** @type {string} */
+ var filterName = minFilterModes[filterNdx].name;
+ /** @type {number} */
+ var format = filterableFormatsByType[fmtNdx].format;
+ /** @type {string} */
+ var formatName = filterableFormatsByType[fmtNdx].name;
+ var isMipmap = minFilter != gl.NEAREST &&
+ minFilter != gl.LINEAR;
+ /** @type {number} */
+ var magFilter = isMipmap ? gl.LINEAR : minFilter;
+ /** @type {string} */
+ var name = formatName + '_' + filterName;
+ /** @type {number} */
+ var wrapS = gl.REPEAT;
+ /** @type {number} */
+ var wrapT = gl.REPEAT;
+ /** @type {number} */ var width = 64;
+ /** @type {number} */ var height = 64;
+
+ formatsGroup.addChild(
+ new es3fTextureFilteringTests.Texture2DFilteringCase(
+ name, '', minFilter, magFilter, wrapS, wrapT,
+ format, width, height
+ )
+ );
+ }
+ }
+
+ // Sizes.
+ /** @type {tcuTestCase.DeqpTest} */
+ var sizesGroup;
+ for (var sizeNdx = 0; sizeNdx < sizes2D.length; sizeNdx++) {
+ sizesGroup = new tcuTestCase.DeqpTest(
+ '2d_sizes', '2D Texture Sizes');
+ this.addChild(sizesGroup);
+ for (var filterNdx = 0;
+ filterNdx < minFilterModes.length;
+ filterNdx++) {
+ minFilter = minFilterModes[filterNdx].mode;
+ filterName = minFilterModes[filterNdx].name;
+ format = gl.RGBA8;
+ isMipmap = minFilter != gl.NEAREST &&
+ minFilter != gl.LINEAR;
+ magFilter = isMipmap ? gl.LINEAR : minFilter;
+ wrapS = gl.REPEAT;
+ wrapT = gl.REPEAT;
+ width = sizes2D[sizeNdx].width;
+ height = sizes2D[sizeNdx].height;
+ name = '' + width + 'x' + height + '_' + filterName;
+
+ sizesGroup.addChild(
+ new es3fTextureFilteringTests.Texture2DFilteringCase(
+ name, '', minFilter, magFilter, wrapS, wrapT,
+ format, width, height
+ )
+ );
+ }
+ }
+
+ // Wrap modes.
+ /** @type {tcuTestCase.DeqpTest} */
+ var combinationsGroup;
+ for (var minFilterNdx = 0;
+ minFilterNdx < minFilterModes.length;
+ minFilterNdx++) {
+ combinationsGroup = new tcuTestCase.DeqpTest(
+ '2d_combinations', '2D Filter and wrap mode combinations');
+ this.addChild(combinationsGroup);
+ for (var magFilterNdx = 0;
+ magFilterNdx < magFilterModes.length;
+ magFilterNdx++) {
+ for (var wrapSNdx = 0;
+ wrapSNdx < wrapModes.length;
+ wrapSNdx++) {
+ for (var wrapTNdx = 0;
+ wrapTNdx < wrapModes.length;
+ wrapTNdx++) {
+ minFilter = minFilterModes[minFilterNdx].mode;
+ magFilter = magFilterModes[magFilterNdx].mode;
+ format = gl.RGBA8;
+ wrapS = wrapModes[wrapSNdx].mode;
+ wrapT = wrapModes[wrapTNdx].mode;
+ width = 63;
+ height = 57;
+ name = minFilterModes[minFilterNdx].name + '_' +
+ magFilterModes[magFilterNdx].name + '_' +
+ wrapModes[wrapSNdx].name + '_' +
+ wrapModes[wrapTNdx].name;
+
+ combinationsGroup.addChild(
+ new
+ es3fTextureFilteringTests.Texture2DFilteringCase(
+ name, '', minFilter, magFilter, wrapS, wrapT,
+ format, width, height
+ )
+ );
+ }
+ }
+ }
+ }
+
+ // Cube map texture filtering.
+
+ // Formats.
+ for (var fmtNdx = 0;
+ fmtNdx < filterableFormatsByType.length;
+ fmtNdx++) {
+ formatsGroup = new tcuTestCase.DeqpTest(
+ 'cube_formats', 'Cube Texture Formats');
+ this.addChild(formatsGroup);
+ for (var filterNdx = 0;
+ filterNdx < minFilterModes.length;
+ filterNdx++) {
+ minFilter = minFilterModes[filterNdx].mode;
+ filterName = minFilterModes[filterNdx].name;
+ format = filterableFormatsByType[fmtNdx].format;
+ formatName = filterableFormatsByType[fmtNdx].name;
+ isMipmap = minFilter != gl.NEAREST &&
+ minFilter != gl.LINEAR;
+ magFilter = isMipmap ? gl.LINEAR : minFilter;
+ name = formatName + '_' + filterName;
+ wrapS = gl.REPEAT;
+ wrapT = gl.REPEAT;
+ width = 64;
+ height = 64;
+
+ formatsGroup.addChild(
+ new es3fTextureFilteringTests.TextureCubeFilteringCase(
+ name, '', minFilter, magFilter, wrapS, wrapT,
+ false /* always sample exterior as well */,
+ format, width, height
+ )
+ );
+ }
+ }
+
+ // Sizes.
+ for (var sizeNdx = 0; sizeNdx < sizesCube.length; sizeNdx++) {
+ sizesGroup = new tcuTestCase.DeqpTest(
+ 'cube_sizes', 'Cube Texture Sizes');
+ this.addChild(sizesGroup);
+ for (var filterNdx = 0;
+ filterNdx < minFilterModes.length;
+ filterNdx++) {
+ minFilter = minFilterModes[filterNdx].mode;
+ filterName = minFilterModes[filterNdx].name;
+ var format = gl.RGBA8;
+ isMipmap = minFilter != gl.NEAREST &&
+ minFilter != gl.LINEAR;
+ magFilter = isMipmap ? gl.LINEAR : minFilter;
+ wrapS = gl.REPEAT;
+ wrapT = gl.REPEAT;
+ width = sizesCube[sizeNdx].width;
+ height = sizesCube[sizeNdx].height;
+ name = '' + width + 'x' + height + '_' + filterName;
+
+ sizesGroup.addChild(
+ new es3fTextureFilteringTests.TextureCubeFilteringCase(
+ name, '', minFilter, magFilter, wrapS, wrapT,
+ false, format, width, height
+ )
+ );
+ }
+ }
+
+ // Filter/wrap mode combinations.
+ for (var minFilterNdx = 0;
+ minFilterNdx < minFilterModes.length;
+ minFilterNdx++) {
+ combinationsGroup = new tcuTestCase.DeqpTest(
+ 'cube_combinations', 'Cube Filter and wrap mode combinations'
+ );
+ this.addChild(combinationsGroup);
+ for (var magFilterNdx = 0;
+ magFilterNdx < magFilterModes.length;
+ magFilterNdx++) {
+ for (var wrapSNdx = 0;
+ wrapSNdx < wrapModes.length;
+ wrapSNdx++) {
+ for (var wrapTNdx = 0;
+ wrapTNdx < wrapModes.length;
+ wrapTNdx++) {
+ minFilter = minFilterModes[minFilterNdx].mode;
+ magFilter = magFilterModes[magFilterNdx].mode;
+ format = gl.RGBA8;
+ wrapS = wrapModes[wrapSNdx].mode;
+ wrapT = wrapModes[wrapTNdx].mode;
+ width = 63;
+ height = 63;
+ name = minFilterModes[minFilterNdx].name + '_' +
+ magFilterModes[magFilterNdx].name + '_' +
+ wrapModes[wrapSNdx].name + '_' +
+ wrapModes[wrapTNdx].name;
+
+ combinationsGroup.addChild(
+ new es3fTextureFilteringTests.
+ TextureCubeFilteringCase(
+ name, '', minFilter, magFilter, wrapS, wrapT,
+ false, format, width, height
+ )
+ );
+ }
+ }
+ }
+ }
+
+ // Cases with no visible cube edges.
+ /** @type {tcuTestCase.DeqpTest} */
+ var onlyFaceInteriorGroup = new tcuTestCase.DeqpTest(
+ 'cube_no_edges_visible', "Don't sample anywhere near a face's edges"
+ );
+ this.addChild(onlyFaceInteriorGroup);
+
+ for (var isLinearI = 0; isLinearI <= 1; isLinearI++) {
+ var isLinear = isLinearI != 0;
+ var filter = isLinear ? gl.LINEAR : gl.NEAREST;
+
+ onlyFaceInteriorGroup.addChild(
+ new es3fTextureFilteringTests.TextureCubeFilteringCase(
+ isLinear ? 'linear' : 'nearest', '',
+ filter, filter, gl.REPEAT, gl.REPEAT,
+ true, gl.RGBA8, 63, 63
+ )
+ );
+ }
+
+ // Formats.
+ for (var fmtNdx = 0;
+ fmtNdx < filterableFormatsByType.length;
+ fmtNdx++) {
+ formatsGroup = new tcuTestCase.DeqpTest(
+ '2d_array_formats', '2D Array Texture Formats');
+ this.addChild(formatsGroup);
+ for (var filterNdx = 0;
+ filterNdx < minFilterModes.length;
+ filterNdx++) {
+ minFilter = minFilterModes[filterNdx].mode;
+ filterName = minFilterModes[filterNdx].name;
+ format = filterableFormatsByType[fmtNdx].format;
+ var formatName = filterableFormatsByType[fmtNdx].name;
+ isMipmap = minFilter != gl.NEAREST &&
+ minFilter != gl.LINEAR;
+ magFilter = isMipmap ? gl.LINEAR : minFilter;
+ name = formatName + '_' + filterName;
+ wrapS = gl.REPEAT;
+ wrapT = gl.REPEAT;
+ width = 128;
+ height = 128;
+ /** @type {number} */ var numLayers = 8;
+
+ formatsGroup.addChild(
+ new es3fTextureFilteringTests.Texture2DArrayFilteringCase(
+ name, '', minFilter, magFilter, wrapS, wrapT,
+ format, width, height, numLayers
+ )
+ );
+ }
+ }
+
+ // Sizes.
+ for (var sizeNdx = 0; sizeNdx < sizes2DArray.length; sizeNdx++) {
+ sizesGroup = new tcuTestCase.DeqpTest(
+ '2d_array_sizes', '2D Array Texture Sizes');
+ this.addChild(sizesGroup);
+ for (var filterNdx = 0;
+ filterNdx < minFilterModes.length;
+ filterNdx++) {
+ minFilter = minFilterModes[filterNdx].mode;
+ filterName = minFilterModes[filterNdx].name;
+ format = gl.RGBA8;
+ isMipmap = minFilter != gl.NEAREST &&
+ minFilter != gl.LINEAR;
+ magFilter = isMipmap ? gl.LINEAR : minFilter;
+ wrapS = gl.REPEAT;
+ wrapT = gl.REPEAT;
+ width = sizes2DArray[sizeNdx].width;
+ height = sizes2DArray[sizeNdx].height;
+ numLayers = sizes2DArray[sizeNdx].numLayers;
+ name = '' + width + 'x' + height + 'x' +
+ numLayers + '_' + filterName;
+
+ sizesGroup.addChild(
+ new es3fTextureFilteringTests.Texture2DArrayFilteringCase(
+ name, '', minFilter, magFilter, wrapS, wrapT,
+ format, width, height, numLayers
+ )
+ );
+ }
+ }
+
+ // Wrap modes.
+ for (var minFilterNdx = 0;
+ minFilterNdx < minFilterModes.length;
+ minFilterNdx++) {
+ combinationsGroup = new tcuTestCase.DeqpTest(
+ '2d_array_combinations',
+ '2D Array Filter and wrap mode combinations');
+ this.addChild(combinationsGroup);
+ for (var magFilterNdx = 0;
+ magFilterNdx < magFilterModes.length;
+ magFilterNdx++) {
+ for (var wrapSNdx = 0;
+ wrapSNdx < wrapModes.length;
+ wrapSNdx++) {
+ for (var wrapTNdx = 0;
+ wrapTNdx < wrapModes.length;
+ wrapTNdx++) {
+ minFilter = minFilterModes[minFilterNdx].mode;
+ magFilter = magFilterModes[magFilterNdx].mode;
+ format = gl.RGBA8;
+ wrapS = wrapModes[wrapSNdx].mode;
+ wrapT = wrapModes[wrapTNdx].mode;
+ width = 123;
+ height = 107;
+ numLayers = 7;
+ name = minFilterModes[minFilterNdx].name + '_' +
+ magFilterModes[magFilterNdx].name + '_' +
+ wrapModes[wrapSNdx].name + '_' +
+ wrapModes[wrapTNdx].name;
+
+ combinationsGroup.addChild(
+ new es3fTextureFilteringTests.
+ Texture2DArrayFilteringCase(
+ name, '', minFilter, magFilter,
+ wrapS, wrapT, format,
+ width, height, numLayers
+ )
+ );
+ }
+ }
+ }
+ }
+
+ // 3D texture filtering.
+
+ // Formats.
+ /** @type {number} */ var depth = 64;
+ for (var fmtNdx = 0;
+ fmtNdx < filterableFormatsByType.length;
+ fmtNdx++) {
+ formatsGroup = new tcuTestCase.DeqpTest(
+ '3d_formats', '3D Texture Formats');
+ this.addChild(formatsGroup);
+ for (var filterNdx = 0;
+ filterNdx < minFilterModes.length;
+ filterNdx++) {
+ minFilter = minFilterModes[filterNdx].mode;
+ filterName = minFilterModes[filterNdx].name;
+ format = filterableFormatsByType[fmtNdx].format;
+ formatName = filterableFormatsByType[fmtNdx].name;
+ isMipmap = minFilter != gl.NEAREST &&
+ minFilter != gl.LINEAR;
+ magFilter = isMipmap ? gl.LINEAR : minFilter;
+ name = formatName + '_' + filterName;
+ wrapS = gl.REPEAT;
+ wrapT = gl.REPEAT;
+ /** @type {number} */ var wrapR = gl.REPEAT;
+ width = 64;
+ height = 64;
+ depth = 64;
+
+ formatsGroup.addChild(
+ new es3fTextureFilteringTests.Texture3DFilteringCase(
+ name, '', minFilter, magFilter,
+ wrapS, wrapT, wrapR, format,
+ width, height, depth
+ )
+ );
+ }
+ }
+
+ // Sizes.
+ for (var sizeNdx = 0; sizeNdx < sizes3D.length; sizeNdx++) {
+ sizesGroup = new tcuTestCase.DeqpTest(
+ '3d_sizes', '3D Texture Sizes');
+ this.addChild(sizesGroup);
+ for (var filterNdx = 0;
+ filterNdx < minFilterModes.length;
+ filterNdx++) {
+ minFilter = minFilterModes[filterNdx].mode;
+ filterName = minFilterModes[filterNdx].name;
+ format = gl.RGBA8;
+ isMipmap =
+ minFilter != gl.NEAREST && minFilter != gl.LINEAR;
+ magFilter =
+ isMipmap ? gl.LINEAR : minFilter;
+ wrapS = gl.REPEAT;
+ wrapT = gl.REPEAT;
+ wrapR = gl.REPEAT;
+ width = sizes3D[sizeNdx].width;
+ height = sizes3D[sizeNdx].height;
+ depth = sizes3D[sizeNdx].depth;
+ name = '' + width + 'x' + height + 'x' + depth +
+ '_' + filterName;
+
+ sizesGroup.addChild(
+ new es3fTextureFilteringTests.Texture3DFilteringCase(
+ name, '', minFilter, magFilter,
+ wrapS, wrapT, wrapR, format,
+ width, height, depth
+ )
+ );
+ }
+ }
+
+ // Wrap modes.
+ for (var minFilterNdx = 0;
+ minFilterNdx < minFilterModes.length;
+ minFilterNdx++) {
+ for (var magFilterNdx = 0;
+ magFilterNdx < magFilterModes.length;
+ magFilterNdx++) {
+ for (var wrapSNdx = 0;
+ wrapSNdx < wrapModes.length;
+ wrapSNdx++) {
+ combinationsGroup = new tcuTestCase.DeqpTest(
+ '3d_combinations',
+ '3D Filter and wrap mode combinations');
+ this.addChild(combinationsGroup);
+ for (var wrapTNdx = 0;
+ wrapTNdx < wrapModes.length;
+ wrapTNdx++) {
+ for (var wrapRNdx = 0;
+ wrapRNdx < wrapModes.length;
+ wrapRNdx++) {
+ minFilter = minFilterModes[minFilterNdx].mode;
+ magFilter = magFilterModes[magFilterNdx].mode;
+ format = gl.RGBA8;
+ wrapS = wrapModes[wrapSNdx].mode;
+ wrapT = wrapModes[wrapTNdx].mode;
+ wrapR = wrapModes[wrapRNdx].mode;
+ width = 63;
+ height = 57;
+ depth = 67;
+ name = minFilterModes[minFilterNdx].name + '_' +
+ magFilterModes[magFilterNdx].name + '_' +
+ wrapModes[wrapSNdx].name + '_' +
+ wrapModes[wrapTNdx].name + '_' +
+ wrapModes[wrapRNdx].name;
+
+ combinationsGroup.addChild(
+ new
+ es3fTextureFilteringTests.
+ Texture3DFilteringCase(
+ name, '', minFilter, magFilter,
+ wrapS, wrapT, wrapR, format,
+ width, height, depth
+ )
+ );
+ }
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * Create and execute the test cases
+ * @param {WebGL2RenderingContext} context
+ * @param {Array<number>=} range Test range
+ */
+ es3fTextureFilteringTests.run = function(context, range) {
+ gl = context;
+
+ const canvas = gl.canvas;
+ canvas.width = canvasWH;
+ canvas.height = canvasWH;
+
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+
+ state.setRoot(new es3fTextureFilteringTests.TextureFilteringTests());
+ if (range)
+ state.setRange(range);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureFormatTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureFormatTests.js
new file mode 100644
index 0000000000..7300225a8d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureFormatTests.js
@@ -0,0 +1,1185 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+'use strict';
+goog.provide('functional.gles3.es3fTextureFormatTests');
+goog.require('framework.common.tcuCompressedTexture');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluStrUtil');
+goog.require('framework.opengl.gluTexture');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('modules.shared.glsTextureTestUtil');
+
+goog.scope(function() {
+
+var es3fTextureFormatTests = functional.gles3.es3fTextureFormatTests;
+var gluShaderUtil = framework.opengl.gluShaderUtil;
+var deRandom = framework.delibs.debase.deRandom;
+var tcuTestCase = framework.common.tcuTestCase;
+var tcuSurface = framework.common.tcuSurface;
+var gluTexture = framework.opengl.gluTexture;
+var gluTextureUtil = framework.opengl.gluTextureUtil;
+var tcuTexture = framework.common.tcuTexture;
+var glsTextureTestUtil = modules.shared.glsTextureTestUtil;
+var tcuTextureUtil = framework.common.tcuTextureUtil;
+var gluStrUtil = framework.opengl.gluStrUtil;
+var deMath = framework.delibs.debase.deMath;
+var tcuCompressedTexture = framework.common.tcuCompressedTexture;
+
+/** @type {WebGL2RenderingContext} */ var gl;
+
+var DE_ASSERT = function(x) {
+ if (!x)
+ throw new Error('Assert failed');
+};
+
+es3fTextureFormatTests.version = '300 es';
+
+es3fTextureFormatTests.testDescription = function() {
+ var test = tcuTestCase.runner.currentTest;
+ return test.description;
+};
+
+es3fTextureFormatTests.setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+es3fTextureFormatTests.Texture2DFormatCase = function(descriptor) {
+ tcuTestCase.DeqpTest.call(this, descriptor.name, descriptor.description);
+ this.m_format = descriptor.format;
+ this.m_dataType = descriptor.dataType;
+ this.m_width = descriptor.width;
+ this.m_height = descriptor.height;
+ this.m_renderer = new glsTextureTestUtil.TextureRenderer(es3fTextureFormatTests.version, gluShaderUtil.precision.PRECISION_HIGHP);
+};
+
+es3fTextureFormatTests.setParentClass(es3fTextureFormatTests.Texture2DFormatCase, tcuTestCase.DeqpTest);
+
+es3fTextureFormatTests.Texture2DFormatCase.prototype.init = function() {
+ /*tcu::TextureFormat*/ var fmt = this.m_dataType ? gluTextureUtil.mapGLTransferFormat(this.m_format, this.m_dataType) : gluTextureUtil.mapGLInternalFormat(this.m_format);
+ /*tcu::TextureFormatInfo*/ var spec = tcuTextureUtil.getTextureFormatInfo(fmt);
+ /* TODO : Port
+
+ std::ostringstream fmtName;
+
+ if (m_dataType)
+ fmtName << glu::getPixelFormatStr(m_format) << ", " << glu::getTypeStr(m_dataType);
+ else
+ fmtName << glu::getPixelFormatStr(m_format);
+
+ log << TestLog::Message << "2D texture, " << fmtName.str() << ", " << m_width << "x" << m_height
+ << ",\n fill with " << formatGradient(&spec.valueMin, &spec.valueMax) << " gradient"
+ << TestLog::EndMessage;
+ */
+
+ this.m_texture = this.m_dataType ?
+ gluTexture.texture2DFromFormat(gl, this.m_format, this.m_dataType, this.m_width, this.m_height) : // Implicit internal format.
+ gluTexture.texture2DFromInternalFormat(gl, this.m_format, this.m_width, this.m_height); // Explicit internal format.
+
+ // Fill level 0.
+ this.m_texture.getRefTexture().allocLevel(0);
+ tcuTextureUtil.fillWithComponentGradients(this.m_texture.getRefTexture().getLevel(0), spec.valueMin, spec.valueMax);
+};
+
+es3fTextureFormatTests.Texture2DFormatCase.prototype.deinit = function() {
+ /* TODO: Implement */
+};
+
+es3fTextureFormatTests.Texture2DFormatCase.prototype.iterate = function() {
+ /* TODO: Implement */
+
+ var viewport = new glsTextureTestUtil.RandomViewport(document.getElementById('canvas'), this.m_width, this.m_height/*, deStringHash(getName())*/);
+
+ /* tcu::Surface */ var renderedFrame = new tcuSurface.Surface(viewport.width, viewport.height);
+ /* tcu::Surface */ var referenceFrame = new tcuSurface.Surface(viewport.width, viewport.height);
+ /* TODO: Implement
+ // tcu::RGBA threshold = m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
+ */
+ var threshold = [3, 3, 3, 3];
+ var renderParams = new glsTextureTestUtil.ReferenceParams(glsTextureTestUtil.textureType.TEXTURETYPE_2D);
+
+ /* tcu::TextureFormatInfo*/ var spec = tcuTextureUtil.getTextureFormatInfo(this.m_texture.getRefTexture().getFormat());
+ /** @const */ var wrapS = gl.CLAMP_TO_EDGE;
+ /** @const */ var wrapT = gl.CLAMP_TO_EDGE;
+ /** @const */ var minFilter = gl.NEAREST;
+ /** @const */ var magFilter = gl.NEAREST;
+
+ renderParams.flags.log_programs = true;
+ renderParams.flags.log_uniforms = true;
+
+ renderParams.samplerType = glsTextureTestUtil.getSamplerType(this.m_texture.getRefTexture().getFormat());
+ renderParams.sampler = new tcuTexture.Sampler(tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE,
+ tcuTexture.FilterMode.NEAREST, tcuTexture.FilterMode.NEAREST);
+ renderParams.colorScale = spec.lookupScale;
+ renderParams.colorBias = spec.lookupBias;
+
+ var texCoord = glsTextureTestUtil.computeQuadTexCoord2D([0, 0], [1, 1]);
+
+ // log << TestLog::Message << "Texture parameters:"
+ // << "\n WRAP_S = " << glu::getTextureParameterValueStr(gl.TEXTURE_WRAP_S, wrapS)
+ // << "\n WRAP_T = " << glu::getTextureParameterValueStr(gl.TEXTURE_WRAP_T, wrapT)
+ // << "\n MIN_FILTER = " << glu::getTextureParameterValueStr(gl.TEXTURE_MIN_FILTER, minFilter)
+ // << "\n MAG_FILTER = " << glu::getTextureParameterValueStr(gl.TEXTURE_MAG_FILTER, magFilter)
+ // << TestLog::EndMessage;
+
+ // Setup base viewport.
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+
+ // Upload texture data to GL.
+ this.m_texture.upload();
+
+ // Bind to unit 0.
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, this.m_texture.getGLTexture());
+
+ // Setup nearest neighbor filtering and clamp-to-edge.
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
+
+ // // Draw.
+ this.m_renderer.renderQuad(0, texCoord, renderParams);
+ renderedFrame.readViewport(gl, viewport);
+
+ // // Compute reference.
+ glsTextureTestUtil.sampleTexture2D(new glsTextureTestUtil.SurfaceAccess(referenceFrame, undefined /*m_renderCtx.getRenderTarget().getPixelFormat()*/),
+ this.m_texture.getRefTexture(), texCoord, renderParams);
+
+ // Compare and log.
+ var isOk = glsTextureTestUtil.compareImages(referenceFrame, renderedFrame, threshold);
+
+ assertMsgOptions(isOk, es3fTextureFormatTests.testDescription(), true, false);
+ return tcuTestCase.IterateResult.STOP;
+};
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+es3fTextureFormatTests.TextureCubeFormatCase = function(descriptor) {
+ tcuTestCase.DeqpTest.call(this, descriptor.name, descriptor.description);
+ this.m_format = descriptor.format;
+ this.m_dataType = descriptor.dataType;
+ this.m_width = descriptor.width;
+ this.m_height = descriptor.height;
+ this.m_renderer = new glsTextureTestUtil.TextureRenderer(es3fTextureFormatTests.version, gluShaderUtil.precision.PRECISION_HIGHP);
+ DE_ASSERT(this.m_width == this.m_height);
+};
+
+es3fTextureFormatTests.setParentClass(es3fTextureFormatTests.TextureCubeFormatCase, tcuTestCase.DeqpTest);
+
+es3fTextureFormatTests.TextureCubeFormatCase.prototype.init = function() {
+ /*tcu::TextureFormat*/ var fmt = this.m_dataType ? gluTextureUtil.mapGLTransferFormat(this.m_format, this.m_dataType) : gluTextureUtil.mapGLInternalFormat(this.m_format);
+ /*tcu::TextureFormatInfo*/ var spec = tcuTextureUtil.getTextureFormatInfo(fmt);
+ /* TODO : Port
+
+ std::ostringstream fmtName;
+
+ if (m_dataType)
+ fmtName << glu::getPixelFormatStr(m_format) << ", " << glu::getTypeStr(m_dataType);
+ else
+ fmtName << glu::getPixelFormatStr(m_format);
+
+ log << TestLog::Message << "2D texture, " << fmtName.str() << ", " << m_width << "x" << m_height
+ << ",\n fill with " << formatGradient(&spec.valueMin, &spec.valueMax) << " gradient"
+ << TestLog::EndMessage;
+ */
+
+ this.m_texture = this.m_dataType ?
+ gluTexture.cubeFromFormat(gl, this.m_format, this.m_dataType, this.m_width) : // Implicit internal format.
+ gluTexture.cubeFromInternalFormat(gl, this.m_format, this.m_width); // Explicit internal format.
+
+ // Fill level 0.
+ for (var face in tcuTexture.CubeFace) {
+ var gMin = null;
+ var gMax = null;
+
+ switch (tcuTexture.CubeFace[face]) {
+ case 0: gMin = deMath.swizzle(spec.valueMin, [0, 1, 2, 3]); gMax = deMath.swizzle(spec.valueMax, [0, 1, 2, 3]); break;
+ case 1: gMin = deMath.swizzle(spec.valueMin, [2, 1, 0, 3]); gMax = deMath.swizzle(spec.valueMax, [2, 1, 0, 3]); break;
+ case 2: gMin = deMath.swizzle(spec.valueMin, [1, 2, 0, 3]); gMax = deMath.swizzle(spec.valueMax, [1, 2, 0, 3]); break;
+ case 3: gMin = deMath.swizzle(spec.valueMax, [0, 1, 2, 3]); gMax = deMath.swizzle(spec.valueMin, [0, 1, 2, 3]); break;
+ case 4: gMin = deMath.swizzle(spec.valueMax, [2, 1, 0, 3]); gMax = deMath.swizzle(spec.valueMin, [2, 1, 0, 3]); break;
+ case 5: gMin = deMath.swizzle(spec.valueMax, [1, 2, 0, 3]); gMax = deMath.swizzle(spec.valueMin, [1, 2, 0, 3]); break;
+ default:
+ DE_ASSERT(false);
+ }
+
+ this.m_texture.getRefTexture().allocLevel(tcuTexture.CubeFace[face], 0);
+ tcuTextureUtil.fillWithComponentGradients(this.m_texture.getRefTexture().getLevelFace(0, tcuTexture.CubeFace[face]), gMin, gMax);
+ }
+
+ this.m_texture.upload();
+ this.m_curFace = 0;
+ this.m_isOk = true;
+};
+
+es3fTextureFormatTests.TextureCubeFormatCase.prototype.testFace = function(face) {
+ /* TODO: Implement */
+
+ var viewport = new glsTextureTestUtil.RandomViewport(document.getElementById('canvas'), this.m_width, this.m_height/*, deStringHash(getName())*/);
+
+ /* tcu::Surface */ var renderedFrame = new tcuSurface.Surface(viewport.width, viewport.height);
+ /* tcu::Surface */ var referenceFrame = new tcuSurface.Surface(viewport.width, viewport.height);
+ /* TODO: Implement
+ // tcu::RGBA threshold = m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
+ */
+ var threshold = [3, 3, 3, 3];
+ var renderParams = new glsTextureTestUtil.ReferenceParams(glsTextureTestUtil.textureType.TEXTURETYPE_CUBE);
+
+ /* tcu::TextureFormatInfo*/ var spec = tcuTextureUtil.getTextureFormatInfo(this.m_texture.getRefTexture().getFormat());
+ /** @const */ var wrapS = gl.CLAMP_TO_EDGE;
+ /** @const */ var wrapT = gl.CLAMP_TO_EDGE;
+ /** @const */ var minFilter = gl.NEAREST;
+ /** @const */ var magFilter = gl.NEAREST;
+
+ renderParams.flags.log_programs = true;
+ renderParams.flags.log_uniforms = true;
+
+ renderParams.samplerType = glsTextureTestUtil.getSamplerType(this.m_texture.getRefTexture().getFormat());
+ renderParams.sampler = new tcuTexture.Sampler(tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE,
+ tcuTexture.FilterMode.NEAREST, tcuTexture.FilterMode.NEAREST);
+ renderParams.colorScale = spec.lookupScale;
+ renderParams.colorBias = spec.lookupBias;
+
+ // Log render info on first face.
+ if (face === tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X) {
+ renderParams.flags.log_programs = true;
+ renderParams.flags.log_uniforms = true;
+ }
+
+ var texCoord = glsTextureTestUtil.computeQuadTexCoordCube(face);
+
+ // log << TestLog::Message << "Texture parameters:"
+ // << "\n WRAP_S = " << glu::getTextureParameterValueStr(gl.TEXTURE_WRAP_S, wrapS)
+ // << "\n WRAP_T = " << glu::getTextureParameterValueStr(gl.TEXTURE_WRAP_T, wrapT)
+ // << "\n MIN_FILTER = " << glu::getTextureParameterValueStr(gl.TEXTURE_MIN_FILTER, minFilter)
+ // << "\n MAG_FILTER = " << glu::getTextureParameterValueStr(gl.TEXTURE_MAG_FILTER, magFilter)
+ // << TestLog::EndMessage;
+
+ // Setup base viewport.
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+
+ // Bind to unit 0.
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.m_texture.getGLTexture());
+
+ // Setup nearest neighbor filtering and clamp-to-edge.
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, wrapS);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, wrapT);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, minFilter);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, magFilter);
+
+ // // Draw.
+ this.m_renderer.renderQuad(0, texCoord, renderParams);
+ renderedFrame.readViewport(gl, viewport);
+
+ // // Compute reference.
+ glsTextureTestUtil.sampleTextureCube(new glsTextureTestUtil.SurfaceAccess(referenceFrame, undefined /*m_renderCtx.getRenderTarget().getPixelFormat()*/),
+ this.m_texture.getRefTexture(), texCoord, renderParams);
+
+ // Compare and log.
+ var skipPixels = null;
+ if (renderParams.samplerType == glsTextureTestUtil.samplerType.SAMPLERTYPE_INT ||
+ renderParams.samplerType == glsTextureTestUtil.samplerType.SAMPLERTYPE_UINT) {
+ // Skip top right pixel due to Mac Intel driver bug.
+ // https://github.com/KhronosGroup/WebGL/issues/1819
+ skipPixels = [
+ [this.m_width - 1, this.m_height - 1]
+ ];
+ }
+ var isOk = glsTextureTestUtil.compareImages(referenceFrame, renderedFrame, threshold, skipPixels);
+
+ assertMsgOptions(isOk, 'Face: ' + this.m_curFace + ' ' + es3fTextureFormatTests.testDescription(), true, false);
+ return isOk;
+};
+
+es3fTextureFormatTests.TextureCubeFormatCase.prototype.iterate = function() {
+ debug('Testing face ' + this.m_curFace);
+ // Execute test for all faces.
+ if (!this.testFace(this.m_curFace))
+ this.m_isOk = false;
+
+ this.m_curFace += 1;
+
+ if (this.m_curFace < Object.keys(tcuTexture.CubeFace).length)
+ return tcuTestCase.IterateResult.CONTINUE;
+ else
+ return tcuTestCase.IterateResult.STOP;
+};
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+es3fTextureFormatTests.Texture2DArrayFormatCase = function(descriptor) {
+ tcuTestCase.DeqpTest.call(this, descriptor.name, descriptor.description);
+ this.m_format = descriptor.format;
+ this.m_dataType = descriptor.dataType;
+ this.m_width = descriptor.width;
+ this.m_height = descriptor.height;
+ this.m_numLayers = descriptor.numLayers;
+ this.m_renderer = new glsTextureTestUtil.TextureRenderer(es3fTextureFormatTests.version, gluShaderUtil.precision.PRECISION_HIGHP);
+};
+
+es3fTextureFormatTests.setParentClass(es3fTextureFormatTests.Texture2DArrayFormatCase, tcuTestCase.DeqpTest);
+
+es3fTextureFormatTests.Texture2DArrayFormatCase.prototype.init = function() {
+ /*tcu::TextureFormat*/ var fmt = this.m_dataType ? gluTextureUtil.mapGLTransferFormat(this.m_format, this.m_dataType) : gluTextureUtil.mapGLInternalFormat(this.m_format);
+ /*tcu::TextureFormatInfo*/ var spec = tcuTextureUtil.getTextureFormatInfo(fmt);
+ /* TODO : Port
+
+ std::ostringstream fmtName;
+
+ if (m_dataType)
+ fmtName << glu::getPixelFormatStr(m_format) << ", " << glu::getTypeStr(m_dataType);
+ else
+ fmtName << glu::getPixelFormatStr(m_format);
+
+ log << TestLog::Message << "2D texture, " << fmtName.str() << ", " << m_width << "x" << m_height
+ << ",\n fill with " << formatGradient(&spec.valueMin, &spec.valueMax) << " gradient"
+ << TestLog::EndMessage;
+ */
+
+ this.m_texture = this.m_dataType ?
+ gluTexture.texture2DArrayFromFormat(gl, this.m_format, this.m_dataType, this.m_width, this.m_height, this.m_numLayers) : // Implicit internal format.
+ gluTexture.texture2DArrayFromInternalFormat(gl, this.m_format, this.m_width, this.m_height, this.m_numLayers); // Explicit internal format.
+
+ this.m_texture.getRefTexture().allocLevel(0);
+ tcuTextureUtil.fillWithComponentGradients(this.m_texture.getRefTexture().getLevel(0), spec.valueMin, spec.valueMax);
+
+ this.m_curLayer = 0;
+ this.m_isOk = true;
+};
+
+es3fTextureFormatTests.Texture2DArrayFormatCase.prototype.testLayer = function(layerNdx) {
+ /* TODO: Implement */
+
+ var viewport = new glsTextureTestUtil.RandomViewport(document.getElementById('canvas'), this.m_width, this.m_height/*, deStringHash(getName())*/);
+
+ /* tcu::Surface */ var renderedFrame = new tcuSurface.Surface(viewport.width, viewport.height);
+ /* tcu::Surface */ var referenceFrame = new tcuSurface.Surface(viewport.width, viewport.height);
+ /* TODO: Implement
+ // tcu::RGBA threshold = m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
+ */
+ var threshold = [3, 3, 3, 3];
+ var renderParams = new glsTextureTestUtil.ReferenceParams(glsTextureTestUtil.textureType.TEXTURETYPE_2D_ARRAY);
+
+ /* tcu::TextureFormatInfo*/ var spec = tcuTextureUtil.getTextureFormatInfo(this.m_texture.getRefTexture().getFormat());
+ /** @const */ var wrapS = gl.CLAMP_TO_EDGE;
+ /** @const */ var wrapT = gl.CLAMP_TO_EDGE;
+ /** @const */ var minFilter = gl.NEAREST;
+ /** @const */ var magFilter = gl.NEAREST;
+
+ renderParams.flags.log_programs = true;
+ renderParams.flags.log_uniforms = true;
+
+ renderParams.samplerType = glsTextureTestUtil.getSamplerType(this.m_texture.getRefTexture().getFormat());
+ renderParams.sampler = new tcuTexture.Sampler(tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE,
+ tcuTexture.FilterMode.NEAREST, tcuTexture.FilterMode.NEAREST);
+ renderParams.colorScale = spec.lookupScale;
+ renderParams.colorBias = spec.lookupBias;
+
+ var texCoord = glsTextureTestUtil.computeQuadTexCoord2DArray(layerNdx, [0, 0], [1, 1]);
+
+ // log << TestLog::Message << "Texture parameters:"
+ // << "\n WRAP_S = " << glu::getTextureParameterValueStr(gl.TEXTURE_WRAP_S, wrapS)
+ // << "\n WRAP_T = " << glu::getTextureParameterValueStr(gl.TEXTURE_WRAP_T, wrapT)
+ // << "\n MIN_FILTER = " << glu::getTextureParameterValueStr(gl.TEXTURE_MIN_FILTER, minFilter)
+ // << "\n MAG_FILTER = " << glu::getTextureParameterValueStr(gl.TEXTURE_MAG_FILTER, magFilter)
+ // << TestLog::EndMessage;
+
+ // Setup base viewport.
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+
+ this.m_texture.upload();
+
+ // Bind to unit 0.
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.m_texture.getGLTexture());
+
+ // Setup nearest neighbor filtering and clamp-to-edge.
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_S, wrapS);
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_T, wrapT);
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, minFilter);
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, magFilter);
+
+ // // Draw.
+ this.m_renderer.renderQuad(0, texCoord, renderParams);
+ renderedFrame.readViewport(gl, viewport);
+
+ // // Compute reference.
+ glsTextureTestUtil.sampleTexture2DArray(new glsTextureTestUtil.SurfaceAccess(referenceFrame, undefined /*m_renderCtx.getRenderTarget().getPixelFormat()*/),
+ this.m_texture.getRefTexture().getView(), texCoord, renderParams);
+
+ // Compare and log.
+ var isOk = glsTextureTestUtil.compareImages(referenceFrame, renderedFrame, threshold);
+
+ assertMsgOptions(isOk, 'Layer: ' + this.m_curLayer + ' ' + es3fTextureFormatTests.testDescription(), true, false);
+ return isOk;
+};
+
+es3fTextureFormatTests.Texture2DArrayFormatCase.prototype.iterate = function() {
+ debug('Testing layer ' + this.m_curLayer);
+ // Execute test for all layers.
+ if (!this.testLayer(this.m_curLayer))
+ this.m_isOk = false;
+
+ this.m_curLayer += 1;
+
+ if (this.m_curLayer == this.m_numLayers)
+ return tcuTestCase.IterateResult.STOP;
+ else
+ return tcuTestCase.IterateResult.CONTINUE;
+};
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+es3fTextureFormatTests.Texture3DFormatCase = function(descriptor) {
+ tcuTestCase.DeqpTest.call(this, descriptor.name, descriptor.description);
+ this.m_format = descriptor.format;
+ this.m_dataType = descriptor.dataType;
+ this.m_width = descriptor.width;
+ this.m_height = descriptor.height;
+ this.m_depth = descriptor.depth;
+ this.m_renderer = new glsTextureTestUtil.TextureRenderer(es3fTextureFormatTests.version, gluShaderUtil.precision.PRECISION_HIGHP);
+};
+
+es3fTextureFormatTests.setParentClass(es3fTextureFormatTests.Texture3DFormatCase, tcuTestCase.DeqpTest);
+
+es3fTextureFormatTests.Texture3DFormatCase.prototype.init = function() {
+ /*tcu::TextureFormat*/ var fmt = this.m_dataType ? gluTextureUtil.mapGLTransferFormat(this.m_format, this.m_dataType) : gluTextureUtil.mapGLInternalFormat(this.m_format);
+ /*tcu::TextureFormatInfo*/ var spec = tcuTextureUtil.getTextureFormatInfo(fmt);
+ /* TODO : Port
+
+ std::ostringstream fmtName;
+
+ if (m_dataType)
+ fmtName << glu::getPixelFormatStr(m_format) << ", " << glu::getTypeStr(m_dataType);
+ else
+ fmtName << glu::getPixelFormatStr(m_format);
+
+ log << TestLog::Message << "2D texture, " << fmtName.str() << ", " << m_width << "x" << m_height
+ << ",\n fill with " << formatGradient(&spec.valueMin, &spec.valueMax) << " gradient"
+ << TestLog::EndMessage;
+ */
+
+ this.m_texture = this.m_dataType ?
+ gluTexture.texture3DFromFormat(gl, this.m_format, this.m_dataType, this.m_width, this.m_height, this.m_depth) : // Implicit internal format.
+ gluTexture.texture3DFromInternalFormat(gl, this.m_format, this.m_width, this.m_height, this.m_depth); // Explicit internal format.
+
+ this.m_texture.getRefTexture().allocLevel(0);
+ tcuTextureUtil.fillWithComponentGradients(this.m_texture.getRefTexture().getLevel(0), spec.valueMin, spec.valueMax);
+
+ this.m_curSlice = 0;
+ this.m_isOk = true;
+};
+
+es3fTextureFormatTests.Texture3DFormatCase.prototype.testSlice = function(sliceNdx) {
+ /* TODO: Implement */
+
+ var viewport = new glsTextureTestUtil.RandomViewport(document.getElementById('canvas'), this.m_width, this.m_height/*, deStringHash(getName())*/);
+
+ /* tcu::Surface */ var renderedFrame = new tcuSurface.Surface(viewport.width, viewport.height);
+ /* tcu::Surface */ var referenceFrame = new tcuSurface.Surface(viewport.width, viewport.height);
+ /* TODO: Implement
+ // tcu::RGBA threshold = m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
+ */
+ var threshold = [3, 3, 3, 3];
+ var renderParams = new glsTextureTestUtil.ReferenceParams(glsTextureTestUtil.textureType.TEXTURETYPE_3D);
+
+ /* tcu::TextureFormatInfo*/ var spec = tcuTextureUtil.getTextureFormatInfo(this.m_texture.getRefTexture().getFormat());
+ var r = (sliceNdx + 0.5) / this.m_depth;
+ /** @const */ var wrapS = gl.CLAMP_TO_EDGE;
+ /** @const */ var wrapT = gl.CLAMP_TO_EDGE;
+ /** @const */ var minFilter = gl.NEAREST;
+ /** @const */ var magFilter = gl.NEAREST;
+
+ renderParams.flags.log_programs = true;
+ renderParams.flags.log_uniforms = true;
+
+ renderParams.samplerType = glsTextureTestUtil.getSamplerType(this.m_texture.getRefTexture().getFormat());
+ renderParams.sampler = new tcuTexture.Sampler(tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE,
+ tcuTexture.FilterMode.NEAREST, tcuTexture.FilterMode.NEAREST);
+ renderParams.colorScale = spec.lookupScale;
+ renderParams.colorBias = spec.lookupBias;
+
+ var texCoord = glsTextureTestUtil.computeQuadTexCoord3D([0, 0, r], [1, 1, r], [0, 1, 2]);
+
+ // log << TestLog::Message << "Texture parameters:"
+ // << "\n WRAP_S = " << glu::getTextureParameterValueStr(gl.TEXTURE_WRAP_S, wrapS)
+ // << "\n WRAP_T = " << glu::getTextureParameterValueStr(gl.TEXTURE_WRAP_T, wrapT)
+ // << "\n MIN_FILTER = " << glu::getTextureParameterValueStr(gl.TEXTURE_MIN_FILTER, minFilter)
+ // << "\n MAG_FILTER = " << glu::getTextureParameterValueStr(gl.TEXTURE_MAG_FILTER, magFilter)
+ // << TestLog::EndMessage;
+
+ // Setup base viewport.
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+
+ this.m_texture.upload();
+
+ // Bind to unit 0.
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_3D, this.m_texture.getGLTexture());
+
+ // Setup nearest neighbor filtering and clamp-to-edge.
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, wrapS);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, wrapT);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, minFilter);
+ gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, magFilter);
+
+ // // Draw.
+ this.m_renderer.renderQuad(0, texCoord, renderParams);
+ renderedFrame.readViewport(gl, viewport);
+
+ // // Compute reference.
+ glsTextureTestUtil.sampleTexture3D(new glsTextureTestUtil.SurfaceAccess(referenceFrame, undefined /*m_renderCtx.getRenderTarget().getPixelFormat()*/),
+ this.m_texture.getRefTexture(), texCoord, renderParams);
+
+ // Compare and log.
+ var isOk = glsTextureTestUtil.compareImages(referenceFrame, renderedFrame, threshold);
+
+ assertMsgOptions(isOk, 'Slice: ' + this.m_curSlice + ' ' + es3fTextureFormatTests.testDescription(), true, false);
+ return isOk;
+};
+
+es3fTextureFormatTests.Texture3DFormatCase.prototype.iterate = function() {
+ debug('Testing slice ' + this.m_curSlice);
+ // Execute test for all layers.
+ if (!this.testSlice(this.m_curSlice))
+ this.m_isOk = false;
+
+ this.m_curSlice += 1;
+
+ if (this.m_curSlice >= this.m_depth)
+ return tcuTestCase.IterateResult.STOP;
+ else
+ return tcuTestCase.IterateResult.CONTINUE;
+};
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+es3fTextureFormatTests.Compressed2DFormatCase = function(descriptor) {
+ tcuTestCase.DeqpTest.call(this, descriptor.name, descriptor.description);
+ this.m_format = descriptor.format;
+ this.m_dataType = descriptor.dataType;
+ this.m_width = descriptor.width;
+ this.m_height = descriptor.height;
+ this.m_renderer = new glsTextureTestUtil.TextureRenderer(es3fTextureFormatTests.version, gluShaderUtil.precision.PRECISION_HIGHP);
+};
+
+es3fTextureFormatTests.setParentClass(es3fTextureFormatTests.Compressed2DFormatCase, tcuTestCase.DeqpTest);
+
+es3fTextureFormatTests.Compressed2DFormatCase.prototype.init = function() {
+ var compressed = new tcuCompressedTexture.CompressedTexture(this.m_format, this.m_width, this.m_height);
+ var rand = new deRandom.Random(0);
+ for (var i = 0; i < compressed.m_data.length; i++) {
+ compressed.m_data[i] = rand.getInt(0, 255);
+ }
+ this.m_texture = gluTexture.compressed2DFromInternalFormat(gl, this.m_format, this.m_width, this.m_height, compressed);
+};
+
+es3fTextureFormatTests.Compressed2DFormatCase.prototype.deinit = function() {
+ /* TODO: Implement */
+};
+
+es3fTextureFormatTests.Compressed2DFormatCase.prototype.iterate = function() {
+ /* TODO: Implement */
+
+ var viewport = new glsTextureTestUtil.RandomViewport(document.getElementById('canvas'), this.m_width, this.m_height/*, deStringHash(getName())*/);
+
+ /* tcu::Surface */ var renderedFrame = new tcuSurface.Surface(viewport.width, viewport.height);
+ /* tcu::Surface */ var referenceFrame = new tcuSurface.Surface(viewport.width, viewport.height);
+ /* TODO: Implement
+ // tcu::RGBA threshold = m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
+ */
+ var threshold = [3, 3, 3, 3];
+ var renderParams = new glsTextureTestUtil.ReferenceParams(glsTextureTestUtil.textureType.TEXTURETYPE_2D);
+
+ /* tcu::TextureFormatInfo*/ var spec = tcuTextureUtil.getTextureFormatInfo(this.m_texture.getRefTexture().getFormat());
+ /** @const */ var wrapS = gl.CLAMP_TO_EDGE;
+ /** @const */ var wrapT = gl.CLAMP_TO_EDGE;
+ /** @const */ var minFilter = gl.NEAREST;
+ /** @const */ var magFilter = gl.NEAREST;
+
+ renderParams.flags.log_programs = true;
+ renderParams.flags.log_uniforms = true;
+
+ renderParams.samplerType = glsTextureTestUtil.getSamplerType(this.m_texture.getRefTexture().getFormat());
+ renderParams.sampler = new tcuTexture.Sampler(tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE,
+ tcuTexture.FilterMode.NEAREST, tcuTexture.FilterMode.NEAREST);
+ renderParams.colorScale = spec.lookupScale;
+ renderParams.colorBias = spec.lookupBias;
+
+ var texCoord = glsTextureTestUtil.computeQuadTexCoord2D([0, 0], [1, 1]);
+
+ // log << TestLog::Message << "Texture parameters:"
+ // << "\n WRAP_S = " << glu::getTextureParameterValueStr(gl.TEXTURE_WRAP_S, wrapS)
+ // << "\n WRAP_T = " << glu::getTextureParameterValueStr(gl.TEXTURE_WRAP_T, wrapT)
+ // << "\n MIN_FILTER = " << glu::getTextureParameterValueStr(gl.TEXTURE_MIN_FILTER, minFilter)
+ // << "\n MAG_FILTER = " << glu::getTextureParameterValueStr(gl.TEXTURE_MAG_FILTER, magFilter)
+ // << TestLog::EndMessage;
+
+ // Setup base viewport.
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+
+ // Bind to unit 0.
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, this.m_texture.getGLTexture());
+
+ // Setup nearest neighbor filtering and clamp-to-edge.
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
+
+ // // Draw.
+ this.m_renderer.renderQuad(0, texCoord, renderParams);
+ renderedFrame.readViewport(gl, viewport);
+
+ // // Compute reference.
+ glsTextureTestUtil.sampleTexture2D(new glsTextureTestUtil.SurfaceAccess(referenceFrame, undefined /*m_renderCtx.getRenderTarget().getPixelFormat()*/),
+ this.m_texture.getRefTexture(), texCoord, renderParams);
+
+ // Compare and log.
+ var isOk = glsTextureTestUtil.compareImages(referenceFrame, renderedFrame, threshold);
+
+ assertMsgOptions(isOk, es3fTextureFormatTests.testDescription(), true, false);
+ return tcuTestCase.IterateResult.STOP;
+};
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+es3fTextureFormatTests.CompressedCubeFormatCase = function(descriptor) {
+ tcuTestCase.DeqpTest.call(this, descriptor.name, descriptor.description);
+ this.m_format = descriptor.format;
+ this.m_dataType = descriptor.dataType;
+ this.m_width = descriptor.width;
+ this.m_height = descriptor.height;
+ this.m_renderer = new glsTextureTestUtil.TextureRenderer(es3fTextureFormatTests.version, gluShaderUtil.precision.PRECISION_HIGHP);
+ this.m_curFace = 0;
+ this.m_isOk = true;
+ DE_ASSERT(this.m_width == this.m_height);
+};
+
+es3fTextureFormatTests.setParentClass(es3fTextureFormatTests.CompressedCubeFormatCase, tcuTestCase.DeqpTest);
+
+es3fTextureFormatTests.CompressedCubeFormatCase.prototype.init = function() {
+ var compressed = new tcuCompressedTexture.CompressedTexture(this.m_format, this.m_width, this.m_height);
+ var rand = new deRandom.Random(0);
+ for (var i = 0; i < compressed.m_data.length; i++) {
+ compressed.m_data[i] = rand.getInt(0, 255);
+ }
+ this.m_texture = gluTexture.compressedCubeFromInternalFormat(gl, this.m_format, this.m_width, compressed);
+};
+
+es3fTextureFormatTests.CompressedCubeFormatCase.prototype.testFace = function(face) {
+ /* TODO: Implement */
+
+ var viewport = new glsTextureTestUtil.RandomViewport(document.getElementById('canvas'), this.m_width, this.m_height/*, deStringHash(getName())*/);
+
+ /* tcu::Surface */ var renderedFrame = new tcuSurface.Surface(viewport.width, viewport.height);
+ /* tcu::Surface */ var referenceFrame = new tcuSurface.Surface(viewport.width, viewport.height);
+ /* TODO: Implement
+ // tcu::RGBA threshold = m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
+ */
+ // Threshold high enough to cover numerical errors in software decoders on Windows and Mac. Threshold is 17 in native dEQP.
+ var threshold = [6, 6, 6, 6];
+ var renderParams = new glsTextureTestUtil.ReferenceParams(glsTextureTestUtil.textureType.TEXTURETYPE_CUBE);
+
+ /** @const */ var wrapS = gl.CLAMP_TO_EDGE;
+ /** @const */ var wrapT = gl.CLAMP_TO_EDGE;
+ /** @const */ var minFilter = gl.NEAREST;
+ /** @const */ var magFilter = gl.NEAREST;
+
+ renderParams.flags.log_programs = true;
+ renderParams.flags.log_uniforms = true;
+
+ renderParams.samplerType = glsTextureTestUtil.getSamplerType(this.m_texture.getRefTexture().getFormat());
+ renderParams.sampler = new tcuTexture.Sampler(tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE, tcuTexture.WrapMode.CLAMP_TO_EDGE,
+ tcuTexture.FilterMode.NEAREST, tcuTexture.FilterMode.NEAREST);
+
+ // Log render info on first face.
+ if (face === tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X) {
+ renderParams.flags.log_programs = true;
+ renderParams.flags.log_uniforms = true;
+ }
+
+ var texCoord = glsTextureTestUtil.computeQuadTexCoordCube(face);
+
+ // log << TestLog::Message << "Texture parameters:"
+ // << "\n WRAP_S = " << glu::getTextureParameterValueStr(gl.TEXTURE_WRAP_S, wrapS)
+ // << "\n WRAP_T = " << glu::getTextureParameterValueStr(gl.TEXTURE_WRAP_T, wrapT)
+ // << "\n MIN_FILTER = " << glu::getTextureParameterValueStr(gl.TEXTURE_MIN_FILTER, minFilter)
+ // << "\n MAG_FILTER = " << glu::getTextureParameterValueStr(gl.TEXTURE_MAG_FILTER, magFilter)
+ // << TestLog::EndMessage;
+
+ // Setup base viewport.
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+
+ // Bind to unit 0.
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.m_texture.getGLTexture());
+
+ // Setup nearest neighbor filtering and clamp-to-edge.
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, wrapS);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, wrapT);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, minFilter);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, magFilter);
+
+ // // Draw.
+ this.m_renderer.renderQuad(0, texCoord, renderParams);
+ renderedFrame.readViewport(gl, viewport);
+
+ // // Compute reference.
+ glsTextureTestUtil.sampleTextureCube(new glsTextureTestUtil.SurfaceAccess(referenceFrame, undefined /*m_renderCtx.getRenderTarget().getPixelFormat()*/),
+ this.m_texture.getRefTexture(), texCoord, renderParams);
+
+ // Compare and log.
+ var isOk = glsTextureTestUtil.compareImages(referenceFrame, renderedFrame, threshold);
+
+ assertMsgOptions(isOk, 'Face: ' + this.m_curFace + ' ' + es3fTextureFormatTests.testDescription(), true, false);
+ return isOk;
+};
+
+es3fTextureFormatTests.CompressedCubeFormatCase.prototype.iterate = function() {
+ debug('Testing face ' + this.m_curFace);
+ // Execute test for all faces.
+ if (!this.testFace(this.m_curFace))
+ this.m_isOk = false;
+
+ this.m_curFace += 1;
+
+ if (this.m_curFace < Object.keys(tcuTexture.CubeFace).length)
+ return tcuTestCase.IterateResult.CONTINUE;
+ else
+ return tcuTestCase.IterateResult.STOP;
+};
+
+es3fTextureFormatTests.genTestCases = function() {
+ var state = tcuTestCase.runner;
+ state.setRoot(tcuTestCase.newTest('texture_format', 'Top level'));
+
+ var texFormats = [
+ ['alpha', gl.ALPHA, gl.UNSIGNED_BYTE],
+ ['luminance', gl.LUMINANCE, gl.UNSIGNED_BYTE],
+ ['luminance_alpha', gl.LUMINANCE_ALPHA, gl.UNSIGNED_BYTE],
+ ['rgb_unsigned_short_5_6_5', gl.RGB, gl.UNSIGNED_SHORT_5_6_5],
+ ['rgb_unsigned_byte', gl.RGB, gl.UNSIGNED_BYTE],
+ ['rgba_unsigned_short_4_4_4_4', gl.RGBA, gl.UNSIGNED_SHORT_4_4_4_4],
+ ['rgba_unsigned_short_5_5_5_1', gl.RGBA, gl.UNSIGNED_SHORT_5_5_5_1],
+ ['rgba_unsigned_byte', gl.RGBA, gl.UNSIGNED_BYTE]
+ ];
+
+ var unsized2DGroup = tcuTestCase.newTest('unsized', 'Unsized formats (2D, Cubemap)');
+ state.testCases.addChild(unsized2DGroup);
+ var unsized2DArrayGroup = tcuTestCase.newTest('unsized', 'Unsized formats (2D Array)');
+ state.testCases.addChild(unsized2DArrayGroup);
+ var unsized3DGroup = tcuTestCase.newTest('unsized', 'Unsized formats (3D)');
+ state.testCases.addChild(unsized3DGroup);
+
+ texFormats.forEach(function(elem) {
+ var format = elem[1];
+ var dataType = elem[2];
+ var nameBase = elem[0];
+ var descriptionBase = gluStrUtil.getPixelFormatName(format) + ', ' + gluStrUtil.getTypeName(dataType);
+ unsized2DGroup.addChild(new es3fTextureFormatTests.Texture2DFormatCase({
+ name: nameBase + '_2d_pot',
+ description: descriptionBase + ' gl.TEXTURE_2D',
+ format: format,
+ dataType: dataType,
+ width: 128,
+ height: 128
+ }));
+ unsized2DGroup.addChild(new es3fTextureFormatTests.Texture2DFormatCase({
+ name: nameBase + '_2d_npot',
+ description: descriptionBase + ' gl.TEXTURE_2D',
+ format: format,
+ dataType: dataType,
+ width: 63,
+ height: 112
+ }));
+ unsized2DGroup.addChild(new es3fTextureFormatTests.TextureCubeFormatCase({
+ name: nameBase + '_cube_pot',
+ description: descriptionBase + ' gl.TEXTURE_CUBE_MAP',
+ format: format,
+ dataType: dataType,
+ width: 64,
+ height: 64
+ }));
+ unsized2DGroup.addChild(new es3fTextureFormatTests.TextureCubeFormatCase({
+ name: nameBase + '_cube_npot',
+ description: descriptionBase + ' gl.TEXTURE_CUBE_MAP',
+ format: format,
+ dataType: dataType,
+ width: 57,
+ height: 57
+ }));
+ unsized2DArrayGroup.addChild(new es3fTextureFormatTests.Texture2DArrayFormatCase({
+ name: nameBase + '_2d_array_pot',
+ description: descriptionBase + ' gl.TEXTURE_2D_ARRAY',
+ format: format,
+ dataType: dataType,
+ width: 64,
+ height: 64,
+ numLayers: 8
+ }));
+ unsized2DArrayGroup.addChild(new es3fTextureFormatTests.Texture2DArrayFormatCase({
+ name: nameBase + '_2d_array_npot',
+ description: descriptionBase + ' gl.TEXTURE_2D_ARRAY',
+ format: format,
+ dataType: dataType,
+ width: 63,
+ height: 57,
+ numLayers: 7
+ }));
+ unsized3DGroup.addChild(new es3fTextureFormatTests.Texture3DFormatCase({
+ name: nameBase + '_3d_pot',
+ description: descriptionBase + ' gl.TEXTURE_3D',
+ format: format,
+ dataType: dataType,
+ width: 8,
+ height: 32,
+ depth: 16
+ }));
+ unsized3DGroup.addChild(new es3fTextureFormatTests.Texture3DFormatCase({
+ name: nameBase + '_3d_npot',
+ description: descriptionBase + ' gl.TEXTURE_3D',
+ format: format,
+ dataType: dataType,
+ width: 11,
+ height: 31,
+ depth: 7
+ }));
+ });
+
+ var sizedColorFormats = [
+ ['rgba32f', gl.RGBA32F],
+ ['rgba32i', gl.RGBA32I],
+ ['rgba32ui', gl.RGBA32UI],
+ ['rgba16f', gl.RGBA16F],
+ ['rgba16i', gl.RGBA16I],
+ ['rgba16ui', gl.RGBA16UI],
+ ['rgba8', gl.RGBA8],
+ ['rgba8i', gl.RGBA8I],
+ ['rgba8ui', gl.RGBA8UI],
+ ['srgb8_alpha8', gl.SRGB8_ALPHA8],
+ ['rgb10_a2', gl.RGB10_A2],
+ ['rgb10_a2ui', gl.RGB10_A2UI],
+ ['rgba4', gl.RGBA4],
+ ['rgb5_a1', gl.RGB5_A1],
+ ['rgba8_snorm', gl.RGBA8_SNORM],
+ ['rgb8', gl.RGB8],
+ ['rgb565', gl.RGB565],
+ ['r11f_g11f_b10f', gl.R11F_G11F_B10F],
+ ['rgb32f', gl.RGB32F],
+ ['rgb32i', gl.RGB32I],
+ ['rgb32ui', gl.RGB32UI],
+ ['rgb16f', gl.RGB16F],
+ ['rgb16i', gl.RGB16I],
+ ['rgb16ui', gl.RGB16UI],
+ ['rgb8_snorm', gl.RGB8_SNORM],
+ ['rgb8i', gl.RGB8I],
+ ['rgb8ui', gl.RGB8UI],
+ ['srgb8', gl.SRGB8],
+ ['rgb9_e5', gl.RGB9_E5],
+ ['rg32f', gl.RG32F],
+ ['rg32i', gl.RG32I],
+ ['rg32ui', gl.RG32UI],
+ ['rg16f', gl.RG16F],
+ ['rg16i', gl.RG16I],
+ ['rg16ui', gl.RG16UI],
+ ['rg8', gl.RG8],
+ ['rg8i', gl.RG8I],
+ ['rg8ui', gl.RG8UI],
+ ['rg8_snorm', gl.RG8_SNORM],
+ ['r32f', gl.R32F],
+ ['r32i', gl.R32I],
+ ['r32ui', gl.R32UI],
+ ['r16f', gl.R16F],
+ ['r16i', gl.R16I],
+ ['r16ui', gl.R16UI],
+ ['r8', gl.R8],
+ ['r8i', gl.R8I],
+ ['r8ui', gl.R8UI],
+ ['r8_snorm', gl.R8_SNORM]
+ ];
+
+ var splitSizedColorTests = 4;
+ var sizedColor2DPOTGroup = [];
+ for (var ii = 0; ii < splitSizedColorTests; ++ii) {
+ sizedColor2DPOTGroup.push(tcuTestCase.newTest('sized', 'Sized formats (2D POT)'));
+ state.testCases.addChild(sizedColor2DPOTGroup[ii]);
+ }
+ var sizedColor2DNPOTGroup = [];
+ for (var ii = 0; ii < splitSizedColorTests; ++ii) {
+ sizedColor2DNPOTGroup.push(tcuTestCase.newTest('sized', 'Sized formats (2D NPOT)'));
+ state.testCases.addChild(sizedColor2DNPOTGroup[ii]);
+ }
+ var sizedColorCubePOTGroup = [];
+ for (var ii = 0; ii < splitSizedColorTests; ++ii) {
+ sizedColorCubePOTGroup.push(tcuTestCase.newTest('sized', 'Sized formats (Cubemap POT)'));
+ state.testCases.addChild(sizedColorCubePOTGroup[ii]);
+ }
+ var sizedColorCubeNPOTGroup = [];
+ for (var ii = 0; ii < splitSizedColorTests; ++ii) {
+ sizedColorCubeNPOTGroup.push(tcuTestCase.newTest('sized', 'Sized formats (Cubemap NPOT)'));
+ state.testCases.addChild(sizedColorCubeNPOTGroup[ii]);
+ }
+ var sizedColor2DArrayPOTGroup = [];
+ for (var ii = 0; ii < splitSizedColorTests; ++ii) {
+ sizedColor2DArrayPOTGroup.push(tcuTestCase.newTest('sized', 'Sized formats (2D Array POT)'));
+ state.testCases.addChild(sizedColor2DArrayPOTGroup[ii]);
+ }
+ var sizedColor2DArrayNPOTGroup = [];
+ for (var ii = 0; ii < splitSizedColorTests; ++ii) {
+ sizedColor2DArrayNPOTGroup.push(tcuTestCase.newTest('sized', 'Sized formats (2D Array NPOT)'));
+ state.testCases.addChild(sizedColor2DArrayNPOTGroup[ii]);
+ }
+ var sizedColor3DPOTGroup = [];
+ for (var ii = 0; ii < splitSizedColorTests; ++ii) {
+ sizedColor3DPOTGroup.push(tcuTestCase.newTest('sized', 'Sized formats (3D POT)'));
+ state.testCases.addChild(sizedColor3DPOTGroup[ii]);
+ }
+ var sizedColor3DNPOTGroup = [];
+ for (var ii = 0; ii < splitSizedColorTests; ++ii) {
+ sizedColor3DNPOTGroup.push(tcuTestCase.newTest('sized', 'Sized formats (3D NPOT)'));
+ state.testCases.addChild(sizedColor3DNPOTGroup[ii]);
+ }
+
+ for (var ii = 0; ii < sizedColorFormats.length; ++ii) {
+ var internalFormat = sizedColorFormats[ii][1];
+ var nameBase = sizedColorFormats[ii][0];
+ var descriptionBase = gluStrUtil.getPixelFormatName(internalFormat);
+ sizedColor2DPOTGroup[ii % splitSizedColorTests].addChild(new es3fTextureFormatTests.Texture2DFormatCase({
+ name: nameBase + '_pot',
+ description: descriptionBase + ' gl.TEXTURE_2D',
+ format: internalFormat,
+ width: 128,
+ height: 128
+ }));
+ sizedColor2DNPOTGroup[ii % splitSizedColorTests].addChild(new es3fTextureFormatTests.Texture2DFormatCase({
+ name: nameBase + '_npot',
+ description: descriptionBase + ' gl.TEXTURE_2D',
+ format: internalFormat,
+ width: 63,
+ height: 112
+ }));
+ sizedColorCubePOTGroup[ii % splitSizedColorTests].addChild(new es3fTextureFormatTests.TextureCubeFormatCase({
+ name: nameBase + '_pot',
+ description: descriptionBase + ' gl.TEXTURE_CUBE_MAP',
+ format: internalFormat,
+ width: 64,
+ height: 64
+ }));
+ sizedColorCubeNPOTGroup[ii % splitSizedColorTests].addChild(new es3fTextureFormatTests.TextureCubeFormatCase({
+ name: nameBase + '_npot',
+ description: descriptionBase + ' gl.TEXTURE_CUBE_MAP',
+ format: internalFormat,
+ width: 57,
+ height: 57
+ }));
+ sizedColor2DArrayPOTGroup[ii % splitSizedColorTests].addChild(new es3fTextureFormatTests.Texture2DArrayFormatCase({
+ name: nameBase + '_pot',
+ description: descriptionBase + ' gl.TEXTURE_2D_ARRAY',
+ format: internalFormat,
+ width: 64,
+ height: 64,
+ numLayers: 8
+
+ }));
+ sizedColor2DArrayNPOTGroup[ii % splitSizedColorTests].addChild(new es3fTextureFormatTests.Texture2DArrayFormatCase({
+ name: nameBase + '_npot',
+ description: descriptionBase + ' gl.TEXTURE_2D_ARRAY',
+ format: internalFormat,
+ width: 63,
+ height: 57,
+ numLayers: 7
+ }));
+ sizedColor3DPOTGroup[ii % splitSizedColorTests].addChild(new es3fTextureFormatTests.Texture3DFormatCase({
+ name: nameBase + '_pot',
+ description: descriptionBase + ' gl.TEXTURE_3D',
+ format: internalFormat,
+ width: 8,
+ height: 32,
+ depth: 16
+ }));
+ sizedColor3DNPOTGroup[ii % splitSizedColorTests].addChild(new es3fTextureFormatTests.Texture3DFormatCase({
+ name: nameBase + '_npot',
+ description: descriptionBase + ' gl.TEXTURE_3D',
+ format: internalFormat,
+ width: 11,
+ height: 31,
+ depth: 7
+ }));
+ }
+
+ var sizedDepthStencilFormats = [
+ // Depth and stencil formats
+ ['depth_component32f', gl.DEPTH_COMPONENT32F],
+ ['depth_component24', gl.DEPTH_COMPONENT24],
+ ['depth_component16', gl.DEPTH_COMPONENT16],
+ // The following format is restricted in WebGL2.
+ // ['depth32f_stencil8', gl.DEPTH32F_STENCIL8],
+ ['depth24_stencil8', gl.DEPTH24_STENCIL8]
+ ];
+ var sizedDepthStencilGroup = tcuTestCase.newTest('sized', 'Sized formats (Depth Stencil)');
+ state.testCases.addChild(sizedDepthStencilGroup);
+ sizedDepthStencilFormats.forEach(function(elem) {
+ var internalFormat = elem[1];
+ var nameBase = elem[0];
+ var descriptionBase = gluStrUtil.getPixelFormatName(internalFormat);
+ sizedDepthStencilGroup.addChild(new es3fTextureFormatTests.Texture2DFormatCase({
+ name: nameBase + '_pot',
+ description: descriptionBase + ' gl.TEXTURE_2D',
+ format: internalFormat,
+ width: 128,
+ height: 128
+ }));
+ sizedDepthStencilGroup.addChild(new es3fTextureFormatTests.Texture2DFormatCase({
+ name: nameBase + '_npot',
+ description: descriptionBase + ' gl.TEXTURE_2D',
+ format: internalFormat,
+ width: 63,
+ height: 112
+ }));
+ sizedDepthStencilGroup.addChild(new es3fTextureFormatTests.TextureCubeFormatCase({
+ name: nameBase + '_pot',
+ description: descriptionBase + ' gl.TEXTURE_CUBE_MAP',
+ format: internalFormat,
+ width: 64,
+ height: 64
+ }));
+ sizedDepthStencilGroup.addChild(new es3fTextureFormatTests.TextureCubeFormatCase({
+ name: nameBase + '_npot',
+ description: descriptionBase + ' gl.TEXTURE_CUBE_MAP',
+ format: internalFormat,
+ width: 57,
+ height: 57
+ }));
+ sizedDepthStencilGroup.addChild(new es3fTextureFormatTests.Texture2DArrayFormatCase({
+ name: nameBase + '_pot',
+ description: descriptionBase + ' gl.TEXTURE_2D_ARRAY',
+ format: internalFormat,
+ width: 64,
+ height: 64,
+ numLayers: 8
+ }));
+ sizedDepthStencilGroup.addChild(new es3fTextureFormatTests.Texture2DArrayFormatCase({
+ name: nameBase + '_npot',
+ description: descriptionBase + ' gl.TEXTURE_2D_ARRAY',
+ format: internalFormat,
+ width: 63,
+ height: 57,
+ numLayers: 7
+ }));
+ });
+
+ var compressed2DGroup = tcuTestCase.newTest('compressed', 'Compressed formats (2D)');
+ state.testCases.addChild(compressed2DGroup);
+ var compressedCubeGroup = tcuTestCase.newTest('compressed', 'Compressed formats (Cubemap)');
+ state.testCases.addChild(compressedCubeGroup);
+ var etc2Formats = [
+ ['gl.COMPRESSED_R11_EAC', 'eac_r11', tcuCompressedTexture.Format.EAC_R11],
+ ['gl.COMPRESSED_SIGNED_R11_EAC', 'eac_signed_r11', tcuCompressedTexture.Format.EAC_SIGNED_R11],
+ ['gl.COMPRESSED_RG11_EAC', 'eac_rg11', tcuCompressedTexture.Format.EAC_RG11],
+ ['gl.COMPRESSED_SIGNED_RG11_EAC', 'eac_signed_rg11', tcuCompressedTexture.Format.EAC_SIGNED_RG11],
+ ['gl.COMPRESSED_RGB8_ETC2', 'etc2_rgb8', tcuCompressedTexture.Format.ETC2_RGB8],
+ ['gl.COMPRESSED_SRGB8_ETC2', 'etc2_srgb8', tcuCompressedTexture.Format.ETC2_SRGB8],
+ ['gl.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2', 'etc2_rgb8_punchthrough_alpha1', tcuCompressedTexture.Format.ETC2_RGB8_PUNCHTHROUGH_ALPHA1],
+ ['gl.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2', 'etc2_srgb8_punchthrough_alpha1', tcuCompressedTexture.Format.ETC2_SRGB8_PUNCHTHROUGH_ALPHA1],
+ ['gl.COMPRESSED_RGBA8_ETC2_EAC', 'etc2_eac_rgba8', tcuCompressedTexture.Format.ETC2_EAC_RGBA8],
+ ['gl.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC', 'etc2_eac_srgb8_alpha8', tcuCompressedTexture.Format.ETC2_EAC_SRGB8_ALPHA8]
+ ];
+ if (!gluTextureUtil.enableCompressedTextureETC()) {
+ debug('Skipping ETC2/EAC texture format tests: no support for WEBGL_compressed_texture_etc');
+ etc2Formats = [];
+ }
+ etc2Formats.forEach(function(elem) {
+ var nameBase = elem[1];
+ var descriptionBase = elem[0];
+ var format = elem[2];
+ compressed2DGroup.addChild(new es3fTextureFormatTests.Compressed2DFormatCase({
+ name: nameBase + '_2d_pot',
+ description: descriptionBase + ', gl.TEXTURE_2D',
+ format: format,
+ width: 128,
+ height: 64
+ }));
+ compressedCubeGroup.addChild(new es3fTextureFormatTests.CompressedCubeFormatCase({
+ name: nameBase + '_cube_pot',
+ description: descriptionBase + ', gl.TEXTURE_CUBE_MAP',
+ format: format,
+ width: 64,
+ height: 64
+ }));
+ compressed2DGroup.addChild(new es3fTextureFormatTests.Compressed2DFormatCase({
+ name: nameBase + '_2d_pot',
+ description: descriptionBase + ', gl.TEXTURE_2D',
+ format: format,
+ width: 128,
+ height: 64
+ }));
+ compressedCubeGroup.addChild(new es3fTextureFormatTests.CompressedCubeFormatCase({
+ name: nameBase + '_cube_npot',
+ description: descriptionBase + ', gl.TEXTURE_CUBE_MAP',
+ format: format,
+ width: 51,
+ height: 51
+ }));
+ });
+};
+
+/**
+ * Create and execute the test cases
+ */
+es3fTextureFormatTests.run = function(context, range) {
+ gl = context;
+ var state = tcuTestCase.runner;
+ try {
+ es3fTextureFormatTests.genTestCases();
+ if (range)
+ state.setRange(range);
+ state.runCallback(tcuTestCase.runTestCases);
+ } catch (err) {
+ bufferedLogToConsole(err);
+ state.terminate();
+ }
+
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureShadowTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureShadowTests.js
new file mode 100644
index 0000000000..c878228b23
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureShadowTests.js
@@ -0,0 +1,898 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+'use strict';
+goog.provide('functional.gles3.es3fTextureShadowTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuLogImage');
+goog.require('framework.common.tcuPixelFormat');
+goog.require('framework.common.tcuRGBA');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexCompareVerifier');
+goog.require('framework.common.tcuTexLookupVerifier');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.delibs.debase.deUtil');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTexture');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('framework.referencerenderer.rrMultisamplePixelBufferAccess');
+goog.require('modules.shared.glsTextureTestUtil');
+
+goog.scope(function() {
+
+var es3fTextureShadowTests = functional.gles3.es3fTextureShadowTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var glsTextureTestUtil = modules.shared.glsTextureTestUtil;
+var gluShaderUtil = framework.opengl.gluShaderUtil;
+var gluTexture = framework.opengl.gluTexture;
+var gluTextureUtil = framework.opengl.gluTextureUtil;
+var tcuTexture = framework.common.tcuTexture;
+var tcuImageCompare = framework.common.tcuImageCompare;
+var tcuLogImage = framework.common.tcuLogImage;
+var tcuTextureUtil = framework.common.tcuTextureUtil;
+var tcuRGBA = framework.common.tcuRGBA;
+var deMath = framework.delibs.debase.deMath;
+var tcuPixelFormat = framework.common.tcuPixelFormat;
+var tcuSurface = framework.common.tcuSurface;
+var tcuTexCompareVerifier = framework.common.tcuTexCompareVerifier;
+var tcuTexLookupVerifier = framework.common.tcuTexLookupVerifier;
+var rrMultisamplePixelBufferAccess = framework.referencerenderer.rrMultisamplePixelBufferAccess;
+var deString = framework.delibs.debase.deString;
+var deUtil = framework.delibs.debase.deUtil;
+
+ es3fTextureShadowTests.version = '300 es';
+
+ /** @const */ var VIEWPORT_WIDTH = 64;
+ /** @const */ var VIEWPORT_HEIGHT = 64;
+ /** @const */ var MIN_VIEWPORT_WIDTH = 64;
+ /** @const */ var MIN_VIEWPORT_HEIGHT = 64;
+
+ var DE_ASSERT = function(x) {
+ if (!x)
+ throw new Error('Assert failed');
+ };
+
+ /**
+ * @param {tcuTexture.TextureFormat} format
+ * @return {boolean}
+ */
+ es3fTextureShadowTests.isFloatingPointDepthFormat = function(format) {
+ // Only two depth and depth-stencil formats are floating point
+ return (format.order == tcuTexture.ChannelOrder.D && format.type == tcuTexture.ChannelType.FLOAT) || (format.order == tcuTexture.ChannelOrder.DS && format.type == tcuTexture.ChannelType.FLOAT_UNSIGNED_INT_24_8_REV);
+ };
+
+ /**
+ * @param {tcuTexture.PixelBufferAccess} access
+ */
+ es3fTextureShadowTests.clampFloatingPointTexture = function(access) {
+ DE_ASSERT(es3fTextureShadowTests.isFloatingPointDepthFormat(access.getFormat()));
+ for (var z = 0; z < access.getDepth(); ++z)
+ for (var y = 0; y < access.getHeight(); ++y)
+ for (var x = 0; x < access.getWidth(); ++x)
+ access.setPixDepth(deMath.clamp(access.getPixDepth(x, y, z), 0.0, 1.0), x, y, z);
+ };
+
+ /**
+ * @param {tcuTexture.Texture2D|tcuTexture.Texture2DArray} target
+ */
+ es3fTextureShadowTests.clampFloatingPointTexture2D = function(target) {
+ for (var level = 0; level < target.getNumLevels(); ++level)
+ if (!target.isLevelEmpty(level))
+ es3fTextureShadowTests.clampFloatingPointTexture(target.getLevel(level));
+ };
+
+ /**
+ * @param {tcuTexture.TextureCube} target
+ */
+ es3fTextureShadowTests.clampFloatingPointTextureCube = function(target) {
+ for (var level = 0; level < target.getNumLevels(); ++level)
+ for (var face = tcuTexture.CubeFace.CUBEFACE_NEGATIVE_X; face < Object.keys(tcuTexture.CubeFace).length; face++)
+ es3fTextureShadowTests.clampFloatingPointTexture(target.getLevelFace(level, face));
+ };
+
+ /**
+ * @param {?} textureType
+ * @param {tcuTexture.ConstPixelBufferAccess} result
+ * @param {tcuTexture.Texture2D|tcuTexture.Texture2DArray|tcuTexture.TextureCube} src
+ * @param {Array<number>} texCoord
+ * @param {glsTextureTestUtil.ReferenceParams} sampleParams
+ * @param {tcuTexCompareVerifier.TexComparePrecision} comparePrec
+ * @param {tcuTexLookupVerifier.LodPrecision} lodPrecision
+ * @param {tcuPixelFormat.PixelFormat} pixelFormat
+ */
+ es3fTextureShadowTests.verifyTexCompareResult = function(textureType, result, src, texCoord, sampleParams, comparePrec, lodPrecision, pixelFormat) {
+ var reference = new tcuSurface.Surface(result.getWidth(), result.getHeight());
+ var errorMask = new tcuSurface.Surface(result.getWidth(), result.getHeight());
+ var nonShadowThreshold = deMath.swizzle(tcuTexLookupVerifier.computeFixedPointThreshold(deMath.subtract(glsTextureTestUtil.getBitsVec(pixelFormat), [1, 1, 1, 1])), [1, 2, 3]);
+ var numFailedPixels;
+
+ if (es3fTextureShadowTests.isFloatingPointDepthFormat(src.getFormat())) {
+ var clampedSource = /*deUtil.clone(*/src/*)*/;
+
+ if (textureType == tcuTexture.Texture2D) {
+ es3fTextureShadowTests.clampFloatingPointTexture2D(/** @type {tcuTexture.Texture2D} */(clampedSource));
+ glsTextureTestUtil.sampleTexture2D(new glsTextureTestUtil.SurfaceAccess(reference, pixelFormat), /** @type {tcuTexture.Texture2DView} */ (clampedSource.getView()), texCoord, sampleParams);
+ // sample clamped values
+ numFailedPixels = glsTextureTestUtil.computeTextureCompareDiff2D(result, reference.getAccess(), errorMask.getAccess(), /** @type {tcuTexture.Texture2DView} */ (clampedSource.getView()), texCoord, sampleParams, comparePrec, lodPrecision, nonShadowThreshold);
+ } else if (textureType == tcuTexture.Texture2DArray) {
+ es3fTextureShadowTests.clampFloatingPointTexture2D(/** @type {tcuTexture.Texture2DArray} */(clampedSource));
+ glsTextureTestUtil.sampleTexture2DArray(new glsTextureTestUtil.SurfaceAccess(reference, pixelFormat), /** @type {tcuTexture.Texture2DArrayView} */ (clampedSource.getView()), texCoord, sampleParams);
+ // sample clamped values
+ numFailedPixels = glsTextureTestUtil.computeTextureCompareDiff2DArray(result, reference.getAccess(), errorMask.getAccess(), /** @type {tcuTexture.Texture2DArrayView} */ (clampedSource.getView()), texCoord, sampleParams, comparePrec, lodPrecision, nonShadowThreshold);
+ } else if (textureType == tcuTexture.TextureCube) {
+ es3fTextureShadowTests.clampFloatingPointTextureCube(/** @type {tcuTexture.TextureCube} */(clampedSource));
+ glsTextureTestUtil.sampleTextureCube(new glsTextureTestUtil.SurfaceAccess(reference, pixelFormat), /** @type {tcuTexture.TextureCubeView} */ (clampedSource.getView()), texCoord, sampleParams);
+ // sample clamped values
+ numFailedPixels = glsTextureTestUtil.computeTextureCompareDiffCube(result, reference.getAccess(), errorMask.getAccess(), /** @type {tcuTexture.TextureCubeView} */ (clampedSource.getView()), texCoord, sampleParams, comparePrec, lodPrecision, nonShadowThreshold);
+ } else
+ throw new Error('Invalid texture type');
+
+ } else {
+ if (textureType == tcuTexture.Texture2D) {
+ glsTextureTestUtil.sampleTexture2D(new glsTextureTestUtil.SurfaceAccess(reference, pixelFormat), /** @type {tcuTexture.Texture2DView} */ (src.getView()), texCoord, sampleParams);
+ // sample raw values (they are guaranteed to be in [0, 1] range as the format cannot represent any other values)
+ numFailedPixels = glsTextureTestUtil.computeTextureCompareDiff2D(result, reference.getAccess(), errorMask.getAccess(), /** @type {tcuTexture.Texture2DView} */ (src.getView()), texCoord, sampleParams, comparePrec, lodPrecision, nonShadowThreshold);
+ } else if (textureType == tcuTexture.Texture2DArray) {
+ glsTextureTestUtil.sampleTexture2DArray(new glsTextureTestUtil.SurfaceAccess(reference, pixelFormat), /** @type {tcuTexture.Texture2DArrayView} */ (src.getView()), texCoord, sampleParams);
+ // sample raw values (they are guaranteed to be in [0, 1] range as the format cannot represent any other values)
+ numFailedPixels = glsTextureTestUtil.computeTextureCompareDiff2DArray(result, reference.getAccess(), errorMask.getAccess(), /** @type {tcuTexture.Texture2DArrayView} */ (src.getView()), texCoord, sampleParams, comparePrec, lodPrecision, nonShadowThreshold);
+ } else if (textureType == tcuTexture.TextureCube) {
+ glsTextureTestUtil.sampleTextureCube(new glsTextureTestUtil.SurfaceAccess(reference, pixelFormat), /** @type {tcuTexture.TextureCubeView} */ (src.getView()), texCoord, sampleParams);
+ // sample raw values (they are guaranteed to be in [0, 1] range as the format cannot represent any other values)
+ numFailedPixels = glsTextureTestUtil.computeTextureCompareDiffCube(result, reference.getAccess(), errorMask.getAccess(), /** @type {tcuTexture.TextureCubeView} */ (src.getView()), texCoord, sampleParams, comparePrec, lodPrecision, nonShadowThreshold);
+ } else
+ throw new Error('Invalid texture type');
+ }
+
+ if (numFailedPixels > 0)
+ bufferedLogToConsole('ERROR: Result verification failed, got ' + numFailedPixels + ' invalid pixels!');
+
+ if (numFailedPixels > 0)
+ tcuImageCompare.displayImages(result, reference.getAccess(), errorMask.getAccess());
+ else
+ tcuLogImage.logImageWithInfo(result, 'Result');
+
+ return numFailedPixels == 0;
+
+ };
+
+ /**
+ * @constructor
+ * @param {string} name
+ * @param {number} format
+ * @struct
+ */
+ es3fTextureShadowTests.Format = function(name, format) {
+ /** @type {string} */ this.name = name;
+ /** @type {number} */ this.format = format;
+ };
+
+ /**
+ * @constructor
+ * @param {string} name
+ * @param {number} minFilter
+ * @param {number} magFilter
+ * @struct
+ */
+ es3fTextureShadowTests.Filter = function(name, minFilter, magFilter) {
+ /** @type {string} */ this.name = name;
+ /** @type {number} */ this.minFilter = minFilter;
+ /** @type {number} */ this.magFilter = magFilter;
+ };
+
+ /**
+ * @constructor
+ * @param {string} name
+ * @param {number} func
+ * @struct
+ */
+ es3fTextureShadowTests.CompareFunc = function(name, func) {
+ /** @type {string} */ this.name = name;
+ /** @type {number} */ this.func = func;
+ };
+
+ /**
+ * @constructor
+ * @param {number} texNdx
+ * @param {number} ref
+ * @param {number} lodX
+ * @param {number} lodY
+ * @param {number} oX
+ * @param {number} oY
+ * @struct
+ */
+ es3fTextureShadowTests.TestCase = function(texNdx, ref, lodX, lodY, oX, oY) {
+ /** @type {number} */ this.texNdx = texNdx;
+ /** @type {number} */ this.ref = ref;
+ /** @type {number} */ this.lodX = lodX;
+ /** @type {number} */ this.lodY = lodY;
+ /** @type {number} */ this.oX = oX
+ /** @type {number} */ this.oY = oY;
+ };
+
+ /**
+ * @constructor
+ * @param {?gluTexture.Texture2D|?gluTexture.TextureCube|?gluTexture.Texture2DArray} tex
+ * @param {number} ref
+ * @param {Array<number>} minCoord
+ * @param {Array<number>} maxCoord
+ * @struct
+ */
+ es3fTextureShadowTests.FilterCase = function(tex, ref, minCoord, maxCoord) {
+ /** @type {?gluTexture.Texture2D|?gluTexture.TextureCube|?gluTexture.Texture2DArray} */ this.texture = tex;
+ /** @type {Array<number>} */ this.minCoord = minCoord;
+ /** @type {Array<number>} */ this.maxCoord = maxCoord;
+ /** @type {number} */ this.ref = ref;
+ };
+
+ /**
+ * @constructor
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} minFilter
+ * @param {number} magFilter
+ * @param {number} wrapS
+ * @param {number} wrapT
+ * @param {number} format
+ * @param {number} width
+ * @param {number} height
+ * @param {number} compareFunc
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fTextureShadowTests.Texture2DShadowCase = function(name, desc, minFilter, magFilter, wrapS, wrapT, format, width, height, compareFunc) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ this.m_minFilter = minFilter;
+ this.m_magFilter = magFilter;
+ this.m_wrapS = wrapS;
+ this.m_wrapT = wrapT;
+ this.m_format = format;
+ this.m_width = width;
+ this.m_height = height;
+ this.m_compareFunc = compareFunc;
+ this.m_renderer = new glsTextureTestUtil.TextureRenderer(es3fTextureShadowTests.version, gluShaderUtil.precision.PRECISION_HIGHP);
+ this.m_caseNdx = 0;
+ this.m_cases = [];
+ };
+
+ es3fTextureShadowTests.Texture2DShadowCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fTextureShadowTests.Texture2DShadowCase.prototype.constructor = es3fTextureShadowTests.Texture2DShadowCase;
+
+ es3fTextureShadowTests.Texture2DShadowCase.prototype.init = function() {
+
+ // Create 2 textures.
+ this.m_textures = [];
+ this.m_textures[0] = gluTexture.texture2DFromInternalFormat(gl, this.m_format, this.m_width, this.m_height);
+ this.m_textures[1] = gluTexture.texture2DFromInternalFormat(gl, this.m_format, this.m_width, this.m_height);
+
+ var numLevels = this.m_textures[0].getRefTexture().getNumLevels();
+
+ for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ this.m_textures[0].getRefTexture().allocLevel(levelNdx);
+ tcuTextureUtil.fillWithComponentGradients(this.m_textures[0].getRefTexture().getLevel(levelNdx), [-0.5, -0.5, -0.5, 2.0], [1, 1, 1, 0]);
+ }
+
+ for (levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ var step = 0x00ffffff / numLevels;
+ var rgb = step * levelNdx;
+ var colorA = 0xff000000 | rgb;
+ var colorB = 0xff000000 | ~rgb;
+
+ this.m_textures[1].getRefTexture().allocLevel(levelNdx);
+ tcuTextureUtil.fillWithGrid(this.m_textures[1].getRefTexture().getLevel(levelNdx), 4, tcuRGBA.newRGBAFromValue(colorA).toVec(), tcuRGBA.newRGBAFromValue(colorB).toVec());
+ }
+
+ for (var i = 0; i < this.m_textures.length; i++)
+ this.m_textures[i].upload();
+
+ var refInRangeUpper = (this.m_compareFunc == gl.EQUAL || this.m_compareFunc == gl.NOTEQUAL) ? 1.0 : 0.5;
+ var refInRangeLower = (this.m_compareFunc == gl.EQUAL || this.m_compareFunc == gl.NOTEQUAL) ? 0.0 : 0.5;
+
+ var refOutOfBoundsUpper = 1.1;
+ var refOutOfBoundsLower = -0.1;
+
+ numLevels = this.m_textures[0].getRefTexture().getNumLevels();
+
+ var cases = [];
+ cases.push(new es3fTextureShadowTests.TestCase(0, refInRangeUpper, 1.6, 2.9, -1.0, -2.7));
+ cases.push(new es3fTextureShadowTests.TestCase(0, refInRangeLower, -2.0, -1.35, -0.2, 0.7));
+ cases.push(new es3fTextureShadowTests.TestCase(1, refInRangeUpper, 0.14, 0.275, -1.5, -1.1));
+ cases.push(new es3fTextureShadowTests.TestCase(1, refInRangeLower, -0.92, -2.64, 0.4, -0.1));
+ cases.push(new es3fTextureShadowTests.TestCase(1, refOutOfBoundsUpper, -0.39, -0.52, 0.65, 0.87));
+ cases.push(new es3fTextureShadowTests.TestCase(1, refOutOfBoundsLower, -1.55, 0.65, 0.35, 0.91));
+
+ var viewportW = Math.min(VIEWPORT_WIDTH, gl.canvas.width);
+ var viewportH = Math.min(VIEWPORT_HEIGHT, gl.canvas.height);
+
+ for (var caseNdx = 0; caseNdx < cases.length; caseNdx++) {
+ var texNdx = deMath.clamp(cases[caseNdx].texNdx, 0, this.m_textures.length - 1);
+ var ref = cases[caseNdx].ref;
+ var lodX = cases[caseNdx].lodX;
+ var lodY = cases[caseNdx].lodY;
+ var oX = cases[caseNdx].oX;
+ var oY = cases[caseNdx].oY;
+ var sX = Math.exp(lodX * Math.log(2)) * viewportW / this.m_textures[texNdx].getRefTexture().getWidth();
+ var sY = Math.exp(lodY * Math.log(2)) * viewportH / this.m_textures[texNdx].getRefTexture().getHeight();
+
+ this.m_cases.push(new es3fTextureShadowTests.FilterCase(this.m_textures[texNdx], ref, [oX, oY], [oX + sX, oY + sY]));
+ }
+
+ this.m_caseNdx = 0;
+ };
+
+ es3fTextureShadowTests.Texture2DShadowCase.prototype.iterate = function() {
+
+ var viewport = new glsTextureTestUtil.RandomViewport(document.getElementById('canvas'), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
+ var curCase = this.m_cases[this.m_caseNdx];
+ var sampleParams = new glsTextureTestUtil.ReferenceParams(glsTextureTestUtil.textureType.TEXTURETYPE_2D);
+ var rendered = new tcuSurface.Surface(viewport.width, viewport.height);
+ var texCoord = [];
+
+ if (viewport.width < MIN_VIEWPORT_WIDTH || viewport.height < MIN_VIEWPORT_HEIGHT)
+ throw new Error('Too small render target');
+
+ // Setup params for reference.
+ sampleParams.sampler = gluTextureUtil.mapGLSampler(this.m_wrapS, this.m_wrapT, gl.CLAMP_TO_EDGE, this.m_minFilter, this.m_magFilter);
+ sampleParams.sampler.compare = gluTextureUtil.mapGLCompareFunc(this.m_compareFunc);
+ sampleParams.samplerType = glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW;
+ sampleParams.lodMode = glsTextureTestUtil.lodMode.EXACT;
+ sampleParams.ref = curCase.ref;
+
+ bufferedLogToConsole('Compare reference value = ' + sampleParams.ref);
+
+ // Compute texture coordinates.
+ bufferedLogToConsole('Texture coordinates: ' + curCase.minCoord + ' -> ' + curCase.maxCoord);
+
+ texCoord = glsTextureTestUtil.computeQuadTexCoord2D(curCase.minCoord, curCase.maxCoord);
+
+ gl.bindTexture(gl.TEXTURE_2D, curCase.texture.getGLTexture());
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.m_minFilter);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.m_magFilter);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, this.m_wrapS);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, this.m_wrapT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_COMPARE_FUNC, this.m_compareFunc);
+
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+ this.m_renderer.renderQuad(0, texCoord, sampleParams);
+ rendered.readViewport(gl, viewport);
+
+
+ var pixelFormat = new tcuPixelFormat.PixelFormat(8, 8, 8, 8);
+ var lodPrecision = new tcuTexLookupVerifier.LodPrecision(18, 6);
+ var texComparePrecision = new tcuTexCompareVerifier.TexComparePrecision([20, 20, 0], [7, 7, 0], 5, 16, pixelFormat.redBits - 1);
+
+ var isHighQuality = es3fTextureShadowTests.verifyTexCompareResult(tcuTexture.Texture2D, rendered.getAccess(), curCase.texture.getRefTexture(),
+ texCoord, sampleParams, texComparePrecision, lodPrecision, pixelFormat);
+
+ if (!isHighQuality) {
+ bufferedLogToConsole('Warning: Verification assuming high-quality PCF filtering failed.');
+
+ lodPrecision.lodBits = 4;
+ texComparePrecision.uvwBits = [4, 4, 0];
+ texComparePrecision.pcfBits = 0;
+
+ var isOk = es3fTextureShadowTests.verifyTexCompareResult(tcuTexture.Texture2D, rendered.getAccess(), curCase.texture.getRefTexture(),
+ texCoord, sampleParams, texComparePrecision, lodPrecision, pixelFormat);
+
+ if (!isOk) {
+ bufferedLogToConsole('ERROR: Verification against low precision requirements failed, failing test case.');
+ testFailedOptions('Image verification failed', false);
+ } else
+ testPassedOptions('Low-quality result', true);
+ } else
+ testPassedOptions('High-quality result', true);
+
+ this.m_caseNdx += 1;
+ return this.m_caseNdx < this.m_cases.length ? tcuTestCase.IterateResult.CONTINUE : tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @constructor
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} minFilter
+ * @param {number} magFilter
+ * @param {number} wrapS
+ * @param {number} wrapT
+ * @param {number} format
+ * @param {number} size
+ * @param {number} compareFunc
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fTextureShadowTests.TextureCubeShadowCase = function(name, desc, minFilter, magFilter, wrapS, wrapT, format, size, compareFunc) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ this.m_minFilter = minFilter;
+ this.m_magFilter = magFilter;
+ this.m_wrapS = wrapS;
+ this.m_wrapT = wrapT;
+ this.m_format = format;
+ this.m_size = size;
+ this.m_compareFunc = compareFunc;
+ this.m_renderer = new glsTextureTestUtil.TextureRenderer(es3fTextureShadowTests.version, gluShaderUtil.precision.PRECISION_HIGHP);
+ this.m_caseNdx = 0;
+ this.m_cases = [];
+ };
+
+ es3fTextureShadowTests.TextureCubeShadowCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fTextureShadowTests.TextureCubeShadowCase.prototype.constructor = es3fTextureShadowTests.TextureCubeShadowCase;
+
+ es3fTextureShadowTests.TextureCubeShadowCase.prototype.init = function() {
+ DE_ASSERT(!this.m_gradientTex && !this.m_gridTex);
+
+ var numLevels = Math.floor(Math.log2(this.m_size)) + 1;
+ /** @type {tcuTexture.TextureFormat} */ var texFmt = gluTextureUtil.mapGLInternalFormat(this.m_format);
+ /** @type {tcuTextureUtil.TextureFormatInfo} */ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
+ /** @type {Array<number>} */ var cBias = fmtInfo.valueMin;
+ /** @type {Array<number>} */ var cScale = deMath.subtract(fmtInfo.valueMax, fmtInfo.valueMin);
+
+ // Create textures.
+ this.m_gradientTex = gluTexture.cubeFromInternalFormat(gl, this.m_format, this.m_size);
+ this.m_gridTex = gluTexture.cubeFromInternalFormat(gl, this.m_format, this.m_size);
+
+ // Fill first with gradient texture.
+ var gradients = [[[-1.0, -1.0, -1.0, 2.0], [1.0, 1.0, 1.0, 0.0]], // negative x
+ [[0.0, -1.0, -1.0, 2.0], [1.0, 1.0, 1.0, 0.0]], // positive x
+ [[-1.0, 0.0, -1.0, 2.0], [1.0, 1.0, 1.0, 0.0]], // negative y
+ [[-1.0, -1.0, 0.0, 2.0], [1.0, 1.0, 1.0, 0.0]], // positive y
+ [[-1.0, -1.0, -1.0, 0.0], [1.0, 1.0, 1.0, 1.0]], // negative z
+ [[0.0, 0.0, 0.0, 2.0], [1.0, 1.0, 1.0, 0.0]]]; // positive z
+
+ for (var face in tcuTexture.CubeFace) {
+ for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ this.m_gradientTex.getRefTexture().allocLevel(tcuTexture.CubeFace[face], levelNdx);
+ tcuTextureUtil.fillWithComponentGradients(this.m_gradientTex.getRefTexture().getLevelFace(levelNdx, tcuTexture.CubeFace[face]), deMath.add(deMath.multiply(gradients[tcuTexture.CubeFace[face]][0], cScale), cBias), deMath.add(deMath.multiply(gradients[tcuTexture.CubeFace[face]][1], cScale), cBias));
+ }
+ }
+
+ // Fill second with grid texture.
+ for (var face in tcuTexture.CubeFace) {
+ for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ var step = 0x00ffffff / (numLevels * Object.keys(tcuTexture.CubeFace).length);
+ var rgb = step * levelNdx * face;
+ var colorA = 0xff000000 | rgb;
+ var colorB = 0xff000000 | ~rgb;
+
+ this.m_gridTex.getRefTexture().allocLevel(tcuTexture.CubeFace[face], levelNdx);
+ tcuTextureUtil.fillWithGrid(this.m_gridTex.getRefTexture().getLevelFace(levelNdx, tcuTexture.CubeFace[face]), 4, deMath.add(deMath.multiply(tcuRGBA.newRGBAFromValue(colorA).toVec(), cScale), cBias), deMath.add(deMath.multiply(tcuRGBA.newRGBAFromValue(colorB).toVec(), cScale), cBias));
+ }
+ }
+
+ // Upload.
+ this.m_gradientTex.upload();
+ this.m_gridTex.upload();
+
+ var refInRangeUpper = (this.m_compareFunc == gl.EQUAL || this.m_compareFunc == gl.NOTEQUAL) ? 1.0 : 0.5;
+ var refInRangeLower = (this.m_compareFunc == gl.EQUAL || this.m_compareFunc == gl.NOTEQUAL) ? 0.0 : 0.5;
+ var refOutOfBoundsUpper = 1.1;
+ var refOutOfBoundsLower = -0.1;
+ var singleSample = new rrMultisamplePixelBufferAccess.MultisamplePixelBufferAccess().getNumSamples() == 0;
+ //var singleSample = this.m_context.getRenderTarget().getNumSamples() == 0;
+
+ if (singleSample)
+ this.m_cases.push(new es3fTextureShadowTests.FilterCase(this.m_gradientTex, refInRangeUpper, [-1.25, -1.2], [1.2, 1.25])); // minification
+ else
+ this.m_cases.push(new es3fTextureShadowTests.FilterCase(this.m_gradientTex, refInRangeUpper, [-1.19, -1.3], [1.1, 1.35])); // minification - w/ tuned coordinates to avoid hitting triangle edges
+
+ this.m_cases.push(new es3fTextureShadowTests.FilterCase(this.m_gradientTex, refInRangeLower, [0.8, 0.8], [1.25, 1.20])); // magnification
+ this.m_cases.push(new es3fTextureShadowTests.FilterCase(this.m_gridTex, refInRangeUpper, [-1.19, -1.3], [1.1, 1.35])); // minification
+ this.m_cases.push(new es3fTextureShadowTests.FilterCase(this.m_gridTex, refInRangeLower, [-1.2, -1.1], [-0.8, -0.8])); // magnification
+ this.m_cases.push(new es3fTextureShadowTests.FilterCase(this.m_gridTex, refOutOfBoundsUpper, [-0.61, -0.1], [0.9, 1.18])); // reference value clamp, upper
+
+ if (singleSample)
+ this.m_cases.push(new es3fTextureShadowTests.FilterCase(this.m_gridTex, refOutOfBoundsLower, [-0.75, 1.0], [0.05, 0.75])); // reference value clamp, lower
+ else
+ this.m_cases.push(new es3fTextureShadowTests.FilterCase(this.m_gridTex, refOutOfBoundsLower, [-0.75, 1.0], [0.25, 0.75])); // reference value clamp, lower
+
+ this.m_caseNdx = 0;
+ };
+
+ es3fTextureShadowTests.TextureCubeShadowCase.prototype.iterate = function() {
+ var viewportSize = 28;
+ var viewport = new glsTextureTestUtil.RandomViewport(document.getElementById('canvas'), viewportSize, viewportSize, deString.deStringHash(this.fullName()) ^ deMath.deMathHash(this.m_caseNdx));
+ var curCase = this.m_cases[this.m_caseNdx];
+ var sampleParams = new glsTextureTestUtil.ReferenceParams(glsTextureTestUtil.textureType.TEXTURETYPE_CUBE);
+
+ if (viewport.width < viewportSize || viewport.height < viewportSize)
+ throw new Error('Too small render target');
+
+ // Setup texture
+ gl.bindTexture(gl.TEXTURE_CUBE_MAP, curCase.texture.getGLTexture());
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, this.m_minFilter);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, this.m_magFilter);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, this.m_wrapS);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, this.m_wrapT);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_COMPARE_FUNC, this.m_compareFunc);
+
+ // Other state
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+
+ // Params for reference computation.
+ sampleParams.sampler = gluTextureUtil.mapGLSampler(gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE, gl.CLAMP_TO_EDGE, this.m_minFilter, this.m_magFilter);
+ sampleParams.sampler.seamlessCubeMap = true;
+ sampleParams.sampler.compare = gluTextureUtil.mapGLCompareFunc(this.m_compareFunc);
+ sampleParams.samplerType = glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW;
+ sampleParams.lodMode = glsTextureTestUtil.lodMode.EXACT;
+ sampleParams.ref = curCase.ref;
+
+ bufferedLogToConsole(
+ 'Compare reference value = ' + sampleParams.ref + '\n' +
+ 'Coordinates: ' + curCase.minCoord + ' -> ' + curCase.maxCoord);
+
+ for (var faceNdx in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[faceNdx];
+ var result = new tcuSurface.Surface(viewport.width, viewport.height);
+ var texCoord = [];
+
+ texCoord = glsTextureTestUtil.computeQuadTexCoordCubeFace(face, curCase.minCoord, curCase.maxCoord);
+
+ this.m_renderer.renderQuad(0, texCoord, sampleParams);
+
+ result.readViewport(gl, viewport);
+
+ var pixelFormat = new tcuPixelFormat.PixelFormat(8, 8, 8, 8);
+ /** @type {tcuTexLookupVerifier.LodPrecision} */ var lodPrecision = new tcuTexLookupVerifier.LodPrecision(10, 5);
+ /** @type {tcuTexCompareVerifier.TexComparePrecision} */ var texComparePrecision = new tcuTexCompareVerifier.TexComparePrecision(
+ [10, 10, 10],
+ [6, 6, 0],
+ 5,
+ 16,
+ pixelFormat.redBits - 1
+ );
+
+ var isHighQuality = es3fTextureShadowTests.verifyTexCompareResult(tcuTexture.TextureCube, result.getAccess(), curCase.texture.getRefTexture(),
+ texCoord, sampleParams, texComparePrecision, lodPrecision, pixelFormat);
+
+ if (!isHighQuality) {
+ bufferedLogToConsole('Warning: Verification assuming high-quality PCF filtering failed.');
+
+ lodPrecision.lodBits = 4;
+ texComparePrecision.uvwBits = [4, 4, 0];
+ texComparePrecision.pcfBits = 0;
+
+ var isOk = es3fTextureShadowTests.verifyTexCompareResult(tcuTexture.TextureCube, result.getAccess(), curCase.texture.getRefTexture(),
+ texCoord, sampleParams, texComparePrecision, lodPrecision, pixelFormat);
+ if (!isOk) {
+ bufferedLogToConsole('ERROR: Verification against low precision requirements failed, failing test case.');
+ testFailedOptions('Image verification failed', false);
+ } else
+ testPassedOptions('Low-quality result', true);
+ }
+ else
+ testPassedOptions('High-quality result', true);
+ }
+
+ this.m_caseNdx += 1;
+ return this.m_caseNdx < this.m_cases.length ? tcuTestCase.IterateResult.CONTINUE : tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * Testure2DArrayShadowCase
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} minFilter
+ * @param {number} magFilter
+ * @param {number} wrapS
+ * @param {number} wrapT
+ * @param {number} format
+ * @param {number} width
+ * @param {number} height
+ * @param {number} numLayers
+ * @param {number} compareFunc
+ */
+ es3fTextureShadowTests.Texture2DArrayShadowCase = function(name, desc, minFilter, magFilter, wrapS, wrapT, format, width, height, numLayers, compareFunc) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ /** @type {number} */ this.m_minFilter = minFilter;
+ /** @type {number} */ this.m_magFilter = magFilter;
+ /** @type {number} */ this.m_wrapS = wrapS;
+ /** @type {number} */ this.m_wrapT = wrapT;
+ /** @type {number} */ this.m_format = format;
+ /** @type {number} */ this.m_width = width;
+ /** @type {number} */ this.m_height = height;
+ /** @type {number} */ this.m_numLayers = numLayers;
+ /** @type {number} */ this.m_compareFunc = compareFunc;
+ /** @type {?gluTexture.Texture2DArray} */ this.m_gradientTex = null;
+ /** @type {?gluTexture.Texture2DArray} */ this.m_gridTex = null;
+ /** @type {glsTextureTestUtil.TextureRenderer} */ this.m_renderer = new glsTextureTestUtil.TextureRenderer(es3fTextureShadowTests.version, gluShaderUtil.precision.PRECISION_HIGHP);
+ /** @type {Array<es3fTextureShadowTests.FilterCase>} */ this.m_cases = [];
+ /** @type {number} */ this.m_caseNdx = 0;
+ };
+
+ es3fTextureShadowTests.Texture2DArrayShadowCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fTextureShadowTests.Texture2DArrayShadowCase.prototype.constructor = es3fTextureShadowTests.Texture2DArrayShadowCase;
+
+ /**
+ * init
+ */
+ es3fTextureShadowTests.Texture2DArrayShadowCase.prototype.init = function() {
+ /** @type {tcuTexture.TextureFormat} */ var texFmt = gluTextureUtil.mapGLInternalFormat(this.m_format);
+ /** @type {tcuTextureUtil.TextureFormatInfo} */ var fmtInfo = tcuTextureUtil.getTextureFormatInfo(texFmt);
+ /** @type {Array<number>}*/ var cScale = deMath.subtract(fmtInfo.valueMax, fmtInfo.valueMin);
+ /** @type {Array<number>}*/ var cBias = fmtInfo.valueMin;
+ /** @type {number}*/ var numLevels = deMath.logToFloor(Math.max(this.m_width, this.m_height)) + 1;
+
+ // Create textures.
+ this.m_gradientTex = gluTexture.texture2DArrayFromInternalFormat(gl, this.m_format, this.m_width, this.m_height, this.m_numLayers);
+ this.m_gridTex = gluTexture.texture2DArrayFromInternalFormat(gl, this.m_format, this.m_width, this.m_height, this.m_numLayers);
+
+ // Fill first gradient texture.
+ for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ /** @type {Array<number>}*/ var gMin = deMath.add(deMath.multiply([-0.5, -0.5, -0.5, 2.0], cScale), cBias);
+ /** @type {Array<number>}*/ var gMax = deMath.add(deMath.multiply([1.0, 1.0, 1.0, 0.0], cScale), cBias);
+
+ this.m_gradientTex.getRefTexture().allocLevel(levelNdx);
+ tcuTextureUtil.fillWithComponentGradients(
+ /** @type {tcuTexture.PixelBufferAccess} */ (this.m_gradientTex.getRefTexture().getLevel(levelNdx)), gMin, gMax);
+ }
+
+ // Fill second with grid texture.
+ for (var levelNdx = 0; levelNdx < numLevels; levelNdx++) {
+ /** @type {number}*/ var step = Math.floor(0x00ffffff / numLevels);
+ /** @type {number}*/ var rgb = step * levelNdx;
+ /** @type {number}*/ var colorA = deMath.binaryOp(0xff000000, rgb, deMath.BinaryOp.OR);
+ /** @type {number}*/ var colorB = deMath.binaryOp(0xff000000, deMath.binaryNot(rgb), deMath.BinaryOp.OR);
+
+ this.m_gridTex.getRefTexture().allocLevel(levelNdx);
+ tcuTextureUtil.fillWithGrid(
+ /** @type {tcuTexture.PixelBufferAccess} */ (this.m_gridTex.getRefTexture().getLevel(levelNdx)), 4,
+ deMath.add(deMath.multiply(tcuRGBA.newRGBAFromValue(colorA).toVec(), cScale), cBias),
+ deMath.add(deMath.multiply(tcuRGBA.newRGBAFromValue(colorB).toVec(), cScale), cBias)
+ );
+ }
+
+ // Upload.
+ this.m_gradientTex.upload();
+ this.m_gridTex.upload();
+
+ // Compute cases.
+ /** @type {number} */ var refInRangeUpper = (this.m_compareFunc == gl.EQUAL || this.m_compareFunc == gl.NOTEQUAL) ? 1.0 : 0.5;
+ /** @type {number} */ var refInRangeLower = (this.m_compareFunc == gl.EQUAL || this.m_compareFunc == gl.NOTEQUAL) ? 0.0 : 0.5;
+ /** @type {number} */ var refOutOfBoundsUpper = 1.1; // !< lookup function should clamp values to [0, 1] range
+ /** @type {number} */ var refOutOfBoundsLower = -0.1;
+
+ /** @type {Array<{texNdx: number, ref: number, lodX: number, lodY: number, oX: number, oY: number}>} */
+ var cases = [{ texNdx: 0, ref: refInRangeUpper, lodX: 1.6, lodY: 2.9, oX: -1.0, oY: -2.7 },{ texNdx: 0, ref: refInRangeLower, lodX: -2.0, lodY: -1.35, oX: -0.2, oY: 0.7 },{ texNdx: 1, ref: refInRangeUpper, lodX: 0.14, lodY: 0.275, oX: -1.5, oY: -1.1 },{ texNdx: 1, ref: refInRangeLower, lodX: -0.92, lodY: -2.64, oX: 0.4, oY: -0.1 },{ texNdx: 1, ref: refOutOfBoundsUpper, lodX: -0.49, lodY: -0.22, oX: 0.45, oY: 0.97 },{ texNdx: 1, ref: refOutOfBoundsLower, lodX: -0.85, lodY: 0.75, oX: 0.25, oY: 0.61 }
+ ];
+
+ var viewportW = Math.min(VIEWPORT_WIDTH, gl.canvas.width);
+ var viewportH = Math.min(VIEWPORT_HEIGHT, gl.canvas.height);
+
+ /** @type {number} */ var minLayer = -0.5;
+ /** @type {number} */ var maxLayer = this.m_numLayers;
+
+ for (var caseNdx = 0; caseNdx < cases.length; caseNdx++) {
+ var tex = cases[caseNdx].texNdx > 0 ? this.m_gridTex : this.m_gradientTex;
+ /** @type {number} */ var ref = cases[caseNdx].ref;
+ /** @type {number} */ var lodX = cases[caseNdx].lodX;
+ /** @type {number} */ var lodY = cases[caseNdx].lodY;
+ /** @type {number} */ var oX = cases[caseNdx].oX;
+ /** @type {number} */ var oY = cases[caseNdx].oY;
+ /** @type {number} */ var sX = Math.exp(lodX * Math.LN2) * viewportW / tex.getRefTexture().getWidth();
+ /** @type {number} */ var sY = Math.exp(lodY * Math.LN2) * viewportH / tex.getRefTexture().getHeight();
+
+ this.m_cases.push(new es3fTextureShadowTests.FilterCase(tex, ref, [oX, oY, minLayer], [oX + sX, oY + sY, maxLayer]));
+ }
+
+ this.m_caseNdx = 0;
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fTextureShadowTests.Texture2DArrayShadowCase.prototype.iterate = function() {
+ var viewport = new glsTextureTestUtil.RandomViewport(document.getElementById('canvas'), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, deString.deStringHash(this.fullName()) ^ deMath.deMathHash(this.m_caseNdx));
+ var curCase = this.m_cases[this.m_caseNdx];
+ var sampleParams = new glsTextureTestUtil.ReferenceParams(glsTextureTestUtil.textureType.TEXTURETYPE_2D_ARRAY);
+ var rendered = new tcuSurface.Surface(viewport.width, viewport.height);
+ var texCoord = [];
+
+ texCoord = [curCase.minCoord[0], curCase.minCoord[1], curCase.minCoord[2],
+ curCase.minCoord[0], curCase.maxCoord[1], (curCase.minCoord[2] + curCase.maxCoord[2]) / 2.0,
+ curCase.maxCoord[0], curCase.minCoord[1], (curCase.minCoord[2] + curCase.maxCoord[2]) / 2.0,
+ curCase.maxCoord[0], curCase.maxCoord[1], curCase.maxCoord[2]];
+
+ if (viewport.width < MIN_VIEWPORT_WIDTH || viewport.height < MIN_VIEWPORT_HEIGHT)
+ throw new Error('Too small render target');
+
+ sampleParams.sampler = gluTextureUtil.mapGLSamplerWrapST(this.m_wrapS, this.m_wrapT, this.m_minFilter, this.m_magFilter);
+ sampleParams.sampler.compare = gluTextureUtil.mapGLCompareFunc(this.m_compareFunc);
+ sampleParams.samplerType = glsTextureTestUtil.samplerType.SAMPLERTYPE_SHADOW;
+ sampleParams.lodMode = glsTextureTestUtil.lodMode.EXACT;
+ sampleParams.ref = curCase.ref;
+
+ bufferedLogToConsole(
+ 'Compare reference value = ' + sampleParams.ref + '\n' +
+ 'Texture Coordinates: ' + curCase.minCoord + ' -> ' + curCase.maxCoord
+ );
+
+ gl.bindTexture(gl.TEXTURE_2D_ARRAY, curCase.texture.getGLTexture());
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, this.m_minFilter);
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, this.m_magFilter);
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_S, this.m_wrapS);
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_T, this.m_wrapT);
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_COMPARE_MODE, gl.COMPARE_REF_TO_TEXTURE);
+ gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_COMPARE_FUNC, this.m_compareFunc);
+
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+ this.m_renderer.renderQuad(0, texCoord, sampleParams);
+ rendered.readViewport(gl, viewport);
+
+ var pixelFormat = new tcuPixelFormat.PixelFormat(8, 8, 8, 8);
+ /** @type {tcuTexLookupVerifier.LodPrecision} */ var lodPrecision = new tcuTexLookupVerifier.LodPrecision(18, 6);
+ /** @type {tcuTexCompareVerifier.TexComparePrecision} */ var texComparePrecision = new tcuTexCompareVerifier.TexComparePrecision(
+ [20, 20, 20],
+ [7, 7, 7],
+ 5,
+ 16,
+ pixelFormat.redBits - 1
+ );
+
+ var isHighQuality = es3fTextureShadowTests.verifyTexCompareResult(tcuTexture.Texture2DArray, rendered.getAccess(), curCase.texture.getRefTexture(),
+ texCoord, sampleParams, texComparePrecision, lodPrecision, pixelFormat);
+
+ if (!isHighQuality) {
+ bufferedLogToConsole('Warning: Verification assuming high-quality PCF filtering failed');
+
+ lodPrecision.lodBits = 4;
+ texComparePrecision.uvwBits = [4, 4, 4];
+ texComparePrecision.pcfBits = 0;
+
+ var isOk = es3fTextureShadowTests.verifyTexCompareResult(tcuTexture.Texture2DArray, rendered.getAccess(), curCase.texture.getRefTexture(),
+ texCoord, sampleParams, texComparePrecision, lodPrecision, pixelFormat);
+
+ if (!isOk) {
+ bufferedLogToConsole('ERROR: Verification against low precision requirements failed, failing test case.');
+ testFailedOptions('Image verification failed', false);
+ } else
+ testPassedOptions('Low-quality result', true);
+ } else
+ testPassedOptions('High-quality result', true);
+
+ this.m_caseNdx += 1;
+ return this.m_caseNdx < this.m_cases.length ? tcuTestCase.IterateResult.CONTINUE : tcuTestCase.IterateResult.STOP;
+ };
+
+ es3fTextureShadowTests.init = function() {
+ /** @type {Array<es3fTextureShadowTests.Format>} */ var formats = [];
+ formats.push(new es3fTextureShadowTests.Format('depth_component16', gl.DEPTH_COMPONENT16));
+ formats.push(new es3fTextureShadowTests.Format('depth_component32f', gl.DEPTH_COMPONENT32F));
+ formats.push(new es3fTextureShadowTests.Format('depth24_stencil8', gl.DEPTH24_STENCIL8));
+
+ /** @type {Array<es3fTextureShadowTests.Filter>} */ var filters = [];
+ filters.push(new es3fTextureShadowTests.Filter('nearest', gl.NEAREST, gl.NEAREST));
+ filters.push(new es3fTextureShadowTests.Filter('linear', gl.LINEAR, gl.LINEAR));
+ filters.push(new es3fTextureShadowTests.Filter('nearest_mipmap_nearest', gl.NEAREST_MIPMAP_NEAREST, gl.LINEAR));
+ filters.push(new es3fTextureShadowTests.Filter('linear_mipmap_nearest', gl.LINEAR_MIPMAP_NEAREST, gl.LINEAR));
+ filters.push(new es3fTextureShadowTests.Filter('nearest_mipmap_linear', gl.NEAREST_MIPMAP_LINEAR, gl.LINEAR));
+ filters.push(new es3fTextureShadowTests.Filter('linear_mipmap_linear', gl.LINEAR_MIPMAP_LINEAR, gl.LINEAR));
+
+ /** @type {Array<es3fTextureShadowTests.CompareFunc>} */ var compareFuncs = [];
+ compareFuncs.push(new es3fTextureShadowTests.CompareFunc('less_or_equal', gl.LEQUAL));
+ compareFuncs.push(new es3fTextureShadowTests.CompareFunc('greater_or_equal', gl.GEQUAL));
+ compareFuncs.push(new es3fTextureShadowTests.CompareFunc('less', gl.LESS));
+ compareFuncs.push(new es3fTextureShadowTests.CompareFunc('greater', gl.GREATER));
+ compareFuncs.push(new es3fTextureShadowTests.CompareFunc('equal', gl.EQUAL));
+ compareFuncs.push(new es3fTextureShadowTests.CompareFunc('not_equal', gl.NOTEQUAL));
+ compareFuncs.push(new es3fTextureShadowTests.CompareFunc('always', gl.ALWAYS));
+ compareFuncs.push(new es3fTextureShadowTests.CompareFunc('never', gl.NEVER));
+
+ var state = tcuTestCase.runner;
+ /** @type {tcuTestCase.DeqpTest} */ var testGroup = state.testCases;
+
+ for (var filterNdx = 0; filterNdx < filters.length; filterNdx++) {
+ for (var compareNdx = 0; compareNdx < compareFuncs.length; compareNdx++) {
+ var filterGroup = tcuTestCase.newTest(
+ '2d.' + filters[filterNdx].name, '2D texture shadow lookup tests');
+ testGroup.addChild(filterGroup);
+
+ for (var formatNdx = 0; formatNdx < formats.length; formatNdx++) {
+ /** @type {number} */ var minFilter = filters[filterNdx].minFilter;
+ /** @type {number} */ var magFilter = filters[filterNdx].magFilter;
+ /** @type {number} */ var format = formats[formatNdx].format;
+ /** @type {number} */ var compareFunc = compareFuncs[compareNdx].func;
+ /** @type {number} */ var wrapS = gl.REPEAT;
+ /** @type {number} */ var wrapT = gl.REPEAT;
+ /** @type {number} */ var width = 32;
+ /** @type {number} */ var height = 64;
+ /** @type {string} */ var name = compareFuncs[compareNdx].name + '_' + formats[formatNdx].name;
+
+ filterGroup.addChild(new es3fTextureShadowTests.Texture2DShadowCase(name, '', minFilter, magFilter, wrapS, wrapT, format, width, height, compareFunc));
+ }
+ }
+ }
+
+ for (filterNdx = 0; filterNdx < filters.length; filterNdx++) {
+ for (compareNdx = 0; compareNdx < compareFuncs.length; compareNdx++) {
+ filterGroup = tcuTestCase.newTest(
+ 'cube.' + filters[filterNdx].name, 'Cube map texture shadow lookup tests');
+ testGroup.addChild(filterGroup);
+
+ for (formatNdx = 0; formatNdx < formats.length; formatNdx++) {
+ minFilter = filters[filterNdx].minFilter;
+ magFilter = filters[filterNdx].magFilter;
+ format = formats[formatNdx].format;
+ compareFunc = compareFuncs[compareNdx].func;
+ wrapS = gl.REPEAT;
+ wrapT = gl.REPEAT;
+ var size = 32;
+ name = compareFuncs[compareNdx].name + '_' + formats[formatNdx].name;
+
+ filterGroup.addChild(new es3fTextureShadowTests.TextureCubeShadowCase(name, '', minFilter, magFilter, wrapS, wrapT, format, size, compareFunc));
+ }
+ }
+ }
+
+ for (var filterNdx = 0; filterNdx < filters.length; filterNdx++) {
+ for (var compareNdx = 0; compareNdx < compareFuncs.length; compareNdx++) {
+ filterGroup = tcuTestCase.newTest(
+ '2d_array.' + filters[filterNdx].name, '2D texture array shadow lookup tests');
+ testGroup.addChild(filterGroup);
+
+ for (var formatNdx = 0; formatNdx < formats.length; formatNdx++) {
+ minFilter = filters[filterNdx].minFilter;
+ magFilter = filters[filterNdx].magFilter;
+ format = formats[formatNdx].format;
+ compareFunc = compareFuncs[compareNdx].func;
+ wrapS = gl.REPEAT;
+ wrapT = gl.REPEAT;
+ width = 32;
+ height = 64;
+ var numLayers = 8;
+ name = compareFuncs[compareNdx].name + '_' + formats[formatNdx].name;
+
+ filterGroup.addChild(new es3fTextureShadowTests.Texture2DArrayShadowCase(name, '', minFilter, magFilter, wrapS, wrapT, format, width, height, numLayers, compareFunc));
+ }
+ }
+ }
+ };
+
+ es3fTextureShadowTests.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var testName = 'texture_shadow';
+ var testDescription = 'Texture Shadow Test';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.testCases = tcuTestCase.newTest(testName, testDescription, null);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ es3fTextureShadowTests.init();
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ bufferedLogToConsole(err);
+ tcuTestCase.runner.terminate();
+ }
+ };
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureSpecificationTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureSpecificationTests.js
new file mode 100644
index 0000000000..5ff5edc550
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureSpecificationTests.js
@@ -0,0 +1,7456 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fTextureSpecificationTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuLogImage');
+goog.require('framework.common.tcuPixelFormat');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('framework.opengl.simplereference.sglrGLContext');
+goog.require('framework.opengl.simplereference.sglrReferenceContext');
+goog.require('framework.referencerenderer.rrUtil');
+goog.require('functional.gles3.es3fFboTestUtil');
+
+goog.scope(function() {
+ var es3fTextureSpecificationTests =
+ functional.gles3.es3fTextureSpecificationTests;
+ var tcuPixelFormat = framework.common.tcuPixelFormat;
+ var tcuImageCompare = framework.common.tcuImageCompare;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuTexture = framework.common.tcuTexture;
+ var tcuTextureUtil = framework.common.tcuTextureUtil;
+ var deMath = framework.delibs.debase.deMath;
+ var deRandom = framework.delibs.debase.deRandom;
+ var deString = framework.delibs.debase.deString;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluTextureUtil = framework.opengl.gluTextureUtil;
+ var sglrGLContext = framework.opengl.simplereference.sglrGLContext;
+ var sglrReferenceContext =
+ framework.opengl.simplereference.sglrReferenceContext;
+ var rrUtil = framework.referencerenderer.rrUtil;
+ var es3fFboTestUtil = functional.gles3.es3fFboTestUtil;
+ var tcuLogImage = framework.common.tcuLogImage;
+
+ /**
+ * @param {number} internalFormat
+ * @return {tcuTexture.TextureFormat}
+ */
+ es3fTextureSpecificationTests.mapGLUnsizedInternalFormat = function(
+ internalFormat
+ ) {
+ switch (internalFormat) {
+ case gl.ALPHA:
+ return new tcuTexture.TextureFormat(
+ tcuTexture.ChannelOrder.A,
+ tcuTexture.ChannelType.UNORM_INT8
+ );
+ case gl.LUMINANCE:
+ return new tcuTexture.TextureFormat(
+ tcuTexture.ChannelOrder.L,
+ tcuTexture.ChannelType.UNORM_INT8
+ );
+ case gl.LUMINANCE_ALPHA:
+ return new tcuTexture.TextureFormat(
+ tcuTexture.ChannelOrder.LA,
+ tcuTexture.ChannelType.UNORM_INT8
+ );
+ case gl.RGB:
+ return new tcuTexture.TextureFormat(
+ tcuTexture.ChannelOrder.RGB,
+ tcuTexture.ChannelType.UNORM_INT8
+ );
+ case gl.RGBA:
+ return new tcuTexture.TextureFormat(
+ tcuTexture.ChannelOrder.RGBA,
+ tcuTexture.ChannelType.UNORM_INT8
+ );
+ default:
+ throw new Error(
+ 'Can\'t map GL unsized internal format (' +
+ internalFormat.toString(16) + ') to texture format'
+ );
+ }
+ };
+
+ var VIEWPORT_WIDTH = 256;
+ var VIEWPORT_HEIGHT = 256;
+
+ /**
+ * @param {number} width
+ * @param {number} height
+ * @param {number=} depth
+ * @return {number}
+ */
+ es3fTextureSpecificationTests.maxLevelCount = function(
+ width, height, depth
+ ) {
+ depth = depth || 0;
+ return deMath.logToFloor(Math.max(width, Math.max(height, depth))) + 1;
+ };
+
+ /**
+ * @param {deRandom.Random} rnd
+ * @param {Array<number>} minVal
+ * @param {Array<number>} maxVal
+ * @param {number} size
+ * @return {Array<number>}
+ */
+ es3fTextureSpecificationTests.randomVector = function(
+ rnd, minVal, maxVal, size
+ ) {
+ var res = [];
+ for (var ndx = 0; ndx < size; ndx++)
+ res[ndx] = rnd.getFloat(minVal[ndx], maxVal[ndx]);
+ return res;
+ };
+
+ /**
+ * @param {tcuPixelFormat.PixelFormat} pixelFormat
+ * @param {tcuTexture.TextureFormat} textureFormat
+ * @return {Array<number>} (ivec4)
+ */
+ es3fTextureSpecificationTests.getPixelFormatCompareDepth = function(
+ pixelFormat, textureFormat
+ ) {
+ switch (textureFormat.order) {
+ case tcuTexture.ChannelOrder.L:
+ case tcuTexture.ChannelOrder.LA:
+ return [
+ pixelFormat.redBits, pixelFormat.redBits,
+ pixelFormat.redBits, pixelFormat.alphaBits
+ ];
+ default:
+ return [
+ pixelFormat.redBits, pixelFormat.greenBits,
+ pixelFormat.blueBits, pixelFormat.alphaBits
+ ];
+ }
+ };
+
+ /**
+ * @param {tcuPixelFormat.PixelFormat} pixelFormat
+ * @param {tcuTexture.TextureFormat} textureFormat
+ * @return {Array<number>} (uvec4)
+ */
+ es3fTextureSpecificationTests.computeCompareThreshold = function(
+ pixelFormat, textureFormat
+ ) {
+ /** @type {Array<number>} */
+ var texFormatBits = tcuTextureUtil.getTextureFormatBitDepth(
+ textureFormat
+ );
+ /** @type {Array<number>} */
+ var pixelFormatBits =
+ es3fTextureSpecificationTests.getPixelFormatCompareDepth(
+ pixelFormat, textureFormat
+ );
+ /** @type {Array<number>} */
+ var accurateFmtBits = deMath.min(pixelFormatBits, texFormatBits);
+ /** @type {Array<number>} */
+ var compareBits = deMath.addScalar(
+ tcuTextureUtil.select(
+ accurateFmtBits, [8, 8, 8, 8],
+ deMath.greaterThan(accurateFmtBits, [0, 0, 0, 0])
+ ), - 1
+ );
+
+ var result = [];
+ for (var i = 0; i < compareBits.length; i++)
+ result.push(1 << compareBits[i]);
+ return result;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * context
+ */
+ es3fTextureSpecificationTests.TextureSpecCase = function(name, desc) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ /**
+ * @type {
+ * ?sglrGLContext.GLContext|sglrReferenceContext.ReferenceContext
+ * }
+ */
+ this.m_context = null;
+ };
+
+ es3fTextureSpecificationTests.TextureSpecCase.prototype = Object.create(
+ tcuTestCase.DeqpTest.prototype
+ );
+
+ es3fTextureSpecificationTests.TextureSpecCase.prototype.constructor =
+ es3fTextureSpecificationTests.TextureSpecCase;
+
+ /**
+ * deinit
+ */
+ es3fTextureSpecificationTests.TextureSpecCase.prototype.deinit =
+ function() {
+ gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4);
+ gl.pixelStorei(gl.UNPACK_ROW_LENGTH, 0);
+ gl.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, 0);
+ gl.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0);
+ gl.pixelStorei(gl.UNPACK_SKIP_ROWS, 0);
+ gl.pixelStorei(gl.UNPACK_SKIP_IMAGES, 0);
+
+ gl.bindBuffer(gl.PIXEL_UNPACK_BUFFER, null);
+ }
+
+ /**
+ * createTexture - Needs to be overridden
+ */
+ es3fTextureSpecificationTests.TextureSpecCase.prototype.createTexture =
+ function() {
+ throw new Error('Must override');
+ };
+
+ /**
+ * verifyTexture - Needs to be overridden
+ * @param {sglrGLContext.GLContext} webgl2Context
+ * @param {sglrReferenceContext.ReferenceContext} refContext
+ * @return {boolean}
+ */
+ es3fTextureSpecificationTests.TextureSpecCase.prototype.verifyTexture =
+ function(
+ webgl2Context, refContext
+ ) {
+ throw new Error('Must override');
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fTextureSpecificationTests.TextureSpecCase.prototype.iterate = function() {
+ if (gl.canvas.width < VIEWPORT_WIDTH ||
+ gl.canvas.height < VIEWPORT_HEIGHT)
+ throw new Error('Too small viewport', '');
+
+ // Context size, and viewport for GLES3
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+ var width = Math.min(gl.canvas.width, VIEWPORT_WIDTH);
+ var height = Math.min(gl.canvas.height, VIEWPORT_HEIGHT);
+ var x = rnd.getInt(0, gl.canvas.width - width);
+ var y = rnd.getInt(0, gl.canvas.height - height);
+
+ // Contexts.
+ /** @type {sglrGLContext.GLContext} */
+ var webgl2Context = new sglrGLContext.GLContext(
+ gl, [x, y, width, height]
+ );
+
+ /** @type {sglrReferenceContext.ReferenceContextBuffers} */
+ var refBuffers = new sglrReferenceContext.ReferenceContextBuffers(
+ new tcuPixelFormat.PixelFormat(
+ 8, 8, 8, gl.getParameter(gl.ALPHA_BITS) ? 8 : 0
+ ), 0 /* depth */, 0 /* stencil */, width, height
+ );
+
+ /** @type {sglrReferenceContext.ReferenceContext} */
+ var refContext = new sglrReferenceContext.ReferenceContext(
+ new sglrReferenceContext.ReferenceContextLimits(gl),
+ refBuffers.getColorbuffer(), refBuffers.getDepthbuffer(),
+ refBuffers.getStencilbuffer()
+ );
+
+ // Clear color buffer.
+ for (var ndx = 0; ndx < 2; ndx++) {
+ this.m_context = ndx ? refContext : webgl2Context;
+ // C++ port uses (0.125, 0.25, 0.5, 1.0), but here we use (0, 0, 0, 0)
+ // in order to optimize the `clear' op in ReferenceContext.
+ this.m_context.clearColor(0, 0, 0, 0);
+ this.m_context.clear(
+ gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT |
+ gl.STENCIL_BUFFER_BIT
+ );
+ }
+
+ // Construct texture using both GLES3 and reference contexts.
+ for (var ndx = 0; ndx < 2; ndx++) {
+ this.m_context = ndx ? refContext : webgl2Context;
+ this.createTexture();
+ checkMessage(
+ this.m_context.getError() == gl.NO_ERROR,
+ 'Problem creating texture.'
+ );
+ }
+
+ // Verify results.
+ if (this.verifyTexture(webgl2Context, refContext))
+ testPassed();
+ else
+ testFailed('Verification failed');
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @param {tcuSurface.Surface} dst
+ * @param {
+ * ?WebGLProgram|
+ * framework.opengl.simplereference.sglrShaderProgram.ShaderProgram
+ * } program
+ * @param {number} width
+ * @param {number} height
+ */
+ es3fTextureSpecificationTests.TextureSpecCase.prototype.renderTex =
+ function(dst, program, width, height) {
+ var targetW = this.m_context.getWidth();
+ var targetH = this.m_context.getHeight();
+
+ var w = width / targetW;
+ var h = height / targetH;
+
+ rrUtil.drawQuad(
+ this.m_context, program, [-1.0, -1.0, 0.0],
+ [-1.0 + w * 2.0, -1.0 + h * 2.0, 0.0]
+ );
+
+ // Read pixels back.
+ dst.readViewport(this.m_context, [0, 0, width, height]);
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.TextureSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {tcuTexture.TextureFormat} format
+ * @param {number} width
+ * @param {number} height
+ * @param {number} numLevels
+ */
+ es3fTextureSpecificationTests.Texture2DSpecCase = function(
+ name, desc, format, width, height, numLevels
+ ) {
+ es3fTextureSpecificationTests.TextureSpecCase.call(this, name, desc);
+
+ this.m_texFormat = format;
+ this.m_texFormatInfo = tcuTextureUtil.getTextureFormatInfo(format);
+ this.m_width = width;
+ this.m_height = height;
+ this.m_numLevels = numLevels;
+ };
+
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype = Object.create(
+ es3fTextureSpecificationTests.TextureSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype.constructor =
+ es3fTextureSpecificationTests.Texture2DSpecCase;
+
+ /**
+ * @param {sglrGLContext.GLContext} webgl2Context
+ * @param {sglrReferenceContext.ReferenceContext} refContext
+ */
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype.verifyTexture =
+ function(
+ webgl2Context, refContext
+ ) {
+ /** @type {es3fFboTestUtil.Texture2DShader} */
+ var shader = new es3fFboTestUtil.Texture2DShader(
+ [gluTextureUtil.getSampler2DType(this.m_texFormat)],
+ gluShaderUtil.DataType.FLOAT_VEC4
+ );
+
+ var shaderIDgles = webgl2Context.createProgram(shader);
+ var shaderIDRef = refContext.createProgram(shader);
+
+ shader.setTexScaleBias(
+ 0, this.m_texFormatInfo.lookupScale,
+ this.m_texFormatInfo.lookupBias
+ );
+
+ // Set state.
+ for (var ndx = 0; ndx < 2; ndx++) {
+ var ctx = ndx ? refContext : webgl2Context;
+
+ this.m_context = ctx;
+
+ this.m_context.texParameteri(
+ gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, this.m_numLevels - 1
+ );
+ }
+
+ for (var levelNdx = 0; levelNdx < this.m_numLevels; levelNdx++) {
+ var levelW = Math.max(1, this.m_width >> levelNdx);
+ var levelH = Math.max(1, this.m_height >> levelNdx);
+ /** @type {tcuSurface.Surface} */ var reference = new tcuSurface.Surface();
+ /** @type {tcuSurface.Surface} */ var result = new tcuSurface.Surface();
+
+ for (var ndx = 0; ndx < 2; ndx++) {
+ /** @type {tcuSurface.Surface} */
+ var dst = ndx ? reference : result;
+ var ctx = ndx ? refContext : webgl2Context;
+ var shaderID = ndx ? shaderIDRef : shaderIDgles;
+
+ this.m_context = ctx;
+ shader.setUniforms(ctx, shaderID);
+ this.renderTex(dst, shaderID, levelW, levelH);
+ }
+
+ var threshold =
+ es3fTextureSpecificationTests.computeCompareThreshold(
+ tcuPixelFormat.PixelFormatFromContext(gl), this.m_texFormat
+ );
+ var levelStr = levelNdx.toString();
+ var name = 'Level' + levelStr;
+ var desc = 'Level ' + levelStr;
+ var isOk = tcuImageCompare.intThresholdCompare(
+ name, desc, reference.getAccess(), result.getAccess(),
+ threshold, levelNdx == 0 ?
+ tcuImageCompare.CompareLogMode.RESULT :
+ tcuImageCompare.CompareLogMode.ON_ERROR
+ );
+
+ if (!isOk) {
+ testFailed('Image comparison failed');
+ return false;
+ } else {
+ // tcuLogImage.logImageWithInfo(result.getAccess(),'Comparison OK on level: ' + levelNdx);
+ }
+ }
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.TextureSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {tcuTexture.TextureFormat} format
+ * @param {number} size
+ * @param {number} numLevels
+ */
+ es3fTextureSpecificationTests.TextureCubeSpecCase = function(
+ name, desc, format, size, numLevels
+ ) {
+ es3fTextureSpecificationTests.TextureSpecCase.call(
+ this, name, desc
+ );
+ this.m_texFormat = format;
+ this.m_texFormatInfo = tcuTextureUtil.getTextureFormatInfo(format);
+ this.m_size = size;
+ this.m_numLevels = numLevels;
+ };
+
+ es3fTextureSpecificationTests.TextureCubeSpecCase.prototype =
+ Object.create(es3fTextureSpecificationTests.TextureSpecCase.prototype);
+
+ es3fTextureSpecificationTests.TextureCubeSpecCase.prototype.constructor =
+ es3fTextureSpecificationTests.TextureCubeSpecCase;
+
+ /**
+ * @param {sglrGLContext.GLContext} webgl2Context
+ * @param {sglrReferenceContext.ReferenceContext} refContext
+ */
+ es3fTextureSpecificationTests.TextureCubeSpecCase.prototype.verifyTexture =
+ function(
+ webgl2Context, refContext
+ ) {
+ /** @type {es3fFboTestUtil.TextureCubeShader} */
+ var shader = new es3fFboTestUtil.TextureCubeShader(
+ gluTextureUtil.getSamplerCubeType(this.m_texFormat),
+ gluShaderUtil.DataType.FLOAT_VEC4
+ );
+ var shaderIDgles = webgl2Context.createProgram(shader);
+ var shaderIDRef = refContext.createProgram(shader);
+
+ shader.setTexScaleBias(
+ this.m_texFormatInfo.lookupScale, this.m_texFormatInfo.lookupBias
+ );
+
+ // Set state.
+ for (var ndx = 0; ndx < 2; ndx++) {
+ var ctx = ndx ? refContext : webgl2Context;
+
+ this.m_context = ctx;
+
+ this.m_context.texParameteri(
+ gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER,
+ gl.NEAREST_MIPMAP_NEAREST
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER,
+ gl.NEAREST
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S,
+ gl.CLAMP_TO_EDGE
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T,
+ gl.CLAMP_TO_EDGE
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAX_LEVEL,
+ this.m_numLevels - 1
+ );
+ }
+
+ for (var levelNdx = 0; levelNdx < this.m_numLevels; levelNdx++) {
+ var levelSize = Math.max(1, this.m_size >> levelNdx);
+ var isOk = true;
+
+ for (var f in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[f];
+ /** @type {tcuSurface.Surface} */
+ var reference = new tcuSurface.Surface();
+ /** @type {tcuSurface.Surface} */
+ var result = new tcuSurface.Surface();
+
+ if (levelSize <= 2)
+ continue; // Fuzzy compare doesn't work for images this small.
+
+ shader.setFace(face);
+
+ for (var ndx = 0; ndx < 2; ndx++) {
+ /** @type {tcuSurface.Surface} */
+ var dst = ndx ? reference : result;
+ ctx = ndx ? refContext : webgl2Context;
+ var shaderID = ndx ? shaderIDRef : shaderIDgles;
+
+ this.m_context = ctx;
+ shader.setUniforms(ctx, shaderID);
+ this.renderTex(dst, shaderID, levelSize, levelSize);
+ }
+
+ var threshold = 0.02;
+ var faceStr = face.toString();
+ var levelStr = levelNdx.toString();
+ var name = 'Level' + levelStr;
+ var desc = 'Level ' + levelStr + ', face ' + faceStr;
+ var isFaceOk = tcuImageCompare.fuzzyCompare(
+ name, desc, reference.getAccess(), result.getAccess(),
+ threshold, levelNdx == 0 ?
+ tcuImageCompare.CompareLogMode.RESULT :
+ tcuImageCompare.CompareLogMode.ON_ERROR
+ );
+
+ if (!isFaceOk) {
+ testFailed('Image comparison failed');
+ return false;
+ }
+ }
+
+ }
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.TextureSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {tcuTexture.TextureFormat} format
+ * @param {number} width
+ * @param {number} height
+ * @param {number} numLayers
+ * @param {number} numLevels
+ */
+ es3fTextureSpecificationTests.Texture2DArraySpecCase = function(
+ name, desc, format, width, height, numLayers, numLevels
+ ) {
+ es3fTextureSpecificationTests.TextureSpecCase.call(
+ this, name, desc
+ );
+ this.m_texFormat = format;
+ this.m_texFormatInfo = tcuTextureUtil.getTextureFormatInfo(format);
+ this.m_width = width;
+ this.m_height = height;
+ this.m_numLayers = numLayers;
+ this.m_numLevels = numLevels;
+ };
+
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype =
+ Object.create(es3fTextureSpecificationTests.TextureSpecCase.prototype);
+
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype.constructor =
+ es3fTextureSpecificationTests.Texture2DArraySpecCase;
+
+ /**
+ * @param {sglrGLContext.GLContext} webgl2Context
+ * @param {sglrReferenceContext.ReferenceContext} refContext
+ */
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype.verifyTexture =
+ function(
+ webgl2Context, refContext
+ ) {
+ /** @type {es3fFboTestUtil.Texture2DArrayShader} */
+ var shader = new es3fFboTestUtil.Texture2DArrayShader(
+ gluTextureUtil.getSampler2DArrayType(this.m_texFormat),
+ gluShaderUtil.DataType.FLOAT_VEC4
+ );
+ var shaderIDgles = webgl2Context.createProgram(shader);
+ var shaderIDRef = refContext.createProgram(shader);
+
+ shader.setTexScaleBias(
+ this.m_texFormatInfo.lookupScale, this.m_texFormatInfo.lookupBias
+ );
+
+ // Set state.
+ for (var ndx = 0; ndx < 2; ndx++) {
+ var ctx = ndx ? refContext : webgl2Context;
+
+ this.m_context = ctx;
+
+ this.m_context.texParameteri(
+ gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER,
+ gl.NEAREST_MIPMAP_NEAREST
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER,
+ gl.NEAREST
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_S,
+ gl.CLAMP_TO_EDGE
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_T,
+ gl.CLAMP_TO_EDGE
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_2D_ARRAY, gl.TEXTURE_WRAP_R,
+ gl.CLAMP_TO_EDGE
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAX_LEVEL,
+ this.m_numLevels - 1
+ );
+ }
+
+ for (var layerNdx = 0; layerNdx < this.m_numLayers; layerNdx++) {
+ var layerOk = true;
+
+ shader.setLayer(layerNdx);
+ for (var levelNdx = 0; levelNdx < this.m_numLevels; levelNdx++) {
+ var levelW = Math.max(1, this.m_width >> levelNdx);
+ var levelH = Math.max(1, this.m_height >> levelNdx);
+
+ if (levelW == 1 || levelH == 1) {
+ // Rendering to texture of size x1 is problematic in referencerenderer
+ // due to its deviation from c++ code: crbug.com/613206
+ continue;
+ }
+ /** @type {tcuSurface.Surface} */
+ var reference = new tcuSurface.Surface();
+ /** @type {tcuSurface.Surface} */
+ var result = new tcuSurface.Surface();
+
+ var isOk = true;
+
+ for (var ndx = 0; ndx < 2; ndx++) {
+ /** @type {tcuSurface.Surface} */
+ var dst = ndx ? reference : result;
+ ctx = ndx ? refContext : webgl2Context;
+ var shaderID = ndx ? shaderIDRef : shaderIDgles;
+
+ this.m_context = ctx;
+ shader.setUniforms(ctx, shaderID);
+ this.renderTex(dst, shaderID, levelW, levelH);
+ }
+
+ var threshold =
+ es3fTextureSpecificationTests.computeCompareThreshold(
+ tcuPixelFormat.PixelFormatFromContext(gl), this.m_texFormat
+ );
+ var levelStr = levelNdx.toString();
+ var layerStr = layerNdx.toString();
+ var name = 'Layer' + layerStr + 'Level' + levelStr;
+ var desc = 'Layer ' + layerStr + ', Level ' + levelStr;
+ var depthOk = tcuImageCompare.intThresholdCompare(
+ name, desc, reference.getAccess(), result.getAccess(),
+ threshold, (levelNdx == 0 && layerNdx == 0) ?
+ tcuImageCompare.CompareLogMode.RESULT :
+ tcuImageCompare.CompareLogMode.ON_ERROR
+ );
+
+ if (!depthOk) {
+ testFailed('Image comparison failed');
+ return false;
+ }
+ }
+
+ }
+ return true;
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.TextureSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {tcuTexture.TextureFormat} format
+ * @param {number} width
+ * @param {number} height
+ * @param {number} depth
+ * @param {number} numLevels
+ */
+ es3fTextureSpecificationTests.Texture3DSpecCase = function(
+ name, desc, format, width, height, depth, numLevels
+ ) {
+ es3fTextureSpecificationTests.TextureSpecCase.call(
+ this, name, desc
+ );
+ this.m_texFormat = format;
+ this.m_texFormatInfo = tcuTextureUtil.getTextureFormatInfo(format);
+ this.m_width = width;
+ this.m_height = height;
+ this.m_depth = depth;
+ this.m_numLevels = numLevels;
+ };
+
+ es3fTextureSpecificationTests.Texture3DSpecCase.prototype =
+ Object.create(es3fTextureSpecificationTests.TextureSpecCase.prototype);
+
+ es3fTextureSpecificationTests.Texture3DSpecCase.prototype.constructor =
+ es3fTextureSpecificationTests.Texture3DSpecCase;
+
+ /**
+ * @param {sglrGLContext.GLContext} webgl2Context
+ * @param {sglrReferenceContext.ReferenceContext} refContext
+ */
+ es3fTextureSpecificationTests.Texture3DSpecCase.prototype.verifyTexture =
+ function(
+ webgl2Context, refContext
+ ) {
+ /** @type {es3fFboTestUtil.Texture3DShader} */
+ var shader = new es3fFboTestUtil.Texture3DShader(
+ gluTextureUtil.getSampler3D(this.m_texFormat),
+ gluShaderUtil.DataType.FLOAT_VEC4
+ );
+ var shaderIDgles = webgl2Context.createProgram(shader);
+ var shaderIDRef = refContext.createProgram(shader);
+
+ shader.setTexScaleBias(
+ this.m_texFormatInfo.lookupScale, this.m_texFormatInfo.lookupBias
+ );
+
+ // Set state.
+ for (var ndx = 0; ndx < 2; ndx++) {
+ var ctx = ndx ? refContext : webgl2Context;
+
+ this.m_context = ctx;
+
+ this.m_context.texParameteri(
+ gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER,
+ gl.NEAREST_MIPMAP_NEAREST
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER,
+ gl.NEAREST
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_3D, gl.TEXTURE_WRAP_S,
+ gl.CLAMP_TO_EDGE
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_3D, gl.TEXTURE_WRAP_T,
+ gl.CLAMP_TO_EDGE
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_3D, gl.TEXTURE_WRAP_R,
+ gl.CLAMP_TO_EDGE
+ );
+ this.m_context.texParameteri(
+ gl.TEXTURE_3D, gl.TEXTURE_MAX_LEVEL,
+ this.m_numLevels - 1
+ );
+ }
+
+ for (var levelNdx = 0; levelNdx < this.m_numLevels; levelNdx++) {
+ var levelW = Math.max(1, this.m_width >> levelNdx);
+ var levelH = Math.max(1, this.m_height >> levelNdx);
+ var levelD = Math.max(1, this.m_depth >> levelNdx);
+ var levelOk = true;
+
+ if (levelW == 1 || levelH == 1) {
+ // Rendering to texture of size x1 is problematic in referencerenderer
+ // due to its deviation from c++ code: crbug.com/613206
+ continue;
+ }
+
+ for (var depth = 0; depth < levelD; depth++) {
+ /** @type {tcuSurface.Surface} */
+ var reference = new tcuSurface.Surface();
+ /** @type {tcuSurface.Surface} */
+ var result = new tcuSurface.Surface();
+
+ shader.setDepth((depth + 0.5) / levelD);
+
+ for (var ndx = 0; ndx < 2; ndx++) {
+ /** @type {tcuSurface.Surface} */
+ var dst = ndx ? reference : result;
+ ctx = ndx ? refContext : webgl2Context;
+ var shaderID = ndx ? shaderIDRef : shaderIDgles;
+
+ this.m_context = ctx;
+ shader.setUniforms(ctx, shaderID);
+ this.renderTex(dst, shaderID, levelW, levelH);
+ }
+
+ var threshold =
+ es3fTextureSpecificationTests.computeCompareThreshold(
+ tcuPixelFormat.PixelFormatFromContext(gl), this.m_texFormat
+ );
+ var levelStr = levelNdx.toString();
+ var sliceStr = depth.toString();
+ var name = 'Layer' + levelStr + 'Slice' + sliceStr;
+ var desc = 'Layer ' + levelStr + ', Slice ' + sliceStr;
+ var depthOk = tcuImageCompare.intThresholdCompare(
+ name, desc, reference.getAccess(), result.getAccess(),
+ threshold, (levelNdx == 0 && depth == 0) ?
+ tcuImageCompare.CompareLogMode.RESULT :
+ tcuImageCompare.CompareLogMode.ON_ERROR
+ );
+
+ if (!depthOk) {
+ testFailed('Image comparison failed');
+ return false;
+ }
+ }
+
+ }
+ return true;
+ };
+
+ // Basic TexImage2D() with 2D texture usage
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} width
+ * @param {number} height
+ */
+ es3fTextureSpecificationTests.BasicTexImage2DCase = function(
+ name, desc, format, dataType, width, height
+ ) {
+ // Unsized internal format.
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ format, dataType
+ ), width, height,
+ es3fTextureSpecificationTests.maxLevelCount(
+ width, height
+ )
+ );
+
+ this.m_internalFormat = format;
+ this.m_format = format;
+ this.m_dataType = dataType;
+ };
+
+ es3fTextureSpecificationTests.BasicTexImage2DCase.prototype = Object.create(
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.BasicTexImage2DCase.prototype.constructor =
+ es3fTextureSpecificationTests.BasicTexImage2DCase;
+
+ /**
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @return {es3fTextureSpecificationTests.BasicTexImage2DCase}
+ */
+ es3fTextureSpecificationTests.newBasicTexImage2DCaseInternal = function(
+ name, desc, internalFormat, width, height
+ ) {
+ // Sized internal format.
+ var fmt = gluTextureUtil.getTransferFormat(
+ gluTextureUtil.mapGLInternalFormat(internalFormat)
+ );
+ var testcase = new es3fTextureSpecificationTests.BasicTexImage2DCase(
+ name, desc, fmt.format, fmt.dataType, width, height
+ );
+ testcase.m_internalFormat = internalFormat;
+ return testcase;
+ };
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.BasicTexImage2DCase.prototype.createTexture =
+ function() {
+ var tex = null;
+ var levelData = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_width, this.m_height
+ );
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ levelData.setSize(levelW, levelH);
+ tcuTextureUtil.fillWithComponentGradients(
+ levelData.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texImage2D(
+ gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
+ this.m_format, this.m_dataType,
+ levelData.getAccess().getDataPtr()
+ );
+ }
+ };
+
+ // Basic TexImage2D() with cubemap usage
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} size
+ */
+ es3fTextureSpecificationTests.BasicTexImageCubeCase = function(
+ name, desc, format, dataType, size
+ ) {
+ // Unsized internal format.
+ es3fTextureSpecificationTests.TextureCubeSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ format, dataType
+ ), size, deMath.logToFloor(size) + 1
+ );
+
+ this.m_internalFormat = format;
+ this.m_format = format;
+ this.m_dataType = dataType;
+ };
+
+ es3fTextureSpecificationTests.BasicTexImageCubeCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ BasicTexImageCubeCase.prototype.constructor =
+ es3fTextureSpecificationTests.BasicTexImageCubeCase;
+
+ /**
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} size
+ * @return {es3fTextureSpecificationTests.BasicTexImageCubeCase}
+ */
+ es3fTextureSpecificationTests.newBasicTexImageCubeCaseInternal = function(
+ name, desc, internalFormat, size
+ ) {
+ // Sized internal format.
+ var fmt = gluTextureUtil.getTransferFormat(
+ gluTextureUtil.mapGLInternalFormat(internalFormat)
+ );
+ var testcase = new es3fTextureSpecificationTests.BasicTexImageCubeCase(
+ name, desc, fmt.format, fmt.dataType, size
+ );
+ testcase.m_internalFormat = internalFormat;
+ return testcase;
+ };
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ BasicTexImageCubeCase.prototype.createTexture =
+ function() {
+ var tex = null;
+ var levelData = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_size, this.m_size
+ );
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelSize = Math.max(1, this.m_size >> ndx);
+
+ levelData.setSize(levelSize, levelSize);
+
+ for (var f in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[f];
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ tcuTextureUtil.fillWithComponentGradients(
+ levelData.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[face],
+ ndx, this.m_internalFormat, levelSize, levelSize, 0,
+ this.m_format, this.m_dataType,
+ levelData.getAccess().getDataPtr()
+ );
+ }
+ }
+ };
+
+ // Basic TexImage3D() with 2D array texture usage
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} numLayers
+ */
+ es3fTextureSpecificationTests.BasicTexImage2DArrayCase = function(
+ name, desc, internalFormat, width, height, numLayers
+ ) {
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
+ this, name, desc,
+ gluTextureUtil.mapGLInternalFormat(internalFormat), width, height,
+ numLayers, es3fTextureSpecificationTests.maxLevelCount(
+ width, height
+ )
+ );
+
+ this.m_internalFormat = internalFormat;
+ };
+
+ es3fTextureSpecificationTests.BasicTexImage2DArrayCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ BasicTexImage2DArrayCase.prototype.constructor =
+ es3fTextureSpecificationTests.BasicTexImage2DArrayCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ BasicTexImage2DArrayCase.prototype.createTexture =
+ function() {
+ var tex = null;
+ var levelData = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_width, this.m_height
+ );
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+ var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ levelData.setSize(levelW, levelH, this.m_numLayers);
+ tcuTextureUtil.fillWithComponentGradients(
+ levelData.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texImage3D(
+ gl.TEXTURE_2D_ARRAY, ndx, this.m_internalFormat, levelW, levelH,
+ this.m_numLayers, 0, transferFmt.format,
+ transferFmt.dataType, levelData.getAccess().getDataPtr()
+ );
+ }
+ };
+
+ // Basic TexImage3D() with 3D texture usage
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} depth
+ */
+ es3fTextureSpecificationTests.BasicTexImage3DCase = function(
+ name, desc, internalFormat, width, height, depth
+ ) {
+ es3fTextureSpecificationTests.Texture3DSpecCase.call(
+ this, name, desc,
+ gluTextureUtil.mapGLInternalFormat(internalFormat), width, height,
+ depth, es3fTextureSpecificationTests.maxLevelCount(
+ width, height, depth
+ )
+ );
+
+ this.m_internalFormat = internalFormat;
+ };
+
+ es3fTextureSpecificationTests.BasicTexImage3DCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture3DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ BasicTexImage3DCase.prototype.constructor =
+ es3fTextureSpecificationTests.BasicTexImage3DCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ BasicTexImage3DCase.prototype.createTexture =
+ function() {
+ var tex = null;
+ var levelData = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_width, this.m_height
+ );
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+ var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_3D, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+ var levelD = Math.max(1, this.m_depth >> ndx);
+
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ levelData.setSize(levelW, levelH, levelD);
+ tcuTextureUtil.fillWithComponentGradients(
+ levelData.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texImage3D(
+ gl.TEXTURE_3D, ndx, this.m_internalFormat, levelW, levelH,
+ levelD, 0, transferFmt.format, transferFmt.dataType,
+ levelData.getAccess().getDataPtr()
+ );
+ }
+ };
+
+ // Randomized 2D texture specification using TexImage2D
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} width
+ * @param {number} height
+ */
+ es3fTextureSpecificationTests.RandomOrderTexImage2DCase = function(
+ name, desc, format, dataType, width, height
+ ) {
+ // Unsized internal format.
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ format, dataType
+ ), width, height,
+ es3fTextureSpecificationTests.maxLevelCount(
+ width, height
+ )
+ );
+
+ this.m_internalFormat = format;
+ this.m_format = format;
+ this.m_dataType = dataType;
+ };
+
+ es3fTextureSpecificationTests.RandomOrderTexImage2DCase.prototype = Object.create(
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ RandomOrderTexImage2DCase.prototype.constructor =
+ es3fTextureSpecificationTests.RandomOrderTexImage2DCase;
+
+ /**
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @return {es3fTextureSpecificationTests.RandomOrderTexImage2DCase}
+ */
+ es3fTextureSpecificationTests.newRandomOrderTexImage2DCaseInternal =
+ function(name, desc, internalFormat, width, height) {
+ // Sized internal format.
+ var fmt = gluTextureUtil.getTransferFormat(
+ gluTextureUtil.mapGLInternalFormat(internalFormat)
+ );
+ var testcase = new es3fTextureSpecificationTests.RandomOrderTexImage2DCase(
+ name, desc, fmt.format, fmt.dataType, width, height
+ );
+ testcase.m_internalFormat = internalFormat;
+ return testcase;
+ };
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ RandomOrderTexImage2DCase.prototype.createTexture = function() {
+ var tex = null;
+ var levelData = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_width, this.m_height
+ );
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ var levels = [];
+ for (var i = 0; i < this.m_numLevels; i++)
+ levels[i] = i;
+ levels = rnd.shuffle(levels);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelNdx = levels[ndx];
+ var levelW = Math.max(1, this.m_width >> levelNdx);
+ var levelH = Math.max(1, this.m_height >> levelNdx);
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ levelData.setSize(levelW, levelH);
+ tcuTextureUtil.fillWithComponentGradients(
+ levelData.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texImage2D(
+ gl.TEXTURE_2D, levelNdx, this.m_internalFormat, levelW, levelH, 0,
+ this.m_format, this.m_dataType,
+ levelData.getAccess().getDataPtr()
+ );
+ }
+ };
+
+ // Randomized cubemap texture specification using TexImage2D
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} size
+ */
+ es3fTextureSpecificationTests.RandomOrderTexImageCubeCase = function(
+ name, desc, format, dataType, size
+ ) {
+ // Unsized internal format.
+ es3fTextureSpecificationTests.TextureCubeSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ format, dataType
+ ), size, deMath.logToFloor(size) + 1
+ );
+
+ this.m_internalFormat = format;
+ this.m_format = format;
+ this.m_dataType = dataType;
+ };
+
+ es3fTextureSpecificationTests.RandomOrderTexImageCubeCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ RandomOrderTexImageCubeCase.prototype.constructor =
+ es3fTextureSpecificationTests.RandomOrderTexImageCubeCase;
+
+ /**
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} size
+ * @return {es3fTextureSpecificationTests.RandomOrderTexImageCubeCase}
+ */
+ es3fTextureSpecificationTests.newRandomOrderTexImageCubeCaseInternal =
+ function(name, desc, internalFormat, size) {
+ // Sized internal format.
+ var fmt = gluTextureUtil.getTransferFormat(
+ gluTextureUtil.mapGLInternalFormat(internalFormat)
+ );
+ var testcase = new es3fTextureSpecificationTests.RandomOrderTexImageCubeCase(
+ name, desc, fmt.format, fmt.dataType, size
+ );
+ testcase.m_internalFormat = internalFormat;
+ return testcase;
+ };
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ RandomOrderTexImageCubeCase.prototype.createTexture =
+ function() {
+ var tex = null;
+ var levelData = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_size, this.m_size
+ );
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ // Level-face pairs.
+ var images = [];
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++)
+ for (var f in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[f];
+ images[ndx * 6 + face] = {ndx: ndx, face: face};
+ }
+
+ images = rnd.shuffle(images);
+
+ for (var ndx = 0; ndx < images.length; ndx++) {
+ var levelNdx = images[ndx].ndx;
+ /** @type {framework.common.tcuTexture.CubeFace} */
+ var face = images[ndx].face;
+ var levelSize = Math.max(1, this.m_size >> levelNdx);
+
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ levelData.setSize(levelSize, levelSize);
+ tcuTextureUtil.fillWithComponentGradients(
+ levelData.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[face],
+ levelNdx, this.m_internalFormat, levelSize, levelSize, 0,
+ this.m_format, this.m_dataType,
+ levelData.getAccess().getDataPtr()
+ );
+ }
+ };
+
+ // TexImage2D() unpack alignment case.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} width
+ * @param {number} height
+ * @param {number} numLevels
+ * @param {number} alignment
+ */
+ es3fTextureSpecificationTests.TexImage2DAlignCase = function(
+ name, desc, format, dataType, width, height, numLevels, alignment
+ ) {
+ // Unsized internal format.
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ format, dataType
+ ), width, height, numLevels
+ );
+
+ this.m_internalFormat = format;
+ this.m_format = format;
+ this.m_dataType = dataType;
+ this.m_alignment = alignment;
+ };
+
+ es3fTextureSpecificationTests.TexImage2DAlignCase.prototype = Object.create(
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexImage2DAlignCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexImage2DAlignCase;
+
+ /**
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} numLevels
+ * @param {number} alignment
+ * @return {es3fTextureSpecificationTests.TexImage2DAlignCase}
+ */
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal = function(
+ name, desc, internalFormat, width, height, numLevels, alignment
+ ) {
+ // Sized internal format.
+ var fmt = gluTextureUtil.getTransferFormat(
+ gluTextureUtil.mapGLInternalFormat(internalFormat)
+ );
+ var testcase = new es3fTextureSpecificationTests.TexImage2DAlignCase(
+ name, desc, fmt.format, fmt.dataType,
+ width, height, numLevels, alignment
+ );
+ testcase.m_internalFormat = internalFormat;
+ return testcase;
+ };
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.TexImage2DAlignCase.prototype.createTexture =
+ function() {
+ var tex = null;
+ /** @type {ArrayBuffer} */ var data;
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+ var colorA = deMath.add(
+ deMath.multiply(
+ [1.0, 0.0, 0.0, 1.0],
+ deMath.subtract(
+ this.m_texFormatInfo.valueMax,
+ this.m_texFormatInfo.valueMin
+ )
+ ), this.m_texFormatInfo.valueMin
+ );
+ var colorB = deMath.add(
+ deMath.multiply(
+ [0.0, 1.0, 0.0, 1.0],
+ deMath.subtract(
+ this.m_texFormatInfo.valueMax,
+ this.m_texFormatInfo.valueMin
+ )
+ ), this.m_texFormatInfo.valueMin
+ );
+
+ var rowPitch = deMath.deAlign32(
+ levelW * this.m_texFormat.getPixelSize(), this.m_alignment
+ );
+ var cellSize = Math.max(1, Math.min(levelW >> 2, levelH >> 2));
+ data = new ArrayBuffer(rowPitch * levelH);
+ var access = new tcuTexture.PixelBufferAccess({format: this.m_texFormat, width: levelW,
+ height: levelH, rowPitch: rowPitch, data: data}
+ );
+ tcuTextureUtil.fillWithGrid(access, cellSize, colorA, colorB
+ );
+
+ this.m_context.texImage2D(
+ gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
+ this.m_format, this.m_dataType,
+ access.getDataPtr()
+ );
+ }
+ };
+
+ // TexImageCube unpack alignment case.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} size
+ * @param {number} numLevels
+ * @param {number} alignment
+ */
+ es3fTextureSpecificationTests.TexImageCubeAlignCase = function(
+ name, desc, format, dataType, size, numLevels, alignment
+ ) {
+ // Unsized internal format.
+ es3fTextureSpecificationTests.TextureCubeSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ format, dataType
+ ), size, numLevels
+ );
+
+ this.m_internalFormat = format;
+ this.m_format = format;
+ this.m_dataType = dataType;
+ this.m_alignment = alignment;
+ };
+
+ es3fTextureSpecificationTests.TexImageCubeAlignCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexImageCubeAlignCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexImageCubeAlignCase;
+
+ /**
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} size
+ * @param {number} numLevels
+ * @param {number} alignment
+ * @return {es3fTextureSpecificationTests.TexImageCubeAlignCase}
+ */
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal =
+ function(name, desc, internalFormat, size, numLevels, alignment) {
+ // Sized internal format.
+ var fmt = gluTextureUtil.getTransferFormat(
+ gluTextureUtil.mapGLInternalFormat(internalFormat)
+ );
+ var testcase = new es3fTextureSpecificationTests.TexImageCubeAlignCase(
+ name, desc, fmt.format, fmt.dataType, size, numLevels, alignment
+ );
+ testcase.m_internalFormat = internalFormat;
+ return testcase;
+ };
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexImageCubeAlignCase.prototype.createTexture =
+ function() {
+ var tex = null;
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+ /** @type {ArrayBuffer} */ var data;
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelSize = Math.max(1, this.m_size >> ndx);
+ var cellSize = Math.max(1, levelSize >> 2);
+ var rowPitch = deMath.deAlign32(
+ this.m_texFormat.getPixelSize() * levelSize, this.m_alignment
+ );
+ var colorA = deMath.add(deMath.multiply(
+ [1.0, 0.0, 0.0, 1.0], deMath.subtract(
+ this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin
+ )), this.m_texFormatInfo.valueMin
+ );
+ var colorB = deMath.add(deMath.multiply(
+ [0.0, 1.0, 0.0, 1.0], deMath.subtract(
+ this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin
+ )), this.m_texFormatInfo.valueMin
+ );
+
+ data = new ArrayBuffer(rowPitch * levelSize);
+ var access = new tcuTexture.PixelBufferAccess({format: this.m_texFormat, width: levelSize,
+ height: levelSize, rowPitch: rowPitch, data: data}
+ );
+ tcuTextureUtil.fillWithGrid(access, cellSize, colorA, colorB
+ );
+
+ for (var f in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[f];
+ this.m_context.texImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[face],
+ ndx, this.m_internalFormat, levelSize, levelSize, 0,
+ this.m_format, this.m_dataType,
+ access.getDataPtr()
+ );
+ }
+ }
+ };
+
+ // TexImage2D() unpack parameters case.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} rowLength
+ * @param {number} skipRows
+ * @param {number} skipPixels
+ * @param {number} alignment
+ */
+ es3fTextureSpecificationTests.TexImage2DParamsCase = function(
+ name, desc, internalFormat, width, height, rowLength, skipRows,
+ skipPixels, alignment
+ ) {
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc,
+ gluTextureUtil.mapGLInternalFormat(internalFormat),
+ width, height, 1
+ );
+ this.m_internalFormat = internalFormat;
+ this.m_rowLength = rowLength;
+ this.m_skipRows = skipRows;
+ this.m_skipPixels = skipPixels;
+ this.m_alignment = alignment;
+ };
+
+ es3fTextureSpecificationTests.TexImage2DParamsCase.prototype =
+ Object.create(es3fTextureSpecificationTests.Texture2DSpecCase.prototype);
+
+ es3fTextureSpecificationTests.TexImage2DParamsCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexImage2DParamsCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.TexImage2DParamsCase.prototype.createTexture =
+ function() {
+ var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
+ var pixelSize = this.m_texFormat.getPixelSize();
+ var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_width;
+ var rowPitch = deMath.deAlign32(rowLength * pixelSize, this.m_alignment);
+ var height = this.m_height + this.m_skipRows;
+ var tex = null;
+ /** @type {ArrayBuffer} */ var data;
+
+ assertMsgOptions(
+ this.m_numLevels == 1, 'Number of levels different to 1',
+ false, true
+ );
+
+ // Fill data with grid.
+ data = new ArrayBuffer(rowPitch * height + this.m_skipPixels * pixelSize);
+
+ var cScale = deMath.subtract(
+ this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin
+ );
+ var cBias = this.m_texFormatInfo.valueMin;
+ var colorA = deMath.add(
+ deMath.multiply(
+ [1.0, 0.0, 0.0, 1.0], cScale
+ ), cBias
+ );
+ var colorB = deMath.add(
+ deMath.multiply(
+ [0.0, 1.0, 0.0, 1.0], cScale
+ ), cBias
+ );
+
+ var accessWithOffset = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_width,
+ height: this.m_height,
+ rowPitch: rowPitch,
+ data: data,
+ offset: this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize
+ });
+ tcuTextureUtil.fillWithGrid(accessWithOffset, 4, colorA, colorB
+ );
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_width,
+ height: this.m_height,
+ rowPitch: rowPitch,
+ data: data,
+ });
+
+ this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+ this.m_context.texImage2D(
+ gl.TEXTURE_2D, 0, this.m_internalFormat,
+ this.m_width, this.m_height, 0,
+ transferFmt.format, transferFmt.dataType, access.getDataPtr()
+ );
+ };
+
+ // TexImage3D() unpack parameters case.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} depth
+ * @param {number} imageHeight
+ * @param {number} rowLength
+ * @param {number} skipImages
+ * @param {number} skipRows
+ * @param {number} skipPixels
+ * @param {number} alignment
+ */
+ es3fTextureSpecificationTests.TexImage3DParamsCase = function(
+ name, desc, internalFormat, width, height, depth, imageHeight,
+ rowLength, skipImages, skipRows, skipPixels, alignment
+ ) {
+ es3fTextureSpecificationTests.Texture3DSpecCase.call(
+ this, name, desc,
+ gluTextureUtil.mapGLInternalFormat(internalFormat),
+ width, height, depth, 1
+ );
+
+ this.m_internalFormat = internalFormat;
+ this.m_imageHeight = imageHeight;
+ this.m_rowLength = rowLength;
+ this.m_skipImages = skipImages;
+ this.m_skipRows = skipRows;
+ this.m_skipPixels = skipPixels;
+ this.m_alignment = alignment;
+ };
+
+ es3fTextureSpecificationTests.TexImage3DParamsCase.prototype =
+ Object.create(es3fTextureSpecificationTests.Texture3DSpecCase.prototype);
+
+ es3fTextureSpecificationTests.TexImage3DParamsCase.prototype.constructor =
+ es3fTextureSpecificationTests.Texture3DSpecCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.TexImage3DParamsCase.prototype.createTexture =
+ function() {
+ var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
+ var pixelSize = this.m_texFormat.getPixelSize();
+ var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_width;
+ var rowPitch = deMath.deAlign32(rowLength * pixelSize, this.m_alignment);
+ var imageHeight = this.m_imageHeight > 0 ?
+ this.m_imageHeight : this.m_height;
+ var slicePitch = imageHeight * rowPitch;
+
+ var tex = null;
+ /** @type {ArrayBuffer} */ var data;
+
+ assertMsgOptions(
+ this.m_numLevels == 1, 'Number of levels different to 1',
+ false, true
+ );
+
+ // Fill data with grid.
+ data = new ArrayBuffer(slicePitch * (this.m_depth + this.m_skipImages) +
+ this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize);
+
+ var cScale = deMath.subtract(
+ this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin
+ );
+ var cBias = this.m_texFormatInfo.valueMin;
+ var colorA = deMath.add(
+ deMath.multiply(
+ [1.0, 0.0, 0.0, 1.0], cScale
+ ), cBias
+ );
+ var colorB = deMath.add(
+ deMath.multiply(
+ [0.0, 1.0, 0.0, 1.0], cScale
+ ), cBias
+ );
+
+ var accessWithOffset = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_width,
+ height: this.m_height,
+ depth: this.m_depth,
+ rowPitch: rowPitch,
+ slicePitch: slicePitch,
+ data: data,
+ offset: this.m_skipImages * slicePitch + this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize
+ });
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_width,
+ height: this.m_height,
+ depth: this.m_depth,
+ rowPitch: rowPitch,
+ slicePitch: slicePitch,
+ data: data
+ });
+ tcuTextureUtil.fillWithGrid(
+ accessWithOffset, 4, colorA, colorB
+ );
+
+ this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, this.m_imageHeight);
+ this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, this.m_skipImages);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_3D, tex);
+ this.m_context.texImage3D(
+ gl.TEXTURE_3D, 0, this.m_internalFormat,
+ this.m_width, this.m_height, this.m_depth, 0,
+ transferFmt.format, transferFmt.dataType, access.getDataPtr()
+ );
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} width
+ * @param {number} height
+ */
+ es3fTextureSpecificationTests.BasicTexSubImage2DCase = function(
+ name, desc, format, dataType, width, height
+ ) {
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ format, dataType
+ ), width, height, es3fTextureSpecificationTests.maxLevelCount(
+ width, height
+ )
+ );
+
+ this.m_format = format;
+ this.m_internalFormat = format;
+ this.m_dataType = dataType;
+ };
+
+ es3fTextureSpecificationTests.BasicTexSubImage2DCase.prototype =
+ Object.create(es3fTextureSpecificationTests.Texture2DSpecCase.prototype);
+
+ es3fTextureSpecificationTests.BasicTexSubImage2DCase.prototype.constructor =
+ es3fTextureSpecificationTests.BasicTexSubImage2DCase;
+
+ /**
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @return {es3fTextureSpecificationTests.BasicTexSubImage2DCase}
+ */
+ es3fTextureSpecificationTests.newBasicTexSubImage2DCaseInternal =
+ function(name, desc, internalFormat, width, height) {
+ // Sized internal format.
+ var fmt = gluTextureUtil.getTransferFormat(
+ gluTextureUtil.mapGLInternalFormat(internalFormat)
+ );
+ var testcase = new es3fTextureSpecificationTests.BasicTexSubImage2DCase(
+ name, desc, fmt.format, fmt.dataType, width, height
+ );
+ testcase.m_internalFormat = internalFormat;
+ return testcase;
+ };
+
+ /**
+ */
+ es3fTextureSpecificationTests.
+ BasicTexSubImage2DCase.prototype.createTexture = function() {
+ var tex = null;
+ var data = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_width, this.m_height
+ );
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ data.setSize(levelW, levelH);
+ tcuTextureUtil.fillWithComponentGradients(
+ data.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texImage2D(
+ gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
+ this.m_format, this.m_dataType,
+ data.getAccess().getDataPtr()
+ );
+ }
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+
+ var w = rnd.getInt(1, levelW);
+ var h = rnd.getInt(1, levelH);
+ var x = rnd.getInt(0, levelW - w);
+ var y = rnd.getInt(0, levelH - h);
+
+ var colorA = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var colorB = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var cellSize = rnd.getInt(2, 16);
+
+ data.setSize(w, h);
+ tcuTextureUtil.fillWithGrid(
+ data.getAccess(), cellSize, colorA, colorB
+ );
+
+ this.m_context.texSubImage2D(
+ gl.TEXTURE_2D, ndx, x, y, w, h, this.m_format, this.m_dataType,
+ data.getAccess().getDataPtr()
+ );
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} size
+ */
+ es3fTextureSpecificationTests.BasicTexSubImageCubeCase = function(
+ name, desc, format, dataType, size
+ ) {
+ es3fTextureSpecificationTests.TextureCubeSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ format, dataType
+ ), size, deMath.logToFloor(size) + 1
+ );
+
+ this.m_internalFormat = format;
+ this.m_format = format;
+ this.m_dataType = dataType;
+ };
+
+ es3fTextureSpecificationTests.BasicTexSubImageCubeCase.prototype =
+ Object.create(es3fTextureSpecificationTests.TextureCubeSpecCase.prototype);
+
+ es3fTextureSpecificationTests.
+ BasicTexSubImageCubeCase.prototype.constructor =
+ es3fTextureSpecificationTests.BasicTexSubImageCubeCase;
+
+ /**
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} size
+ */
+ es3fTextureSpecificationTests.newBasicTexSubImageCubeCaseInternal =
+ function(name, desc, internalFormat, size) {
+ // Sized internal format.
+ var fmt = gluTextureUtil.getTransferFormat(
+ gluTextureUtil.mapGLInternalFormat(internalFormat)
+ );
+ var testcase =
+ new es3fTextureSpecificationTests.BasicTexSubImageCubeCase(
+ name, desc, fmt.format, fmt.dataType,
+ size);
+ testcase.m_internalFormat = internalFormat;
+ return testcase;
+ };
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ BasicTexSubImageCubeCase.prototype.createTexture = function() {
+ var tex = null;
+ var data = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_size, this.m_size
+ );
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelSize = Math.max(1, this.m_size >> ndx);
+ data.setSize(levelSize, levelSize);
+
+ for (var face = /** @type {tcuTexture.CubeFace} */ (0);
+ face < es3fTextureSpecificationTests.s_cubeMapFaces.length;
+ face++) {
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ tcuTextureUtil.fillWithComponentGradients(
+ data.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[face], ndx,
+ this.m_internalFormat, levelSize, levelSize, 0,
+ this.m_format, this.m_dataType,
+ data.getAccess().getDataPtr()
+ );
+ }
+ }
+
+ // Re-specify parts of each face and level.
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelSize = Math.max(1, this.m_size >> ndx);
+
+ for (var f in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[f];
+
+ var w = rnd.getInt(1, levelSize);
+ var h = rnd.getInt(1, levelSize);
+ var x = rnd.getInt(0, levelSize - w);
+ var y = rnd.getInt(0, levelSize - h);
+
+ var colorA = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var colorB = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var cellSize = rnd.getInt(2, 16);
+
+ data.setSize(w, h);
+ tcuTextureUtil.fillWithGrid(
+ data.getAccess(), cellSize, colorA, colorB
+ );
+
+ this.m_context.texSubImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[face],
+ ndx, x, y, w, h, this.m_format,
+ this.m_dataType, data.getAccess().getDataPtr()
+ );
+ }
+ }
+ };
+
+ // TexSubImage2D() unpack parameters case.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} subX
+ * @param {number} subY
+ * @param {number} subW
+ * @param {number} subH
+ * @param {number} rowLength
+ * @param {number} skipRows
+ * @param {number} skipPixels
+ * @param {number} alignment
+ */
+ es3fTextureSpecificationTests.TexSubImage2DParamsCase = function(
+ name, desc, internalFormat, width, height, subX, subY, subW, subH,
+ rowLength, skipRows, skipPixels, alignment
+ ) {
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc,
+ gluTextureUtil.mapGLInternalFormat(internalFormat),
+ width, height, 1
+ );
+ this.m_internalFormat = internalFormat;
+ this.m_subX = subX;
+ this.m_subY = subY;
+ this.m_subW = subW;
+ this.m_subH = subH;
+ this.m_rowLength = rowLength;
+ this.m_skipRows = skipRows;
+ this.m_skipPixels = skipPixels;
+ this.m_alignment = alignment;
+ };
+
+ es3fTextureSpecificationTests.TexSubImage2DParamsCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexSubImage2DParamsCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexSubImage2DParamsCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexSubImage2DParamsCase.prototype.createTexture = function() {
+ var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
+ var pixelSize = this.m_texFormat.getPixelSize();
+ var tex = null;
+ /** @type {ArrayBuffer} */ var data;
+
+ assertMsgOptions(
+ this.m_numLevels == 1, 'Number of levels different to 1',
+ false, true
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+
+ // First fill texture with gradient.
+ data = new ArrayBuffer(
+ deMath.deAlign32(this.m_width * pixelSize, 4) * this.m_height
+ );
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_width,
+ height: this.m_height,
+ rowPitch: deMath.deAlign32(this.m_width * pixelSize, 4),
+ data: data
+ });
+ tcuTextureUtil.fillWithComponentGradients(access, this.m_texFormatInfo.valueMin, this.m_texFormatInfo.valueMax
+ );
+ this.m_context.texImage2D(
+ gl.TEXTURE_2D, 0, this.m_internalFormat, this.m_width,
+ this.m_height, 0, transferFmt.format, transferFmt.dataType,
+ access.getDataPtr()
+ );
+
+ // Fill data with grid.
+ var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
+ var rowPitch = deMath.deAlign32(rowLength * pixelSize, this.m_alignment);
+ var height = this.m_subH + this.m_skipRows;
+ var cScale = deMath.subtract(
+ this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin
+ );
+ var cBias = this.m_texFormatInfo.valueMin;
+ var colorA = deMath.add(
+ deMath.multiply(
+ [1.0, 0.0, 0.0, 1.0], cScale
+ ), cBias
+ );
+ var colorB = deMath.add(
+ deMath.multiply(
+ [0.0, 1.0, 0.0, 1.0], cScale
+ ), cBias
+ );
+
+ data = new ArrayBuffer(rowPitch * height + this.m_skipPixels * pixelSize);
+ tcuTextureUtil.fillWithGrid(
+ new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_subW,
+ height: this.m_subH,
+ rowPitch: rowPitch,
+ data: data,
+ offset: this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize
+ }) ,
+ 4, colorA, colorB
+ );
+
+ access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_subW,
+ height: this.m_subH,
+ rowPitch: rowPitch,
+ data: data
+ });
+ this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+ this.m_context.texSubImage2D(
+ gl.TEXTURE_2D, 0, this.m_subX, this.m_subY,
+ this.m_subW, this.m_subH,
+ transferFmt.format, transferFmt.dataType,
+ access.getDataPtr()
+ );
+ };
+
+ // Basic TexSubImage3D() with 3D texture usage
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} depth
+ */
+ es3fTextureSpecificationTests.BasicTexSubImage3DCase = function(
+ name, desc, internalFormat, width, height, depth
+ ) {
+ es3fTextureSpecificationTests.Texture3DSpecCase.call(
+ this, name, desc,
+ gluTextureUtil.mapGLInternalFormat(internalFormat),
+ width, height, depth, es3fTextureSpecificationTests.maxLevelCount(
+ width, height, depth
+ )
+ );
+
+ this.m_internalFormat = internalFormat;
+ };
+
+ es3fTextureSpecificationTests.BasicTexSubImage3DCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture3DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.BasicTexSubImage3DCase.prototype.constructor =
+ es3fTextureSpecificationTests.BasicTexSubImage3DCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ BasicTexSubImage3DCase.prototype.createTexture = function() {
+ var tex = null;
+ var data = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_width, this.m_height
+ );
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+ var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_3D, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ // First specify full texture.
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+ var levelD = Math.max(1, this.m_depth >> ndx);
+
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ data.setSize(levelW, levelH, levelD);
+ tcuTextureUtil.fillWithComponentGradients(
+ data.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texImage3D(
+ gl.TEXTURE_3D, ndx, this.m_internalFormat, levelW, levelH,
+ levelD, 0, transferFmt.format, transferFmt.dataType,
+ data.getAccess().getDataPtr()
+ );
+ }
+
+ // Re-specify parts of each level.
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+ var levelD = Math.max(1, this.m_depth >> ndx);
+
+ var w = rnd.getInt(1, levelW);
+ var h = rnd.getInt(1, levelH);
+ var d = rnd.getInt(1, levelD);
+ var x = rnd.getInt(0, levelW - w);
+ var y = rnd.getInt(0, levelH - h);
+ var z = rnd.getInt(0, levelD - d);
+
+ var colorA = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var colorB = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var cellSize = rnd.getInt(2, 16);
+
+ data.setSize(w, h, d);
+ tcuTextureUtil.fillWithGrid(
+ data.getAccess(), cellSize, colorA, colorB
+ );
+
+ this.m_context.texSubImage3D(
+ gl.TEXTURE_3D, ndx, x, y, z, w, h, d,
+ transferFmt.format, transferFmt.dataType,
+ data.getAccess().getDataPtr()
+ );
+ }
+ };
+
+ // TexSubImage2D() to texture initialized with empty data
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} width
+ * @param {number} height
+ */
+ es3fTextureSpecificationTests.TexSubImage2DEmptyTexCase = function(
+ name, desc, format, dataType, width, height
+ ) {
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ format, dataType
+ ), width, height, es3fTextureSpecificationTests.maxLevelCount(
+ width, height
+ )
+ );
+
+ this.m_format = format;
+ this.m_internalFormat = format;
+ this.m_dataType = dataType;
+ };
+
+ es3fTextureSpecificationTests.TexSubImage2DEmptyTexCase.prototype =
+ Object.create(es3fTextureSpecificationTests.Texture2DSpecCase.prototype);
+
+ es3fTextureSpecificationTests.
+ TexSubImage2DEmptyTexCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexSubImage2DEmptyTexCase;
+
+ /**
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ */
+ es3fTextureSpecificationTests.newTexSubImage2DEmptyTexCaseInternal =
+ function(name, desc, internalFormat, width, height) {
+ // Sized internal format.
+ var fmt = gluTextureUtil.getTransferFormat(
+ gluTextureUtil.mapGLInternalFormat(internalFormat)
+ );
+ var testcase =
+ new es3fTextureSpecificationTests.TexSubImage2DEmptyTexCase(
+ name, desc, fmt.format, fmt.dataType, width, height
+ );
+ testcase.m_internalFormat = internalFormat;
+ return testcase;
+ };
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexSubImage2DEmptyTexCase.prototype.createTexture = function() {
+ var tex = null;
+ var data = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_width, this.m_height
+ );
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ // First allocate storage for each level.
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+
+ this.m_context.texImage2D(
+ gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
+ this.m_format, this.m_dataType,
+ null
+ );
+ }
+
+ // Specify pixel data to all levels using glTexSubImage2D()
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ data.setSize(levelW, levelH);
+ tcuTextureUtil.fillWithComponentGradients(
+ data.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texSubImage2D(
+ gl.TEXTURE_2D, ndx, 0, 0, levelW, levelH,
+ this.m_format, this.m_dataType,
+ data.getAccess().getDataPtr()
+ );
+ }
+ };
+
+ // TexSubImage2D() to empty cubemap texture
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} size
+ */
+ es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase = function(
+ name, desc, format, dataType, size
+ ) {
+ // Unsized internal format.
+ es3fTextureSpecificationTests.TextureCubeSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ format, dataType
+ ), size, deMath.logToFloor(size) + 1
+ );
+
+ this.m_internalFormat = format;
+ this.m_format = format;
+ this.m_dataType = dataType;
+ };
+
+ es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexSubImageCubeEmptyTexCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase;
+
+ /**
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} size
+ * @return {es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase}
+ */
+ es3fTextureSpecificationTests.newTexSubImageCubeEmptyTexCaseInternal =
+ function(name, desc, internalFormat, size) {
+ // Sized internal format.
+ var fmt = gluTextureUtil.getTransferFormat(
+ gluTextureUtil.mapGLInternalFormat(internalFormat)
+ );
+ var testcase =
+ new es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase(
+ name, desc, fmt.format, fmt.dataType, size
+ );
+ testcase.m_internalFormat = internalFormat;
+ return testcase;
+ };
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexSubImageCubeEmptyTexCase.prototype.createTexture =
+ function() {
+ var tex = null;
+ var data = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_size, this.m_size
+ );
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ // Specify storage for each level.
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelSize = Math.max(1, this.m_size >> ndx);
+
+ for (var f in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[f];
+ this.m_context.texImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[face],
+ ndx, this.m_internalFormat, levelSize, levelSize, 0,
+ this.m_format, this.m_dataType,
+ null
+ );
+ }
+ }
+
+ // Specify data using glTexSubImage2D()
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelSize = Math.max(1, this.m_size >> ndx);
+
+ data.setSize(levelSize, levelSize);
+
+ for (var f in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[f];
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ tcuTextureUtil.fillWithComponentGradients(
+ data.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texSubImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[face],
+ ndx, 0, 0, levelSize, levelSize, this.m_format,
+ this.m_dataType, data.getAccess().getDataPtr()
+ );
+ }
+ }
+ };
+
+ // TexSubImage2D() unpack alignment with 2D texture
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} width
+ * @param {number} height
+ * @param {number} subX
+ * @param {number} subY
+ * @param {number} subW
+ * @param {number} subH
+ * @param {number} alignment
+ */
+ es3fTextureSpecificationTests.TexSubImage2DAlignCase = function(
+ name, desc, format, dataType, width, height, subX, subY, subW, subH,
+ alignment
+ ) {
+ // Unsized internal format.
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ format, dataType
+ ), width, height, 1
+ );
+
+ this.m_internalFormat = format;
+ this.m_format = format;
+ this.m_dataType = dataType;
+ this.m_subX = subX;
+ this.m_subY = subY;
+ this.m_subW = subW;
+ this.m_subH = subH;
+ this.m_alignment = alignment;
+ };
+
+ es3fTextureSpecificationTests.TexSubImage2DAlignCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexSubImage2DAlignCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexSubImage2DAlignCase;
+
+ /**
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} subX
+ * @param {number} subY
+ * @param {number} subW
+ * @param {number} subH
+ * @param {number} alignment
+ * @return {es3fTextureSpecificationTests.TexSubImage2DAlignCase}
+ */
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal = function(
+ name, desc, internalFormat, width, height, subX, subY, subW, subH,
+ alignment
+ ) {
+ // Sized internal format.
+ var fmt = gluTextureUtil.getTransferFormat(
+ gluTextureUtil.mapGLInternalFormat(internalFormat)
+ );
+ var testcase = new es3fTextureSpecificationTests.TexSubImage2DAlignCase(
+ name, desc, fmt.format, fmt.dataType,
+ width, height, subX, subY, subW, subH, alignment
+ );
+ testcase.m_internalFormat = internalFormat;
+ return testcase;
+ };
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexSubImage2DAlignCase.prototype.createTexture = function() {
+ var tex = null;
+ /** @type {ArrayBuffer} */ var data;
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+
+ // Specify base level.
+ data = new ArrayBuffer(this.m_texFormat.getPixelSize() *
+ this.m_width * this.m_height
+ );
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_width,
+ height: this.m_height,
+ data: data
+ });
+ tcuTextureUtil.fillWithComponentGradients(access, [0, 0, 0, 0], [1, 1, 1, 1]);
+
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+ this.m_context.texImage2D(gl.TEXTURE_2D, 0, this.m_internalFormat,
+ this.m_width, this.m_height, 0, this.m_format, this.m_dataType,
+ access.getDataPtr()
+ );
+
+ // Re-specify subrectangle.
+ var rowPitch = deMath.deAlign32(
+ this.m_texFormat.getPixelSize() * this.m_subW, this.m_alignment
+ );
+ data = new ArrayBuffer(rowPitch * this.m_subH);
+ access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_subW,
+ height: this.m_subH,
+ rowPitch: rowPitch,
+ data: data
+ });
+ tcuTextureUtil.fillWithGrid(access, 4, [1, 0, 0, 1], [0, 1, 0, 1]
+ );
+
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+ this.m_context.texSubImage2D(
+ gl.TEXTURE_2D, 0, this.m_subX, this.m_subY, this.m_subW,
+ this.m_subH, this.m_format, this.m_dataType, access.getDataPtr()
+ );
+ };
+
+ // TexSubImage2D() unpack alignment with cubemap texture
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} size
+ * @param {number} subX
+ * @param {number} subY
+ * @param {number} subW
+ * @param {number} subH
+ * @param {number} alignment
+ */
+ es3fTextureSpecificationTests.TexSubImageCubeAlignCase = function(
+ name, desc, format, dataType, size, subX, subY, subW, subH, alignment
+ ) {
+ // Unsized internal format.
+ es3fTextureSpecificationTests.TextureCubeSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ format, dataType
+ ), size, 1
+ );
+
+ this.m_internalFormat = format;
+ this.m_format = format;
+ this.m_dataType = dataType;
+ this.m_subX = subX;
+ this.m_subY = subY;
+ this.m_subW = subW;
+ this.m_subH = subH;
+ this.m_alignment = alignment;
+ };
+
+ es3fTextureSpecificationTests.TexSubImageCubeAlignCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexSubImageCubeAlignCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexSubImageCubeAlignCase;
+
+ /**
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} size
+ * @param {number} subX
+ * @param {number} subY
+ * @param {number} subW
+ * @param {number} subH
+ * @param {number} alignment
+ * @return {es3fTextureSpecificationTests.TexSubImageCubeAlignCase}
+ */
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal =
+ function(
+ name, desc, internalFormat, size,
+ subX, subY, subW, subH, alignment
+ ) {
+ // Sized internal format.
+ var fmt = gluTextureUtil.getTransferFormat(
+ gluTextureUtil.mapGLInternalFormat(internalFormat)
+ );
+ var testcase =
+ new es3fTextureSpecificationTests.TexSubImageCubeAlignCase(
+ name, desc, fmt.format, fmt.dataType, size,
+ subX, subY, subW, subH, alignment
+ );
+ testcase.m_internalFormat = internalFormat;
+ return testcase;
+ };
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexSubImageCubeAlignCase.prototype.createTexture =
+ function() {
+ var tex = null;
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+
+ var data = new ArrayBuffer(this.m_texFormat.getPixelSize() * this.m_size * this.m_size);
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_size,
+ height: this.m_size,
+ data: data
+ });
+ tcuTextureUtil.fillWithComponentGradients(access, [0, 0, 0, 0], [1, 1, 1, 1]
+ );
+
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+ for (var f in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[f];
+ this.m_context.texImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[face],
+ 0, this.m_internalFormat, this.m_size, this.m_size, 0,
+ this.m_format, this.m_dataType,
+ access.getDataPtr()
+ );
+ }
+
+ // Re-specify subrectangle.
+ var rowPitch = deMath.deAlign32(
+ this.m_texFormat.getPixelSize() * this.m_subW, this.m_alignment
+ );
+ data = new ArrayBuffer(rowPitch * this.m_subH);
+ access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_subW,
+ height: this.m_subH,
+ rowPitch: rowPitch,
+ data: data
+ });
+ tcuTextureUtil.fillWithGrid(access, 4, [1, 0, 0, 1], [0, 1, 0, 1]
+ );
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+ for (var f in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[f];
+ this.m_context.texSubImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[face],
+ 0, this.m_subX, this.m_subY, this.m_subW, this.m_subH,
+ this.m_format, this.m_dataType, access.getDataPtr()
+ );
+ }
+ };
+
+ // TexSubImage3D() unpack parameters case.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} depth
+ * @param {number} subX ,
+ * @param {number} subY ,
+ * @param {number} subZ ,
+ * @param {number} subW ,
+ * @param {number} subH ,
+ * @param {number} subD ,
+ * @param {number} imageHeight ,
+ * @param {number} rowLength ,
+ * @param {number} skipImages ,
+ * @param {number} skipRows ,
+ * @param {number} skipPixels ,
+ * @param {number} alignment
+ */
+ es3fTextureSpecificationTests.TexSubImage3DParamsCase = function(
+ name, desc, internalFormat, width, height, depth,
+ subX, subY, subZ, subW, subH, subD,
+ imageHeight, rowLength, skipImages, skipRows, skipPixels, alignment
+ ) {
+ es3fTextureSpecificationTests.Texture3DSpecCase.call(
+ this, name, desc,
+ gluTextureUtil.mapGLInternalFormat(internalFormat),
+ width, height, depth, 1
+ );
+
+ this.m_internalFormat = internalFormat;
+ this.m_subX = subX;
+ this.m_subY = subY;
+ this.m_subZ = subZ;
+ this.m_subW = subW;
+ this.m_subH = subH;
+ this.m_subD = subD;
+ this.m_imageHeight = imageHeight;
+ this.m_rowLength = rowLength;
+ this.m_skipImages = skipImages;
+ this.m_skipRows = skipRows;
+ this.m_skipPixels = skipPixels;
+ this.m_alignment = alignment;
+ };
+
+ es3fTextureSpecificationTests.TexSubImage3DParamsCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture3DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexSubImage3DParamsCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexSubImage3DParamsCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexSubImage3DParamsCase.prototype.createTexture = function() {
+ var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
+ var pixelSize = this.m_texFormat.getPixelSize();
+ var tex = null;
+ var rowPitch = deMath.deAlign32(pixelSize * this.m_width, 4);
+ var slicePitch = rowPitch * this.m_height;
+ assertMsgOptions(
+ this.m_numLevels == 1, 'Numbel of levels different than 1',
+ false, true
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_3D, tex);
+
+ // Fill with gradient.
+
+ var data = new ArrayBuffer(slicePitch * this.m_depth);
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_width,
+ height: this.m_height,
+ depth: this.m_depth,
+ rowPitch: rowPitch,
+ slicePitch: slicePitch,
+ data: data
+ });
+ tcuTextureUtil.fillWithComponentGradients(access, this.m_texFormatInfo.valueMin, this.m_texFormatInfo.valueMax);
+
+ this.m_context.texImage3D(
+ gl.TEXTURE_3D, 0, this.m_internalFormat, this.m_width,
+ this.m_height, this.m_depth, 0, transferFmt.format,
+ transferFmt.dataType, access.getDataPtr()
+ );
+
+ // Fill data with grid.
+ var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
+ rowPitch = deMath.deAlign32(rowLength * pixelSize, this.m_alignment);
+ var imageHeight = this.m_imageHeight > 0 ? this.m_imageHeight : this.m_subH;
+ slicePitch = imageHeight * rowPitch;
+ var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
+ var cBias = this.m_texFormatInfo.valueMin;
+ var colorA = deMath.add(
+ deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
+ );
+ var colorB = deMath.add(
+ deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
+ );
+
+ data = new ArrayBuffer(slicePitch * (this.m_depth + this.m_skipImages) +
+ this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize);
+ var accessWithOffset = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_subW,
+ height: this.m_subH,
+ depth: this.m_subD,
+ rowPitch: rowPitch,
+ slicePitch: slicePitch,
+ data: data,
+ offset: this.m_skipImages * slicePitch + this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize
+ });
+ access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_subW,
+ height: this.m_subH,
+ depth: this.m_subD,
+ rowPitch: rowPitch,
+ slicePitch: slicePitch,
+ data: data
+ });
+ tcuTextureUtil.fillWithGrid(accessWithOffset, 4, colorA, colorB);
+
+ this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, this.m_imageHeight);
+ this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, this.m_skipImages);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+ this.m_context.texSubImage3D(
+ gl.TEXTURE_3D, 0, this.m_subX, this.m_subY, this.m_subZ,
+ this.m_subW, this.m_subH, this.m_subD,
+ transferFmt.format, transferFmt.dataType, access.getDataPtr()
+ );
+ };
+
+ // Basic CopyTexImage2D() with 2D texture usage
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ */
+ es3fTextureSpecificationTests.BasicCopyTexImage2DCase = function(
+ name, desc, internalFormat, width, height
+ ) {
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ internalFormat, gl.UNSIGNED_BYTE
+ ), width, height, es3fTextureSpecificationTests.maxLevelCount(
+ width, height
+ )
+ );
+
+ this.m_internalFormat = internalFormat;
+ };
+
+ es3fTextureSpecificationTests.BasicCopyTexImage2DCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ BasicCopyTexImage2DCase.prototype.constructor =
+ es3fTextureSpecificationTests.BasicCopyTexImage2DCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ BasicCopyTexImage2DCase.prototype.createTexture = function() {
+ var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
+ var targetHasRGB = pixelFormat.redBits > 0 &&
+ pixelFormat.greenBits > 0 &&
+ pixelFormat.blueBits > 0;
+ var targetHasAlpha = pixelFormat.alphaBits > 0;
+ var fmt = es3fTextureSpecificationTests.mapGLUnsizedInternalFormat(
+ this.m_internalFormat
+ );
+ var texHasRGB = fmt.order != tcuTexture.ChannelOrder.A;
+ var texHasAlpha = fmt.order == tcuTexture.ChannelOrder.RGBA ||
+ fmt.order == tcuTexture.ChannelOrder.LA ||
+ fmt.order == tcuTexture.ChannelOrder.A;
+ var tex = null;
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+ /** @type {es3fFboTestUtil.GradientShader} */
+ var shader = new es3fFboTestUtil.GradientShader(
+ gluShaderUtil.DataType.FLOAT_VEC4
+ );
+ var shaderID = this.m_context.createProgram(shader);
+
+ if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
+ throw new Error(
+ 'Copying from current framebuffer is not supported'
+ );
+
+ // Fill render target with gradient.
+ shader.setGradient(
+ this.m_context, shaderID, [0, 0, 0, 0], [1, 1, 1, 1]
+ );
+ rrUtil.drawQuad(
+ this.m_context, shaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+ var x = rnd.getInt(0, this.m_width - levelW);
+ var y = rnd.getInt(0, this.m_height - levelH);
+
+ this.m_context.copyTexImage2D(
+ gl.TEXTURE_2D, ndx, this.m_internalFormat, x, y,
+ levelW, levelH, 0
+ );
+ }
+ };
+
+ // Basic CopyTexImage2D() with cubemap usage
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} size
+ */
+ es3fTextureSpecificationTests.BasicCopyTexImageCubeCase = function(
+ name, desc, internalFormat, size
+ ) {
+ es3fTextureSpecificationTests.TextureCubeSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ internalFormat, gl.UNSIGNED_BYTE
+ ), size, deMath.logToFloor(size) + 1
+ );
+
+ this.m_internalFormat = internalFormat;
+ };
+
+ es3fTextureSpecificationTests.BasicCopyTexImageCubeCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ BasicCopyTexImageCubeCase.prototype.constructor =
+ es3fTextureSpecificationTests.BasicCopyTexImageCubeCase;
+
+ es3fTextureSpecificationTests.
+ BasicCopyTexImageCubeCase.prototype.createTexture = function() {
+ var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
+ var targetHasRGB = pixelFormat.redBits > 0 &&
+ pixelFormat.greenBits > 0 &&
+ pixelFormat.blueBits > 0;
+ var targetHasAlpha = pixelFormat.alphaBits > 0;
+ var fmt = es3fTextureSpecificationTests.mapGLUnsizedInternalFormat(
+ this.m_internalFormat
+ );
+ var texHasRGB = fmt.order != tcuTexture.ChannelOrder.A;
+ var texHasAlpha = fmt.order == tcuTexture.ChannelOrder.RGBA ||
+ fmt.order == tcuTexture.ChannelOrder.LA ||
+ fmt.order == tcuTexture.ChannelOrder.A;
+ var tex = null;
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+ /** @type {es3fFboTestUtil.GradientShader} */
+ var shader = new es3fFboTestUtil.GradientShader(
+ gluShaderUtil.DataType.FLOAT_VEC4
+ );
+ var shaderID = this.m_context.createProgram(shader);
+
+ if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
+ throw new Error(
+ 'Copying from current framebuffer is not supported'
+ );
+
+ // Fill render target with gradient.
+ shader.setGradient(
+ this.m_context, shaderID, [0, 0, 0, 0], [1, 1, 1, 1]
+ );
+ rrUtil.drawQuad(
+ this.m_context, shaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelSize = Math.max(1, this.m_size >> ndx);
+
+ for (var f in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[f];
+ var x = rnd.getInt(0, this.m_size - levelSize);
+ var y = rnd.getInt(0, this.m_size - levelSize);
+
+ this.m_context.copyTexImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[face], ndx,
+ this.m_internalFormat, x, y, levelSize, levelSize, 0
+ );
+ }
+ }
+ };
+
+ // Basic CopyTexSubImage2D() with 2D texture usage
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} width
+ * @param {number} height
+ */
+ es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase = function(
+ name, desc, format, dataType, width, height
+ ) {
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ format, dataType
+ ), width, height, es3fTextureSpecificationTests.maxLevelCount(
+ width, height
+ )
+ );
+
+ this.m_format = format;
+ this.m_dataType = dataType;
+ };
+
+ es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ BasicCopyTexSubImage2DCase.prototype.constructor =
+ es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ BasicCopyTexSubImage2DCase.prototype.createTexture = function() {
+ var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
+ var targetHasRGB = pixelFormat.redBits > 0 &&
+ pixelFormat.greenBits > 0 &&
+ pixelFormat.blueBits > 0;
+ var targetHasAlpha = pixelFormat.alphaBits > 0;
+ var fmt = gluTextureUtil.mapGLTransferFormat(
+ this.m_format, this.m_dataType
+ );
+ var texHasRGB = fmt.order != tcuTexture.ChannelOrder.A;
+ var texHasAlpha = fmt.order == tcuTexture.ChannelOrder.RGBA ||
+ fmt.order == tcuTexture.ChannelOrder.LA ||
+ fmt.order == tcuTexture.ChannelOrder.A;
+ var tex = null;
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+ /** @type {es3fFboTestUtil.GradientShader} */
+ var shader = new es3fFboTestUtil.GradientShader(
+ gluShaderUtil.DataType.FLOAT_VEC4
+ );
+ var shaderID = this.m_context.createProgram(shader);
+
+ if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
+ throw new Error(
+ 'Copying from current framebuffer is not supported'
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ // First specify full texture.
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+
+ var colorA = es3fTextureSpecificationTests.randomVector(
+ rnd, [0, 0, 0, 0], [1, 1, 1, 1], 4
+ );
+ var colorB = es3fTextureSpecificationTests.randomVector(
+ rnd, [0, 0, 0, 0], [1, 1, 1, 1], 4
+ );
+ var cellSize = rnd.getInt(2, 16);
+
+ var data = new tcuTexture.TextureLevel(fmt, levelW, levelH);
+ tcuTextureUtil.fillWithGrid(
+ data.getAccess(), cellSize, colorA, colorB
+ );
+
+ this.m_context.texImage2D(
+ gl.TEXTURE_2D, ndx, this.m_format, levelW, levelH, 0, this.m_format, this.m_dataType, data.getAccess().getDataPtr()
+ );
+ }
+
+ // Fill render target with gradient.
+ shader.setGradient(
+ this.m_context, shaderID, [0, 0, 0, 0], [1, 1, 1, 1]
+ );
+ rrUtil.drawQuad(
+ this.m_context, shaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+
+ // Re-specify parts of each level.
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+
+ var w = rnd.getInt(1, levelW);
+ var h = rnd.getInt(1, levelH);
+ var xo = rnd.getInt(0, levelW - w);
+ var yo = rnd.getInt(0, levelH - h);
+
+ var x = rnd.getInt(0, this.m_width - w);
+ var y = rnd.getInt(0, this.m_height - h);
+
+ this.m_context.copyTexSubImage2D(
+ gl.TEXTURE_2D, ndx, xo, yo, x, y, w, h
+ );
+ }
+ };
+
+ // Basic CopyTexSubImage2D() with cubemap usage
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} size
+ */
+ es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase = function(
+ name, desc, format, dataType, size
+ ) {
+ es3fTextureSpecificationTests.TextureCubeSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLTransferFormat(
+ format, dataType
+ ), size, deMath.logToFloor(size) + 1
+ );
+
+ this.m_format = format;
+ this.m_dataType = dataType;
+ };
+
+ es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ BasicCopyTexSubImageCubeCase.prototype.constructor =
+ es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase;
+
+ es3fTextureSpecificationTests.
+ BasicCopyTexSubImageCubeCase.prototype.createTexture = function() {
+ var pixelFormat = tcuPixelFormat.PixelFormatFromContext(gl);
+ var targetHasRGB = pixelFormat.redBits > 0 &&
+ pixelFormat.greenBits > 0 &&
+ pixelFormat.blueBits > 0;
+ var targetHasAlpha = pixelFormat.alphaBits > 0;
+ var fmt = gluTextureUtil.mapGLTransferFormat(this.m_format, this.m_dataType);
+ var texHasRGB = fmt.order != tcuTexture.ChannelOrder.A;
+ var texHasAlpha = fmt.order == tcuTexture.ChannelOrder.RGBA ||
+ fmt.order == tcuTexture.ChannelOrder.LA ||
+ fmt.order == tcuTexture.ChannelOrder.A;
+ var tex = null;
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+ /** @type {es3fFboTestUtil.GradientShader} */
+ var shader = new es3fFboTestUtil.GradientShader(
+ gluShaderUtil.DataType.FLOAT_VEC4
+ );
+ var shaderID = this.m_context.createProgram(shader);
+
+ if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
+ throw new Error(
+ 'Copying from current framebuffer is not supported'
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ var data = new tcuTexture.TextureLevel(fmt);
+
+ // First specify full texture.
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelSize = Math.max(1, this.m_size >> ndx);
+
+ data.setSize(levelSize, levelSize);
+
+ for (var f in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[f];
+ var colorA = es3fTextureSpecificationTests.randomVector(
+ rnd, [0, 0, 0, 0], [1, 1, 1, 1], 4
+ );
+ var colorB = es3fTextureSpecificationTests.randomVector(
+ rnd, [0, 0, 0, 0], [1, 1, 1, 1], 4
+ );
+ var cellSize = rnd.getInt(2, 16);
+
+ tcuTextureUtil.fillWithGrid(
+ data.getAccess(), cellSize, colorA, colorB
+ );
+
+ this.m_context.texImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[face],
+ ndx, this.m_format, levelSize, levelSize, 0, this.m_format,
+ this.m_dataType, data.getAccess().getDataPtr()
+ );
+ }
+ }
+
+ // Fill render target with gradient.
+ shader.setGradient(
+ this.m_context, shaderID, [0, 0, 0, 0], [1, 1, 1, 1]
+ );
+ rrUtil.drawQuad(
+ this.m_context, shaderID, [-1.0, -1.0, 0.0], [1.0, 1.0, 0.0]
+ );
+
+ // Re-specify parts of each face and level.
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelSize = Math.max(1, this.m_size >> ndx);
+
+ for (var f in es3fTextureSpecificationTests.s_cubeMapFaces) {
+ var w = rnd.getInt(1, levelSize);
+ var h = rnd.getInt(1, levelSize);
+ var xo = rnd.getInt(0, levelSize - w);
+ var yo = rnd.getInt(0, levelSize - h);
+
+ var x = rnd.getInt(0, this.m_size - w);
+ var y = rnd.getInt(0, this.m_size - h);
+
+ this.m_context.copyTexSubImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[f],
+ ndx, xo, yo, x, y, w, h
+ );
+ }
+ }
+ };
+
+ // Basic glTexStorage2D() with 2D texture usage
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} numLevels
+ */
+ es3fTextureSpecificationTests.BasicTexStorage2DCase = function(
+ name, desc, internalFormat, width, height, numLevels
+ ) {
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), width, height, numLevels
+ );
+
+ this.m_internalFormat = internalFormat;
+ };
+
+ es3fTextureSpecificationTests.BasicTexStorage2DCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.BasicTexStorage2DCase.prototype.constructor =
+ es3fTextureSpecificationTests.BasicTexStorage2DCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ BasicTexStorage2DCase.prototype.createTexture = function() {
+ var fmt = gluTextureUtil.mapGLInternalFormat(this.m_internalFormat);
+ var transferFmt = gluTextureUtil.getTransferFormat(fmt);
+ var tex = null;
+ var levelData = new tcuTexture.TextureLevel(
+ fmt, this.m_width, this.m_height
+ );
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+ this.m_context.texStorage2D(
+ gl.TEXTURE_2D, this.m_numLevels, this.m_internalFormat,
+ this.m_width, this.m_height
+ );
+
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ levelData.setSize(levelW, levelH);
+ tcuTextureUtil.fillWithComponentGradients(
+ levelData.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texSubImage2D(
+ gl.TEXTURE_2D, ndx, 0, 0, levelW, levelH,
+ transferFmt.format, transferFmt.dataType,
+ levelData.getAccess().getDataPtr()
+ );
+ }
+ };
+
+ // Basic glTexStorage2D() with cubemap usage
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} size
+ * @param {number} numLevels
+ */
+ es3fTextureSpecificationTests.BasicTexStorageCubeCase = function(
+ name, desc, internalFormat, size, numLevels
+ ) {
+ es3fTextureSpecificationTests.TextureCubeSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), size, numLevels
+ );
+
+ this.m_internalFormat = internalFormat;
+ };
+
+ es3fTextureSpecificationTests.BasicTexStorageCubeCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.BasicTexStorageCubeCase.prototype.constructor =
+ es3fTextureSpecificationTests.BasicTexStorageCubeCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.BasicTexStorageCubeCase.prototype.createTexture = function() {
+ var fmt = gluTextureUtil.mapGLInternalFormat(this.m_internalFormat);
+ var transferFmt = gluTextureUtil.getTransferFormat(fmt);
+ var tex = null;
+ var levelData = new tcuTexture.TextureLevel(
+ fmt, this.m_size, this.m_size
+ );
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ this.m_context.texStorage2D(
+ gl.TEXTURE_CUBE_MAP, this.m_numLevels, this.m_internalFormat,
+ this.m_size, this.m_size
+ );
+
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelSize = Math.max(1, this.m_size >> ndx);
+
+ levelData.setSize(levelSize, levelSize);
+
+ for (var f in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[f];
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ tcuTextureUtil.fillWithComponentGradients(
+ levelData.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texSubImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[face],
+ ndx, 0, 0, levelSize, levelSize,
+ transferFmt.format, transferFmt.dataType,
+ levelData.getAccess().getDataPtr()
+ );
+ }
+ }
+ };
+
+ // Basic glTexStorage3D() with 2D array texture usage
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} numLayers
+ * @param {number} numLevels
+ */
+ es3fTextureSpecificationTests.BasicTexStorage2DArrayCase = function(
+ name, desc, internalFormat, width, height, numLayers, numLevels
+ ) {
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), width, height, numLayers, numLevels
+ );
+ this.m_internalFormat = internalFormat;
+ };
+
+ es3fTextureSpecificationTests.BasicTexStorage2DArrayCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ BasicTexStorage2DArrayCase.prototype.constructor =
+ es3fTextureSpecificationTests.BasicTexStorage2DArrayCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.BasicTexStorage2DArrayCase.prototype.createTexture = function() {
+ var tex = null;
+ var levelData = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_width, this.m_height
+ );
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+ var transferFmt = gluTextureUtil.getTransferFormat(
+ this.m_texFormat
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
+ this.m_context.texStorage3D(
+ gl.TEXTURE_2D_ARRAY, this.m_numLevels, this.m_internalFormat,
+ this.m_width, this.m_height, this.m_numLayers
+ );
+
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ levelData.setSize(levelW, levelH, this.m_numLayers);
+ tcuTextureUtil.fillWithComponentGradients(
+ levelData.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texSubImage3D(
+ gl.TEXTURE_2D_ARRAY, ndx, 0, 0, 0, levelW, levelH,
+ this.m_numLayers, transferFmt.format, transferFmt.dataType,
+ levelData.getAccess().getDataPtr()
+ );
+ }
+ };
+
+ // Basic TexStorage3D() with 3D texture usage
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} depth
+ * @param {number} numLevels
+ */
+ es3fTextureSpecificationTests.BasicTexStorage3DCase = function(
+ name, desc, internalFormat, width, height, depth, numLevels
+ ) {
+ es3fTextureSpecificationTests.Texture3DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), width, height, depth, numLevels
+ );
+
+ this.m_internalFormat = internalFormat;
+ };
+
+ es3fTextureSpecificationTests.BasicTexStorage3DCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture3DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ BasicTexStorage3DCase.prototype.constructor =
+ es3fTextureSpecificationTests.BasicTexStorage3DCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ BasicTexStorage3DCase.prototype.createTexture = function() {
+ var tex = null;
+ var levelData = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_width, this.m_height
+ );
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+ var transferFmt = gluTextureUtil.getTransferFormat(
+ this.m_texFormat
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_3D, tex);
+ this.m_context.texStorage3D(
+ gl.TEXTURE_3D, this.m_numLevels, this.m_internalFormat,
+ this.m_width, this.m_height, this.m_depth
+ );
+
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+ var levelD = Math.max(1, this.m_depth >> ndx);
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ levelData.setSize(levelW, levelH, levelD);
+ tcuTextureUtil.fillWithComponentGradients(
+ levelData.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texSubImage3D(
+ gl.TEXTURE_3D, ndx, 0, 0, 0, levelW, levelH,
+ levelD, transferFmt.format, transferFmt.dataType,
+ levelData.getAccess().getDataPtr()
+ );
+ }
+ };
+
+ // Pixel buffer object cases.
+
+ // TexImage2D() from pixel buffer object.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} rowLength
+ * @param {number} skipRows
+ * @param {number} skipPixels
+ * @param {number} alignment
+ * @param {number} offset
+ */
+ es3fTextureSpecificationTests.TexImage2DBufferCase = function(
+ name, desc, internalFormat, width, height, rowLength,
+ skipRows, skipPixels, alignment, offset
+ ) {
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), width, height, 1
+ );
+
+ this.m_internalFormat = internalFormat;
+ this.m_rowLength = rowLength;
+ this.m_skipRows = skipRows;
+ this.m_skipPixels = skipPixels;
+ this.m_alignment = alignment;
+ this.m_offset = offset;
+ };
+
+ es3fTextureSpecificationTests.TexImage2DBufferCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexImage2DBufferCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexImage2DBufferCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.TexImage2DBufferCase.prototype.createTexture =
+ function() {
+ var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
+ var pixelSize = this.m_texFormat.getPixelSize();
+ var rowLength = this.m_rowLength > 0 ?
+ this.m_rowLength :
+ this.m_width + this.m_skipPixels;
+ var rowPitch = deMath.deAlign32(
+ rowLength * pixelSize, this.m_alignment
+ );
+ var height = this.m_height + this.m_skipRows;
+ var buf = null;
+ var tex = null;
+ var data = new ArrayBuffer(rowPitch * height + this.m_skipPixels * pixelSize + this.m_offset);
+
+ assertMsgOptions(
+ this.m_numLevels == 1, 'Number of levels different than 1',
+ false, true
+ );
+
+ // Fill data with grid.
+ var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
+ var cBias = this.m_texFormatInfo.valueMin;
+ var colorA = deMath.add(
+ deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
+ );
+ var colorB = deMath.add(
+ deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
+ );
+
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_width,
+ height: this.m_height,
+ rowPitch: rowPitch,
+ data: data,
+ offset: this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize + this.m_offset
+ });
+ tcuTextureUtil.fillWithGrid(access, 4, colorA, colorB);
+
+ // Create buffer and upload.
+ buf = this.m_context.createBuffer();
+ this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
+ this.m_context.bufferData(gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW
+ );
+
+ this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+ this.m_context.texImage2D(gl.TEXTURE_2D, 0, this.m_internalFormat,
+ this.m_width, this.m_height, 0, transferFmt.format, transferFmt.dataType,
+ this.m_offset
+ );
+ };
+
+ // TexImage2D() cubemap from pixel buffer object case
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} size
+ * @param {number} rowLength
+ * @param {number} skipRows
+ * @param {number} skipPixels
+ * @param {number} alignment
+ * @param {number} offset
+ */
+ es3fTextureSpecificationTests.TexImageCubeBufferCase = function(
+ name, desc, internalFormat, size, rowLength, skipRows, skipPixels,
+ alignment, offset
+ ) {
+ es3fTextureSpecificationTests.TextureCubeSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), size, 1
+ );
+
+ this.m_internalFormat = internalFormat;
+ this.m_rowLength = rowLength;
+ this.m_skipRows = skipRows;
+ this.m_skipPixels = skipPixels;
+ this.m_alignment = alignment;
+ this.m_offset = offset;
+ };
+
+ es3fTextureSpecificationTests.TexImageCubeBufferCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexImageCubeBufferCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexImageCubeBufferCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexImageCubeBufferCase.prototype.createTexture = function() {
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+ var tex = null;
+ var fmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
+ var pixelSize = this.m_texFormat.getPixelSize();
+ var rowLength = this.m_rowLength > 0 ?
+ this.m_rowLength : this.m_size + this.m_skipPixels;
+ var rowPitch = deMath.deAlign32(
+ rowLength * pixelSize, this.m_alignment
+ );
+ var height = this.m_size + this.m_skipRows;
+
+ var data = new ArrayBuffer(rowPitch * height + this.m_skipPixels * pixelSize + this.m_offset);
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_size,
+ height: this.m_size,
+ rowPitch: rowPitch,
+ data: data,
+ offset: this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize + this.m_offset
+ });
+
+ assertMsgOptions(
+ this.m_numLevels == 1, 'Number of levels is different than 1',
+ false, true
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ for (var f in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[f];
+ var buf = null;
+
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ tcuTextureUtil.fillWithComponentGradients(access, gMin, gMax);
+
+ // Create buffer and upload.
+ buf = this.m_context.createBuffer();
+ this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
+ this.m_context.bufferData(gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW);
+
+ this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+
+ this.m_context.texImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[face], 0,
+ this.m_internalFormat, this.m_size, this.m_size, 0, fmt.format,
+ fmt.dataType, this.m_offset);
+ }
+ };
+
+ // TexImage3D() 2D array from pixel buffer object.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} depth
+ * @param {number} imageHeight
+ * @param {number} rowLength
+ * @param {number} skipImages
+ * @param {number} skipRows
+ * @param {number} skipPixels
+ * @param {number} alignment
+ * @param {number} offset
+ */
+ es3fTextureSpecificationTests.TexImage2DArrayBufferCase = function(
+ name, desc, internalFormat, width, height, depth, imageHeight,
+ rowLength, skipImages, skipRows, skipPixels, alignment, offset
+ ) {
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), width, height, depth, 1
+ );
+
+ this.m_internalFormat = internalFormat;
+ this.m_imageHeight = imageHeight;
+ this.m_rowLength = rowLength;
+ this.m_skipImages = skipImages;
+ this.m_skipRows = skipRows;
+ this.m_skipPixels = skipPixels;
+ this.m_alignment = alignment;
+ this.m_offset = offset;
+ };
+
+ es3fTextureSpecificationTests.TexImage2DArrayBufferCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexImage2DArrayBufferCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexImage2DArrayBufferCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexImage2DArrayBufferCase.prototype.createTexture = function() {
+ var transferFmt = gluTextureUtil.getTransferFormat(
+ this.m_texFormat
+ );
+ var pixelSize = this.m_texFormat.getPixelSize();
+ var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_width;
+ var rowPitch = deMath.deAlign32(
+ rowLength * pixelSize, this.m_alignment
+ );
+ var imageHeight = this.m_imageHeight > 0 ?
+ this.m_imageHeight : this.m_height;
+ var slicePitch = imageHeight * rowPitch;
+ var tex = null;
+ var buf = null;
+ var data = new ArrayBuffer(
+ slicePitch * (this.m_numLayers + this.m_skipImages) +
+ this.m_skipRows * rowPitch + this.m_skipPixels * pixelSize + this.m_offset
+ );
+
+ assertMsgOptions(
+ this.m_numLevels == 1, 'Number of levels is different than 1',
+ false, true
+ );
+
+ // Fill data with grid.
+ var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
+ var cBias = this.m_texFormatInfo.valueMin;
+ var colorA = deMath.add(
+ deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
+ );
+ var colorB = deMath.add(
+ deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
+ );
+
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_width,
+ height: this.m_height,
+ depth: this.m_numLayers,
+ rowPitch: rowPitch,
+ slicePitch: slicePitch,
+ data: data,
+ offset: this.m_skipImages * slicePitch +
+ this.m_skipRows * rowPitch +
+ this.m_skipPixels * pixelSize +
+ this.m_offset
+ });
+ tcuTextureUtil.fillWithGrid(access, 4, colorA, colorB);
+
+ // Create buffer and upload.
+ buf = this.m_context.createBuffer();
+ this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
+ this.m_context.bufferData(gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW);
+
+ this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, this.m_imageHeight);
+ this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, this.m_skipImages);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
+ this.m_context.texImage3D(
+ gl.TEXTURE_2D_ARRAY, 0, this.m_internalFormat, this.m_width,
+ this.m_height, this.m_numLayers, 0, transferFmt.format,
+ transferFmt.dataType, this.m_offset
+ );
+ };
+
+ // TexImage3D() from pixel buffer object.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} depth
+ * @param {number} imageHeight
+ * @param {number} rowLength
+ * @param {number} skipImages
+ * @param {number} skipRows
+ * @param {number} skipPixels
+ * @param {number} alignment
+ * @param {number} offset
+ */
+ es3fTextureSpecificationTests.TexImage3DBufferCase = function(
+ name, desc, internalFormat, width, height, depth, imageHeight,
+ rowLength, skipImages, skipRows, skipPixels, alignment, offset
+ ) {
+ es3fTextureSpecificationTests.Texture3DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), width, height, depth, 1
+ );
+
+ this.m_internalFormat = internalFormat;
+ this.m_imageHeight = imageHeight;
+ this.m_rowLength = rowLength;
+ this.m_skipImages = skipImages;
+ this.m_skipRows = skipRows;
+ this.m_skipPixels = skipPixels;
+ this.m_alignment = alignment;
+ this.m_offset = offset;
+ };
+
+ es3fTextureSpecificationTests.TexImage3DBufferCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture3DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexImage3DBufferCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexImage3DBufferCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexImage3DBufferCase.prototype.createTexture = function() {
+ var transferFmt = gluTextureUtil.getTransferFormat(
+ this.m_texFormat
+ );
+ var pixelSize = this.m_texFormat.getPixelSize();
+ var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_width;
+ var rowPitch = deMath.deAlign32(
+ rowLength * pixelSize, this.m_alignment
+ );
+ var imageHeight = this.m_imageHeight > 0 ?
+ this.m_imageHeight : this.m_height;
+ var slicePitch = imageHeight * rowPitch;
+ var tex = null;
+ var buf = null;
+ var data = new ArrayBuffer(
+ slicePitch * (this.m_depth + this.m_skipImages) +
+ rowPitch * this.m_skipRows + pixelSize * this.m_skipPixels + this.m_offset
+ );
+
+ assertMsgOptions(
+ this.m_numLevels == 1, 'Number of levels is different than 1',
+ false, true
+ );
+
+ // Fill data with grid.
+ var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
+ var cBias = this.m_texFormatInfo.valueMin;
+ var colorA = deMath.add(
+ deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
+ );
+ var colorB = deMath.add(
+ deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
+ );
+
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_width,
+ height: this.m_height,
+ depth: this.m_depth,
+ rowPitch: rowPitch,
+ slicePitch: slicePitch,
+ data: data,
+ offset: this.m_skipImages * slicePitch +
+ this.m_skipRows * rowPitch +
+ this.m_skipPixels * pixelSize +
+ this.m_offset
+ });
+ tcuTextureUtil.fillWithGrid(access, 4, colorA, colorB);
+
+ // Create buffer and upload.
+ buf = this.m_context.createBuffer();
+ this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
+ this.m_context.bufferData(gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW);
+
+ this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, this.m_imageHeight);
+ this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, this.m_skipImages);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_3D, tex);
+ this.m_context.texImage3D(
+ gl.TEXTURE_3D, 0, this.m_internalFormat, this.m_width,
+ this.m_height, this.m_depth, 0, transferFmt.format,
+ transferFmt.dataType, this.m_offset
+ );
+ };
+
+ // TexSubImage2D() PBO case.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} subX
+ * @param {number} subY
+ * @param {number} subW
+ * @param {number} subH
+ * @param {number} rowLength
+ * @param {number} skipRows
+ * @param {number} skipPixels
+ * @param {number} alignment
+ * @param {number} offset
+ */
+ es3fTextureSpecificationTests.TexSubImage2DBufferCase = function(
+ name, desc, internalFormat, width, height, subX, subY, subW, subH,
+ rowLength, skipRows, skipPixels, alignment, offset
+ ) {
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), width, height, 1
+ );
+ this.m_internalFormat = internalFormat;
+ this.m_subX = subX;
+ this.m_subY = subY;
+ this.m_subW = subW;
+ this.m_subH = subH;
+ this.m_rowLength = rowLength;
+ this.m_skipRows = skipRows;
+ this.m_skipPixels = skipPixels;
+ this.m_alignment = alignment;
+ this.m_offset = offset;
+ };
+
+ es3fTextureSpecificationTests.TexSubImage2DBufferCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexSubImage2DBufferCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexSubImage2DBufferCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexSubImage2DBufferCase.prototype.createTexture = function() {
+ var transferFmt = gluTextureUtil.getTransferFormat(
+ this.m_texFormat
+ );
+ var pixelSize = this.m_texFormat.getPixelSize();
+ var tex = null;
+ var buf = null;
+ var data = new ArrayBuffer(
+ deMath.deAlign32(this.m_width * pixelSize, 4) * this.m_height
+ );
+
+ assertMsgOptions(
+ this.m_numLevels == 1, 'Number of levels is different than 1',
+ false, true
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_width,
+ height: this.m_height,
+ rowPitch: deMath.deAlign32(this.m_width * pixelSize, 4),
+ data: data
+ });
+ // First fill texture with gradient.
+ tcuTextureUtil.fillWithComponentGradients(access, this.m_texFormatInfo.valueMin, this.m_texFormatInfo.valueMax);
+ this.m_context.texImage2D(
+ gl.TEXTURE_2D, 0, this.m_internalFormat,
+ this.m_width, this.m_height, 0, transferFmt.format,
+ transferFmt.dataType, access.getDataPtr()
+ );
+
+ // Fill data with grid.
+ var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
+ var rowPitch = deMath.deAlign32(
+ rowLength * pixelSize, this.m_alignment
+ );
+ var height = this.m_subH + this.m_skipRows;
+ var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
+ var cBias = this.m_texFormatInfo.valueMin;
+ var colorA = deMath.add(
+ deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
+ );
+ var colorB = deMath.add(
+ deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
+ );
+
+ access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_subW,
+ height: this.m_subH,
+ rowPitch: rowPitch,
+ data: new ArrayBuffer(rowPitch * height + this.m_offset),
+ offset: this.m_skipRows * rowPitch +
+ this.m_skipPixels * pixelSize +
+ this.m_offset
+ });
+ tcuTextureUtil.fillWithGrid(access, 4, colorA, colorB);
+
+ buf = this.m_context.createBuffer();
+ this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
+ this.m_context.bufferData(gl.PIXEL_UNPACK_BUFFER, access.getBuffer(), gl.STATIC_DRAW);
+
+ this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+
+ this.m_context.texSubImage2D(
+ gl.TEXTURE_2D, 0, this.m_subX, this.m_subY,
+ this.m_subW, this.m_subH, transferFmt.format,
+ transferFmt.dataType, this.m_offset
+ );
+ };
+
+ // TexSubImage2D() cubemap PBO case.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.TextureCubeSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} size
+ * @param {number} subX
+ * @param {number} subY
+ * @param {number} subW
+ * @param {number} subH
+ * @param {number} rowLength
+ * @param {number} skipRows
+ * @param {number} skipPixels
+ * @param {number} alignment
+ * @param {number} offset
+ */
+ es3fTextureSpecificationTests.TexSubImageCubeBufferCase = function(
+ name, desc, internalFormat, size, subX, subY, subW, subH, rowLength,
+ skipRows, skipPixels, alignment, offset
+ ) {
+ es3fTextureSpecificationTests.TextureCubeSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), size, 1
+ );
+
+ this.m_internalFormat = internalFormat;
+ this.m_subX = subX;
+ this.m_subY = subY;
+ this.m_subW = subW;
+ this.m_subH = subH;
+ this.m_rowLength = rowLength;
+ this.m_skipRows = skipRows;
+ this.m_skipPixels = skipPixels;
+ this.m_alignment = alignment;
+ this.m_offset = offset;
+ };
+
+ es3fTextureSpecificationTests.TexSubImageCubeBufferCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.TextureCubeSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexSubImageCubeBufferCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexSubImageCubeBufferCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexSubImageCubeBufferCase.prototype.createTexture = function() {
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+ var transferFmt = gluTextureUtil.getTransferFormat(
+ this.m_texFormat
+ );
+ var pixelSize = this.m_texFormat.getPixelSize();
+ var tex = null;
+ var buf = null;
+ var data = new ArrayBuffer(
+ deMath.deAlign32(this.m_size * pixelSize, 4) * this.m_size
+ );
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_size,
+ height: this.m_size,
+ rowPitch: deMath.deAlign32(this.m_size * pixelSize, 4),
+ data: data
+ });
+ assertMsgOptions(
+ this.m_numLevels == 1, 'Number of levels is different than 1',
+ false, true
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_CUBE_MAP, tex);
+
+ // Fill faces with different gradients.
+
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ for (var f in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[f];
+ var gMin = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+ var gMax = es3fTextureSpecificationTests.randomVector(
+ rnd, this.m_texFormatInfo.valueMin,
+ this.m_texFormatInfo.valueMax, 4
+ );
+
+ tcuTextureUtil.fillWithComponentGradients(access, gMin, gMax);
+
+ this.m_context.texImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[face], 0,
+ this.m_internalFormat, this.m_size, this.m_size, 0,
+ transferFmt.format, transferFmt.dataType,
+ access.getDataPtr()
+ );
+ }
+
+ // Fill data with grid.
+ var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
+ var rowPitch = deMath.deAlign32(
+ rowLength * pixelSize, this.m_alignment
+ );
+ var height = this.m_subH + this.m_skipRows;
+ var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
+ var cBias = this.m_texFormatInfo.valueMin;
+ var colorA = deMath.add(
+ deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
+ );
+ var colorB = deMath.add(
+ deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
+ );
+
+ data = new ArrayBuffer(rowPitch * height + this.m_skipPixels * pixelSize + this.m_offset);
+ var accessSub = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_subW,
+ height: this.m_subH,
+ rowPitch: rowPitch,
+ data: data,
+ offset: this.m_skipRows * rowPitch +
+ this.m_skipPixels * pixelSize +
+ this.m_offset
+ });
+ tcuTextureUtil.fillWithGrid(accessSub, 4, colorA, colorB);
+
+ buf = this.m_context.createBuffer();
+ this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
+ this.m_context.bufferData(
+ gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW
+ );
+
+ this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+
+ for (var f in tcuTexture.CubeFace) {
+ var face = tcuTexture.CubeFace[f];
+ this.m_context.texSubImage2D(
+ es3fTextureSpecificationTests.s_cubeMapFaces[face], 0,
+ this.m_subX, this.m_subY, this.m_subW, this.m_subH,
+ transferFmt.format, transferFmt.dataType, this.m_offset
+ );
+ }
+ };
+
+ // TexSubImage3D() 2D array PBO case.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} depth
+ * @param {number} subX
+ * @param {number} subY
+ * @param {number} subZ
+ * @param {number} subW
+ * @param {number} subH
+ * @param {number} subD
+ * @param {number} imageHeight
+ * @param {number} rowLength
+ * @param {number} skipImages
+ * @param {number} skipRows
+ * @param {number} skipPixels
+ * @param {number} alignment
+ * @param {number} offset
+ */
+ es3fTextureSpecificationTests.TexSubImage2DArrayBufferCase = function(
+ name, desc, internalFormat, width, height, depth, subX, subY, subZ,
+ subW, subH, subD, imageHeight, rowLength, skipImages, skipRows,
+ skipPixels, alignment, offset
+ ) {
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), width, height, depth, 1
+ );
+ this.m_internalFormat = internalFormat;
+ this.m_subX = subX;
+ this.m_subY = subY;
+ this.m_subZ = subZ;
+ this.m_subW = subW;
+ this.m_subH = subH;
+ this.m_subD = subD;
+ this.m_imageHeight = imageHeight;
+ this.m_rowLength = rowLength;
+ this.m_skipImages = skipImages;
+ this.m_skipRows = skipRows;
+ this.m_skipPixels = skipPixels;
+ this.m_alignment = alignment;
+ this.m_offset = offset;
+ };
+
+ es3fTextureSpecificationTests.TexSubImage2DArrayBufferCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexSubImage2DArrayBufferCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexSubImage2DArrayBufferCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexSubImage2DArrayBufferCase.prototype.createTexture = function() {
+ var transferFmt = gluTextureUtil.getTransferFormat(
+ this.m_texFormat
+ );
+ var pixelSize = this.m_texFormat.getPixelSize();
+ var tex = null;
+ var buf = null;
+ /** @type {ArrayBuffer} */ var data;
+
+ assertMsgOptions(
+ this.m_numLevels == 1, 'Number of levels is different than 1',
+ false, true
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
+
+ // Fill with gradient.
+ var rowPitch = deMath.deAlign32(pixelSize * this.m_width, 4);
+ var slicePitch = rowPitch * this.m_height;
+
+ data = new ArrayBuffer(slicePitch * this.m_numLayers);
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_width,
+ height: this.m_height,
+ depth: this.m_numLayers,
+ rowPitch: rowPitch,
+ slicePitch: slicePitch,
+ data: data
+ });
+ tcuTextureUtil.fillWithComponentGradients(access, this.m_texFormatInfo.valueMin, this.m_texFormatInfo.valueMax
+ );
+
+ this.m_context.texImage3D(gl.TEXTURE_2D_ARRAY, 0, this.m_internalFormat, this.m_width, this.m_height,
+ this.m_numLayers, 0, transferFmt.format, transferFmt.dataType, access.getDataPtr());
+
+ // Fill data with grid.
+ var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
+ rowPitch = deMath.deAlign32(
+ rowLength * pixelSize, this.m_alignment
+ );
+ var height = this.m_subH + this.m_skipRows;
+ var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
+
+ var cBias = this.m_texFormatInfo.valueMin;
+ var colorA = deMath.add(
+ deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
+ );
+ var colorB = deMath.add(
+ deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
+ );
+
+ var accessSub = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_subW,
+ height: this.m_subH,
+ rowPitch: rowPitch,
+ data: new ArrayBuffer(rowPitch * height + this.m_offset),
+ offset: this.m_skipRows * rowPitch +
+ this.m_skipPixels * pixelSize +
+ this.m_offset
+ });
+ tcuTextureUtil.fillWithGrid(accessSub, 4, colorA, colorB);
+
+ buf = this.m_context.createBuffer();
+ this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
+ this.m_context.bufferData(
+ gl.PIXEL_UNPACK_BUFFER, accessSub.getBuffer(), gl.STATIC_DRAW
+ );
+
+ this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+ };
+
+ // TexSubImage3D() PBO case.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture3DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} width
+ * @param {number} height
+ * @param {number} depth
+ * @param {number} subX
+ * @param {number} subY
+ * @param {number} subZ
+ * @param {number} subW
+ * @param {number} subH
+ * @param {number} subD
+ * @param {number} imageHeight
+ * @param {number} rowLength
+ * @param {number} skipImages
+ * @param {number} skipRows
+ * @param {number} skipPixels
+ * @param {number} alignment
+ * @param {number} offset
+ */
+ es3fTextureSpecificationTests.TexSubImage3DBufferCase = function(
+ name, desc, internalFormat, width, height, depth, subX, subY, subZ,
+ subW, subH, subD, imageHeight, rowLength, skipImages, skipRows,
+ skipPixels, alignment, offset
+ ) {
+ es3fTextureSpecificationTests.Texture3DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), width, height, depth, 1
+ );
+
+ this.m_internalFormat = internalFormat;
+ this.m_subX = subX;
+ this.m_subY = subY;
+ this.m_subZ = subZ;
+ this.m_subW = subW;
+ this.m_subH = subH;
+ this.m_subD = subD;
+ this.m_imageHeight = imageHeight;
+ this.m_rowLength = rowLength;
+ this.m_skipImages = skipImages;
+ this.m_skipRows = skipRows;
+ this.m_skipPixels = skipPixels;
+ this.m_alignment = alignment;
+ this.m_offset = offset;
+ };
+
+ es3fTextureSpecificationTests.TexSubImage3DBufferCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture3DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexSubImage3DBufferCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexSubImage3DBufferCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexSubImage3DBufferCase.prototype.createTexture = function() {
+ var transferFmt = gluTextureUtil.getTransferFormat(
+ this.m_texFormat
+ );
+ var pixelSize = this.m_texFormat.getPixelSize();
+ var tex = null;
+ var buf = null;
+ /** @type {ArrayBuffer} */ var data;
+
+ assertMsgOptions(
+ this.m_numLevels == 1, 'Number of levels is different than 1',
+ false, true
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_3D, tex);
+
+ // Fill with gradient.
+ var rowPitch = deMath.deAlign32(pixelSize * this.m_width, 4);
+ var slicePitch = rowPitch * this.m_height;
+
+ data = new ArrayBuffer(slicePitch * this.m_depth);
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_width,
+ height: this.m_height,
+ depth: this.m_depth,
+ rowPitch: rowPitch,
+ slicePitch: slicePitch,
+ data: data});
+ tcuTextureUtil.fillWithComponentGradients(access, this.m_texFormatInfo.valueMin, this.m_texFormatInfo.valueMax
+ );
+
+ this.m_context.texImage3D(
+ gl.TEXTURE_3D, 0, this.m_internalFormat, this.m_width,
+ this.m_height, this.m_depth, 0, transferFmt.format,
+ transferFmt.dataType, access.getDataPtr()
+ );
+
+ // Fill data with grid.
+ var rowLength = this.m_rowLength > 0 ? this.m_rowLength : this.m_subW;
+ rowPitch = deMath.deAlign32(
+ rowLength * pixelSize, this.m_alignment
+ );
+ var imageHeight = this.m_imageHeight > 0 ?
+ this.m_imageHeight : this.m_subH;
+ slicePitch = imageHeight * rowPitch;
+ var cScale = deMath.subtract(this.m_texFormatInfo.valueMax, this.m_texFormatInfo.valueMin);
+ var cBias = this.m_texFormatInfo.valueMin;
+ var colorA = deMath.add(
+ deMath.multiply([1.0, 0.0, 0.0, 1.0], cScale), cBias
+ );
+ var colorB = deMath.add(
+ deMath.multiply([0.0, 1.0, 0.0, 1.0], cScale), cBias
+ );
+
+ data = new ArrayBuffer(slicePitch * (this.m_subD + this.m_skipImages) +
+ rowPitch * this.m_skipRows + pixelSize * this.m_skipPixels + this.m_offset);
+ var accessSub = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_subW,
+ height: this.m_subH,
+ depth: this.m_subD,
+ rowPitch: rowPitch,
+ slicePitch: slicePitch,
+ data: data,
+ offset: this.m_skipImages * slicePitch +
+ this.m_skipRows * rowPitch +
+ this.m_skipPixels * pixelSize +
+ this.m_offset
+ });
+ tcuTextureUtil.fillWithGrid(accessSub, 4, colorA, colorB
+ );
+
+ buf = this.m_context.createBuffer();
+ this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
+ this.m_context.bufferData(
+ gl.PIXEL_UNPACK_BUFFER, data, gl.STATIC_DRAW
+ );
+
+ this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, this.m_imageHeight);
+ this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, this.m_rowLength);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, this.m_skipImages);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, this.m_skipRows);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, this.m_skipPixels);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, this.m_alignment);
+ this.m_context.texSubImage3D(
+ gl.TEXTURE_3D, 0, this.m_subX, this.m_subY, this.m_subZ,
+ this.m_subW, this.m_subH, this.m_subD, transferFmt.format,
+ transferFmt.dataType, this.m_offset
+ );
+ };
+
+ // TexImage2D() depth case.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} imageWidth
+ * @param {number} imageHeight
+ */
+ es3fTextureSpecificationTests.TexImage2DDepthCase = function(
+ name, desc, internalFormat, imageWidth, imageHeight
+ ) {
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), imageWidth, imageHeight,
+ es3fTextureSpecificationTests.maxLevelCount(
+ imageWidth, imageHeight
+ )
+ );
+
+ this.m_internalFormat = internalFormat;
+ // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
+ this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
+ this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
+ };
+
+ es3fTextureSpecificationTests.TexImage2DDepthCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexImage2DDepthCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexImage2DDepthCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.TexImage2DDepthCase.prototype.createTexture =
+ function() {
+ var fmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
+ var tex = null;
+ var levelData = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_width, this.m_height
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+ var gMin = [-1.5, -2.0, 1.7, -1.5];
+ var gMax = [2.0, 1.5, -1.0, 2.0];
+
+ levelData.setSize(levelW, levelH);
+ tcuTextureUtil.fillWithComponentGradients(
+ levelData.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texImage2D(
+ gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
+ fmt.format, fmt.dataType, levelData.getAccess().getDataPtr()
+ );
+ }
+ };
+
+ // TexImage3D() depth case.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} imageWidth
+ * @param {number} imageHeight
+ * @param {number} numLayers
+ */
+ es3fTextureSpecificationTests.TexImage2DArrayDepthCase = function(
+ name, desc, internalFormat, imageWidth, imageHeight, numLayers
+ ) {
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), imageWidth, imageHeight, numLayers,
+ es3fTextureSpecificationTests.maxLevelCount(
+ imageWidth, imageHeight
+ )
+ );
+
+ this.m_internalFormat = internalFormat;
+ // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
+ this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
+ this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
+ };
+
+ es3fTextureSpecificationTests.TexImage2DArrayDepthCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexImage2DArrayDepthCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexImage2DArrayDepthCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexImage2DArrayDepthCase.prototype.createTexture = function() {
+ var fmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
+ var tex = null;
+ var levelData = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_width, this.m_height
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+ var gMin = [-1.5, -2.0, 1.7, -1.5];
+ var gMax = [2.0, 1.5, -1.0, 2.0];
+
+ levelData.setSize(levelW, levelH, this.m_numLayers);
+ tcuTextureUtil.fillWithComponentGradients(
+ levelData.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texImage3D(
+ gl.TEXTURE_2D_ARRAY, ndx, this.m_internalFormat, levelW, levelH,
+ this.m_numLayers, 0, fmt.format, fmt.dataType,
+ levelData.getAccess().getDataPtr()
+ );
+ }
+ };
+
+ // TexSubImage2D() depth case.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} imageWidth
+ * @param {number} imageHeight
+ */
+ es3fTextureSpecificationTests.TexSubImage2DDepthCase = function(
+ name, desc, internalFormat, imageWidth, imageHeight
+ ) {
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), imageWidth, imageHeight,
+ es3fTextureSpecificationTests.maxLevelCount(
+ imageWidth, imageHeight
+ )
+ );
+
+ this.m_internalFormat = internalFormat;
+ // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
+ this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
+ this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
+ };
+
+ es3fTextureSpecificationTests.TexSubImage2DDepthCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexSubImage2DDepthCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexSubImage2DDepthCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexSubImage2DDepthCase.prototype.createTexture = function() {
+ var fmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+ var tex = null;
+ var levelData = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_width, this.m_height
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ // First specify full texture.
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+ var gMin = [-1.5, -2.0, 1.7, -1.5];
+ var gMax = [2.0, 1.5, -1.0, 2.0];
+
+ levelData.setSize(levelW, levelH);
+ tcuTextureUtil.fillWithComponentGradients(
+ levelData.getAccess(), gMin, gMax
+ );
+
+ this.m_context.texImage2D(
+ gl.TEXTURE_2D, ndx, this.m_internalFormat, levelW, levelH, 0,
+ fmt.format, fmt.dataType, levelData.getAccess().getDataPtr()
+ );
+ }
+
+ // Re-specify parts of each level.
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+
+ var w = rnd.getInt(1, levelW);
+ var h = rnd.getInt(1, levelH);
+ var x = rnd.getInt(0, levelW - w);
+ var y = rnd.getInt(0, levelH - h);
+
+ var colorA = [2.0, 1.5, -1.0, 2.0];
+ var colorB = [-1.5, -2.0, 1.7, -1.5];
+ var cellSize = rnd.getInt(2, 16);
+
+ levelData.setSize(w, h);
+ tcuTextureUtil.fillWithGrid(
+ levelData.getAccess(), cellSize, colorA, colorB
+ );
+
+ this.m_context.texSubImage2D(
+ gl.TEXTURE_2D, ndx, x, y, w, h, fmt.format, fmt.dataType,
+ levelData.getAccess().getDataPtr()
+ );
+ }
+ };
+
+ // TexSubImage3D() depth case.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} imageWidth
+ * @param {number} imageHeight
+ * @param {number} numLayers
+ */
+ es3fTextureSpecificationTests.TexSubImage2DArrayDepthCase = function(
+ name, desc, internalFormat, imageWidth, imageHeight, numLayers
+ ) {
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), imageWidth, imageHeight, numLayers,
+ es3fTextureSpecificationTests.maxLevelCount(
+ imageWidth, imageHeight
+ )
+ );
+
+ this.m_internalFormat = internalFormat;
+ // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
+ this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
+ this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
+ };
+
+ es3fTextureSpecificationTests.TexSubImage2DArrayDepthCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexSubImage2DArrayDepthCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexSubImage2DArrayDepthCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexSubImage2DArrayDepthCase.prototype.createTexture = function() {
+ var fmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
+ var rnd = new deRandom.Random(deString.deStringHash(this.fullName()));
+ var tex = null;
+ var levelData = new tcuTexture.TextureLevel(
+ this.m_texFormat, this.m_width, this.m_height
+ );
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ // First specify full texture.
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+ var gMin = [-1.5, -2.0, 1.7, -1.5];
+ var gMax = [2.0, 1.5, -1.0, 2.0];
+
+ levelData.setSize(levelW, levelH, this.m_numLayers);
+ tcuTextureUtil.fillWithComponentGradients(
+ levelData.getAccess(), gMin, gMax
+ );
+ this.m_context.texImage3D(
+ gl.TEXTURE_2D_ARRAY, ndx, this.m_internalFormat, levelW, levelH,
+ this.m_numLayers, 0, fmt.format, fmt.dataType,
+ levelData.getAccess().getDataPtr()
+ );
+ }
+
+ // Re-specify parts of each level.
+ for (var ndx = 0; ndx < this.m_numLevels; ndx++) {
+ var levelW = Math.max(1, this.m_width >> ndx);
+ var levelH = Math.max(1, this.m_height >> ndx);
+
+ var w = rnd.getInt(1, levelW);
+ var h = rnd.getInt(1, levelH);
+ var d = rnd.getInt(1, this.m_numLayers);
+ var x = rnd.getInt(0, levelW - w);
+ var y = rnd.getInt(0, levelH - h);
+ var z = rnd.getInt(0, this.m_numLayers - d);
+
+ var colorA = [2.0, 1.5, -1.0, 2.0];
+ var colorB = [-1.5, -2.0, 1.7, -1.5];
+ var cellSize = rnd.getInt(2, 16);
+
+ levelData.setSize(w, h, d);
+ tcuTextureUtil.fillWithGrid(
+ levelData.getAccess(), cellSize, colorA, colorB
+ );
+
+ this.m_context.texSubImage3D(
+ gl.TEXTURE_2D_ARRAY, ndx, x, y, z, w, h, d, fmt.format,
+ fmt.dataType, levelData.getAccess().getDataPtr()
+ );
+ }
+ };
+
+ // TexImage2D() depth case with pbo.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DSpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} imageWidth
+ * @param {number} imageHeight
+ */
+ es3fTextureSpecificationTests.TexImage2DDepthBufferCase = function(
+ name, desc, internalFormat, imageWidth, imageHeight
+ ) {
+ es3fTextureSpecificationTests.Texture2DSpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), imageWidth, imageHeight, 1
+ );
+
+ this.m_internalFormat = internalFormat;
+ // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
+ this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
+ this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
+ };
+
+ es3fTextureSpecificationTests.TexImage2DDepthBufferCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DSpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexImage2DDepthBufferCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexImage2DDepthBufferCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexImage2DDepthBufferCase.prototype.createTexture = function() {
+ var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
+ var pixelSize = this.m_texFormat.getPixelSize();
+ var rowLength = this.m_width;
+ var alignment = 4;
+ var rowPitch = deMath.deAlign32(rowLength * pixelSize, alignment);
+ var height = this.m_height;
+ var buf = null;
+ var tex = null;
+ var data = new ArrayBuffer(rowPitch * height);
+
+ assertMsgOptions(
+ this.m_numLevels == 1, 'Number of levels is different than 1',
+ false, true
+ );
+
+ // Fill data with gradient
+ var gMin = [-1.5, -2.0, 1.7, -1.5];
+ var gMax = [2.0, 1.5, -1.0, 2.0];
+
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_width,
+ height: this.m_height,
+ rowPitch: rowPitch,
+ data: data
+ });
+ tcuTextureUtil.fillWithComponentGradients(access, gMin, gMax);
+
+ // Create buffer and upload.
+ buf = this.m_context.createBuffer();
+ this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
+ this.m_context.bufferData(
+ gl.PIXEL_UNPACK_BUFFER, access.getBuffer(), gl.STATIC_DRAW
+ );
+
+ this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, rowLength);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, 0);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, alignment);
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D, tex);
+ this.m_context.texImage2D(
+ gl.TEXTURE_2D, 0, this.m_internalFormat, this.m_width,
+ this.m_height, 0, transferFmt.format, transferFmt.dataType, 0
+ );
+ this.m_context.deleteBuffer(buf);
+ };
+
+ // TexImage3D() depth case with pbo.
+ /**
+ * @constructor
+ * @extends {es3fTextureSpecificationTests.Texture2DArraySpecCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} internalFormat
+ * @param {number} imageWidth
+ * @param {number} imageHeight
+ */
+ es3fTextureSpecificationTests.TexImage2DArrayDepthBufferCase = function(
+ name, desc, internalFormat, imageWidth, imageHeight, numLayers
+ ) {
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.call(
+ this, name, desc, gluTextureUtil.mapGLInternalFormat(
+ internalFormat
+ ), imageWidth, imageHeight, numLayers, 1
+ );
+
+ this.m_internalFormat = internalFormat;
+ // we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
+ this.m_texFormatInfo.lookupBias = [0.25, 0.0, 0.0, 1.0];
+ this.m_texFormatInfo.lookupScale = [0.5, 1.0, 1.0, 0.0];
+ };
+
+ es3fTextureSpecificationTests.TexImage2DArrayDepthBufferCase.prototype =
+ Object.create(
+ es3fTextureSpecificationTests.Texture2DArraySpecCase.prototype
+ );
+
+ es3fTextureSpecificationTests.
+ TexImage2DArrayDepthBufferCase.prototype.constructor =
+ es3fTextureSpecificationTests.TexImage2DArrayDepthBufferCase;
+
+ /**
+ * createTexture
+ */
+ es3fTextureSpecificationTests.
+ TexImage2DArrayDepthBufferCase.prototype.createTexture = function() {
+ var transferFmt = gluTextureUtil.getTransferFormat(this.m_texFormat);
+ var pixelSize = this.m_texFormat.getPixelSize();
+ var rowLength = this.m_width;
+ var alignment = 4;
+ var rowPitch = deMath.deAlign32(rowLength * pixelSize, alignment);
+ var imageHeight = this.m_height;
+ var slicePitch = imageHeight * rowPitch;
+ var tex = null;
+ var buf = null;
+ var data = new ArrayBuffer(slicePitch * this.m_numLayers);
+
+ assertMsgOptions(
+ this.m_numLevels == 1, 'Number of levels is different than 1',
+ false, true
+ );
+
+ // Fill data with gradient
+ var gMin = [-1.5, -2.0, 1.7, -1.5];
+ var gMax = [2.0, 1.5, -1.0, 2.0];
+
+ var access = new tcuTexture.PixelBufferAccess({
+ format: this.m_texFormat,
+ width: this.m_width,
+ height: this.m_height,
+ depth: this.m_numLayers,
+ rowPitch: rowPitch,
+ slicePitch: slicePitch,
+ data: data
+ });
+ tcuTextureUtil.fillWithComponentGradients(access, gMin, gMax);
+
+ buf = this.m_context.createBuffer();
+ this.m_context.bindBuffer(gl.PIXEL_UNPACK_BUFFER, buf);
+ this.m_context.bufferData(
+ gl.PIXEL_UNPACK_BUFFER, access.getBuffer(), gl.STATIC_DRAW
+ );
+
+ this.m_context.pixelStorei(gl.UNPACK_IMAGE_HEIGHT, rowLength);
+ this.m_context.pixelStorei(gl.UNPACK_ROW_LENGTH, rowLength);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_IMAGES, 0);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_ROWS, 0);
+ this.m_context.pixelStorei(gl.UNPACK_SKIP_PIXELS, 0);
+ this.m_context.pixelStorei(gl.UNPACK_ALIGNMENT, alignment);
+
+ tex = this.m_context.createTexture();
+ this.m_context.bindTexture(gl.TEXTURE_2D_ARRAY, tex);
+ this.m_context.texImage3D(
+ gl.TEXTURE_2D_ARRAY, 0, this.m_internalFormat, this.m_width,
+ this.m_height, this.m_numLayers, 0, transferFmt.format,
+ transferFmt.dataType, 0
+ );
+ this.m_context.deleteBuffer(buf);
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fTextureSpecificationTests.TextureSpecificationTests = function() {
+ tcuTestCase.DeqpTest.call(
+ this, 'specification', 'Texture Specification Tests'
+ );
+ };
+
+ es3fTextureSpecificationTests.TextureSpecificationTests.prototype =
+ Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fTextureSpecificationTests.TextureSpecificationTests.prototype.constructor =
+ es3fTextureSpecificationTests.TextureSpecificationTests;
+
+ es3fTextureSpecificationTests.TextureSpecificationTests.prototype.init = function() {
+ /**
+ * @type {Array<number>}
+ */
+ es3fTextureSpecificationTests.s_cubeMapFaces = [
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_X,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
+ gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,
+ gl.TEXTURE_CUBE_MAP_POSITIVE_Z
+ ];
+
+ /** @type {Array<{name: string, format: number, dataType: number}>} */
+ var unsizedFormats = [{
+ name: 'alpha_unsigned_byte',
+ format: gl.ALPHA,
+ dataType: gl.UNSIGNED_BYTE
+ }, {
+ name: 'luminance_unsigned_byte',
+ format: gl.LUMINANCE,
+ dataType: gl.UNSIGNED_BYTE
+ }, {
+ name: 'luminance_alpha_unsigned_byte',
+ format: gl.LUMINANCE_ALPHA,
+ dataType: gl.UNSIGNED_BYTE
+ }, {
+ name: 'rgb_unsigned_short_5_6_5',
+ format: gl.RGB,
+ dataType: gl.UNSIGNED_SHORT_5_6_5
+ }, {
+ name: 'rgb_unsigned_byte',
+ format: gl.RGB,
+ dataType: gl.UNSIGNED_BYTE
+ }, {
+ name: 'rgba_unsigned_short_4_4_4_4',
+ format: gl.RGBA,
+ dataType: gl.UNSIGNED_SHORT_4_4_4_4
+ }, {
+ name: 'rgba_unsigned_short_5_5_5_1',
+ format: gl.RGBA,
+ dataType: gl.UNSIGNED_SHORT_5_5_5_1
+ }, {
+ name: 'rgba_unsigned_byte',
+ format: gl.RGBA,
+ dataType: gl.UNSIGNED_BYTE
+ }
+ ];
+
+ /** @type {Array<{name: string, internalFormat: number}>} */
+ var colorFormats = [{
+ name: 'rgba32f', internalFormat: gl.RGBA32F
+ }, {
+ name: 'rgba32i', internalFormat: gl.RGBA32I
+ }, {
+ name: 'rgba32ui', internalFormat: gl.RGBA32UI
+ }, {
+ name: 'rgba16f', internalFormat: gl.RGBA16F
+ }, {
+ name: 'rgba16i', internalFormat: gl.RGBA16I
+ }, {
+ name: 'rgba16ui', internalFormat: gl.RGBA16UI
+ }, {
+ name: 'rgba8', internalFormat: gl.RGBA8
+ }, {
+ name: 'rgba8i', internalFormat: gl.RGBA8I
+ }, {
+ name: 'rgba8ui', internalFormat: gl.RGBA8UI
+ }, {
+ name: 'srgb8_alpha8', internalFormat: gl.SRGB8_ALPHA8
+ }, {
+ name: 'rgb10_a2', internalFormat: gl.RGB10_A2
+ }, {
+ name: 'rgb10_a2ui', internalFormat: gl.RGB10_A2UI
+ }, {
+ name: 'rgba4', internalFormat: gl.RGBA4
+ }, {
+ name: 'rgb5_a1', internalFormat: gl.RGB5_A1
+ }, {
+ name: 'rgba8_snorm', internalFormat: gl.RGBA8_SNORM
+ }, {
+ name: 'rgb8', internalFormat: gl.RGB8
+ }, {
+ name: 'rgb565', internalFormat: gl.RGB565
+ }, {
+ name: 'r11f_g11f_b10f', internalFormat: gl.R11F_G11F_B10F
+ }, {
+ name: 'rgb32f', internalFormat: gl.RGB32F
+ }, {
+ name: 'rgb32i', internalFormat: gl.RGB32I
+ }, {
+ name: 'rgb32ui', internalFormat: gl.RGB32UI
+ }, {
+ name: 'rgb16f', internalFormat: gl.RGB16F
+ }, {
+ name: 'rgb16i', internalFormat: gl.RGB16I
+ }, {
+ name: 'rgb16ui', internalFormat: gl.RGB16UI
+ }, {
+ name: 'rgb8_snorm', internalFormat: gl.RGB8_SNORM
+ }, {
+ name: 'rgb8i', internalFormat: gl.RGB8I
+ }, {
+ name: 'rgb8ui', internalFormat: gl.RGB8UI
+ }, {
+ name: 'srgb8', internalFormat: gl.SRGB8
+ }, {
+ name: 'rgb9_e5', internalFormat: gl.RGB9_E5
+ }, {
+ name: 'rg32f', internalFormat: gl.RG32F
+ }, {
+ name: 'rg32i', internalFormat: gl.RG32I
+ }, {
+ name: 'rg32ui', internalFormat: gl.RG32UI
+ }, {
+ name: 'rg16f', internalFormat: gl.RG16F
+ }, {
+ name: 'rg16i', internalFormat: gl.RG16I
+ }, {
+ name: 'rg16ui', internalFormat: gl.RG16UI
+ }, {
+ name: 'rg8', internalFormat: gl.RG8
+ }, {
+ name: 'rg8i', internalFormat: gl.RG8I
+ }, {
+ name: 'rg8ui', internalFormat: gl.RG8UI
+ }, {
+ name: 'rg8_snorm', internalFormat: gl.RG8_SNORM
+ }, {
+ name: 'r32f', internalFormat: gl.R32F
+ }, {
+ name: 'r32i', internalFormat: gl.R32I
+ }, {
+ name: 'r32ui', internalFormat: gl.R32UI
+ }, {
+ name: 'r16f', internalFormat: gl.R16F
+ }, {
+ name: 'r16i', internalFormat: gl.R16I
+ }, {
+ name: 'r16ui', internalFormat: gl.R16UI
+ }, {
+ name: 'r8', internalFormat: gl.R8
+ }, {
+ name: 'r8i', internalFormat: gl.R8I
+ }, {
+ name: 'r8ui', internalFormat: gl.R8UI
+ }, {
+ name: 'r8_snorm', internalFormat: gl.R8_SNORM
+ }
+ ];
+
+ // Depth and stencil formats
+ /** @type {Array<{name: string, internalFormat: number}>} */
+ var depthStencilFormats = [{
+ name: 'depth_component32f',
+ internalFormat: gl.DEPTH_COMPONENT32F
+ }, {
+ name: 'depth_component24',
+ internalFormat: gl.DEPTH_COMPONENT24
+ }, {
+ name: 'depth_component16',
+ internalFormat: gl.DEPTH_COMPONENT16
+ }, {
+ name: 'depth32f_stencil8',
+ internalFormat: gl.DEPTH32F_STENCIL8
+ }, {
+ name: 'depth24_stencil8',
+ internalFormat: gl.DEPTH24_STENCIL8
+ }
+ ];
+
+ // Basic TexImage2D usage.
+ var splitBasicTex2D = 2, splitBasicTexCube = 5;
+ /** @type {Array<{tcuTestCase.DeqpTest}>} */
+ var basicTexImageGroup2D = [];
+ for (var ii = 0; ii < splitBasicTex2D; ++ii) {
+ basicTexImageGroup2D.push(
+ new tcuTestCase.DeqpTest('basic_teximage2d', 'Basic glTexImage2D() usage')
+ );
+ this.addChild(basicTexImageGroup2D[ii]);
+ }
+ /** @type {Array<{tcuTestCase.DeqpTest}>} */
+ var basicTexImageGroupCube = [];
+ for (var ii = 0; ii < splitBasicTexCube; ++ii) {
+ basicTexImageGroupCube.push(
+ new tcuTestCase.DeqpTest('basic_teximage2d', 'Basic glTexImage2D() usage')
+ );
+ this.addChild(basicTexImageGroupCube[ii]);
+ }
+ for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
+ /** @type {string} */
+ var fmtName = colorFormats[formatNdx].name;
+ /** @type {number} */
+ var format = colorFormats[formatNdx].internalFormat;
+ /** @type {number} */
+ var tex2DWidth = 64;
+ /** @type {number} */
+ var tex2DHeight = 128;
+ /** @type {number} */
+ var texCubeSize = 64;
+
+ basicTexImageGroup2D[formatNdx % splitBasicTex2D].addChild(
+ es3fTextureSpecificationTests.newBasicTexImage2DCaseInternal(
+ fmtName + '_2d', '', format, tex2DWidth, tex2DHeight
+ )
+ );
+ basicTexImageGroupCube[formatNdx % splitBasicTexCube].addChild(
+ es3fTextureSpecificationTests.newBasicTexImageCubeCaseInternal(
+ fmtName + '_cube', '', format, texCubeSize
+ )
+ );
+ }
+
+ // Randomized TexImage2D order.
+ /** @type {tcuTestCase.DeqpTest} */
+ var randomTexImageGroup = new tcuTestCase.DeqpTest(
+ 'random_teximage2d', 'Randomized glTexImage2D() usage'
+ );
+ this.addChild(randomTexImageGroup);
+ var rnd = new deRandom.Random(9);
+
+ // 2D cases.
+ for (var ndx = 0; ndx < 10; ndx++) {
+ var formatNdx = rnd.getInt(0, colorFormats.length - 1);
+ var width = 1 << rnd.getInt(2, 8);
+ var height = 1 << rnd.getInt(2, 8);
+
+ randomTexImageGroup.addChild(
+ es3fTextureSpecificationTests.newRandomOrderTexImage2DCaseInternal(
+ '2d.' + colorFormats[formatNdx].name, '',
+ colorFormats[formatNdx].internalFormat, width, height
+ )
+ );
+ }
+
+ // Cubemap cases.
+ randomTexImageGroup = new tcuTestCase.DeqpTest(
+ 'random_teximage2d', 'Randomized glTexImage2D() usage'
+ );
+ this.addChild(randomTexImageGroup);
+
+ for (var ndx = 0; ndx < 10; ndx++) {
+ formatNdx = rnd.getInt(0, colorFormats.length - 1);
+ /** @type {number} */ var size = 1 << rnd.getInt(2, 8);
+
+ randomTexImageGroup.addChild(
+ es3fTextureSpecificationTests.newRandomOrderTexImageCubeCaseInternal(
+ 'cube.' + colorFormats[formatNdx].name, '',
+ colorFormats[formatNdx].internalFormat, size
+ )
+ );
+ }
+
+ // TexImage2D unpack alignment.
+ /** @type {tcuTestCase.DeqpTest} */
+ var alignGroup = new tcuTestCase.DeqpTest(
+ 'teximage2d_align', 'glTexImage2D() unpack alignment tests'
+ );
+ this.addChild(alignGroup);
+
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_r8_4_8', '', gl.R8, 4, 8, 4, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_r8_63_1', '', gl.R8, 63, 30, 1, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_r8_63_2', '', gl.R8, 63, 30, 1, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_r8_63_4', '', gl.R8, 63, 30, 1, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_r8_63_8', '', gl.R8, 63, 30, 1, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_rgba4_51_1', '', gl.RGBA4, 51, 30, 1, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_rgba4_51_2', '', gl.RGBA4, 51, 30, 1, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_rgba4_51_4', '', gl.RGBA4, 51, 30, 1, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_rgba4_51_8', '', gl.RGBA4, 51, 30, 1, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_rgb8_39_1', '', gl.RGB8, 39, 43, 1, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_rgb8_39_2', '', gl.RGB8, 39, 43, 1, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_rgb8_39_4', '', gl.RGB8, 39, 43, 1, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_rgb8_39_8', '', gl.RGB8, 39, 43, 1, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_rgba8_47_1', '', gl.RGBA8, 47, 27, 1, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_rgba8_47_2', '', gl.RGBA8, 47, 27, 1, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_rgba8_47_4', '', gl.RGBA8, 47, 27, 1, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImage2DAlignCaseInternal(
+ '2d_rgba8_47_8', '', gl.RGBA8, 47, 27, 1, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_r8_4_8', '', gl.R8, 4, 3, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_r8_63_1', '', gl.R8, 63, 1, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_r8_63_2', '', gl.R8, 63, 1, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_r8_63_4', '', gl.R8, 63, 1, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_r8_63_8', '', gl.R8, 63, 1, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_rgba4_51_1', '', gl.RGBA4, 51, 1, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_rgba4_51_2', '', gl.RGBA4, 51, 1, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_rgba4_51_4', '', gl.RGBA4, 51, 1, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_rgba4_51_8', '', gl.RGBA4, 51, 1, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_rgb8_39_1', '', gl.RGB8, 39, 1, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_rgb8_39_2', '', gl.RGB8, 39, 1, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_rgb8_39_4', '', gl.RGB8, 39, 1, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_rgb8_39_8', '', gl.RGB8, 39, 1, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_rgba8_47_1', '', gl.RGBA8, 47, 1, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_rgba8_47_2', '', gl.RGBA8, 47, 1, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_rgba8_47_4', '', gl.RGBA8, 47, 1, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexImageCubeAlignCaseInternal(
+ 'cube_rgba8_47_8', '', gl.RGBA8, 47, 1, 8
+ )
+ );
+
+ // glTexImage2D() unpack parameter cases.
+ /** @type {tcuTestCase.DeqpTest} */
+ var paramGroup = new tcuTestCase.DeqpTest(
+ 'teximage2d_unpack_params',
+ 'glTexImage2D() pixel transfer mode cases'
+ );
+ this.addChild(paramGroup);
+
+ var cases = [{
+ name: 'rgb8_alignment', format: gl.RGB8, width: 31,
+ height: 30, rowLength: 0, skipRows: 0, skipPixels: 0,
+ alignment: 2
+ }, {
+ name: 'rgb8_row_length', format: gl.RGB8, width: 31,
+ height: 30, rowLength: 50, skipRows: 0, skipPixels: 0,
+ alignment: 4
+ }, {
+ name: 'rgb8_skip_rows', format: gl.RGB8, width: 31,
+ height: 30, rowLength: 0, skipRows: 3, skipPixels: 0,
+ alignment: 4
+ }, {
+ name: 'rgb8_skip_pixels', format: gl.RGB8, width: 31,
+ height: 30, rowLength: 36, skipRows: 0, skipPixels: 5,
+ alignment: 4
+ }, {
+ name: 'r8_complex1', format: gl.R8, width: 31,
+ height: 30, rowLength: 64, skipRows: 1, skipPixels: 3,
+ alignment: 1
+ }, {
+ name: 'r8_complex2', format: gl.R8, width: 31,
+ height: 30, rowLength: 64, skipRows: 1, skipPixels: 3,
+ alignment: 2
+ }, {
+ name: 'r8_complex3', format: gl.R8, width: 31,
+ height: 30, rowLength: 64, skipRows: 1, skipPixels: 3,
+ alignment: 4
+ }, {
+ name: 'r8_complex4', format: gl.R8, width: 31,
+ height: 30, rowLength: 64, skipRows: 1, skipPixels: 3,
+ alignment: 8
+ }, {
+ name: 'rgba8_complex1', format: gl.RGBA8, width: 56,
+ height: 61, rowLength: 69, skipRows: 0, skipPixels: 0,
+ alignment: 8
+ }, {
+ name: 'rgba8_complex2', format: gl.RGBA8, width: 56,
+ height: 61, rowLength: 69, skipRows: 0, skipPixels: 7,
+ alignment: 8
+ }, {
+ name: 'rgba8_complex3', format: gl.RGBA8, width: 56,
+ height: 61, rowLength: 69, skipRows: 3, skipPixels: 0,
+ alignment: 8
+ }, {
+ name: 'rgba8_complex4', format: gl.RGBA8, width: 56,
+ height: 61, rowLength: 69, skipRows: 3, skipPixels: 7,
+ alignment: 8
+ }, {
+ name: 'rgba32f_complex', format: gl.RGBA32F, width: 19,
+ height: 10, rowLength: 27, skipRows: 1, skipPixels: 7,
+ alignment: 8
+ }
+ ];
+
+ for (var ndx = 0; ndx < cases.length; ndx++)
+ paramGroup.addChild(
+ new es3fTextureSpecificationTests.TexImage2DParamsCase(
+ cases[ndx].name, '', cases[ndx].format, cases[ndx].width,
+ cases[ndx].height, cases[ndx].rowLength,
+ cases[ndx].skipRows, cases[ndx].skipPixels,
+ cases[ndx].alignment
+ )
+ );
+
+ // glTexImage2D() pbo cases.
+ var splitPboTex2D = 2, splitPboTexCube = 5;
+ /** @type {Array<{tcuTestCase.DeqpTest}>} */ var pboGroup2D = [];
+ for (var ii = 0; ii < splitPboTex2D; ++ii) {
+ pboGroup2D.push(new tcuTestCase.DeqpTest('teximage2d_pbo', 'glTexImage2D() from PBO'));
+ this.addChild(pboGroup2D[ii]);
+ }
+ /** @type {Array<{tcuTestCase.DeqpTest}>} */ var pboGroupCube = [];
+ for (var ii = 0; ii < splitPboTexCube; ++ii) {
+ pboGroupCube.push(new tcuTestCase.DeqpTest('teximage2d_pbo', 'glTexImage2D() from PBO'));
+ this.addChild(pboGroupCube[ii]);
+ }
+ for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
+ fmtName = colorFormats[formatNdx].name;
+ format = colorFormats[formatNdx].internalFormat;
+ tex2DWidth = 65;
+ tex2DHeight = 37;
+ texCubeSize = 64;
+
+ pboGroup2D[formatNdx % splitPboTex2D].addChild(
+ new es3fTextureSpecificationTests.TexImage2DBufferCase(
+ fmtName + '_2d', '', format,
+ tex2DWidth, tex2DHeight, 0, 0, 0, 4, 0
+ )
+ );
+ pboGroupCube[formatNdx % splitPboTexCube].addChild(
+ new es3fTextureSpecificationTests.TexImageCubeBufferCase(
+ fmtName + '_cube', '', format,
+ texCubeSize, 0, 0, 0, 4, 0
+ )
+ );
+ }
+
+ // Parameter cases
+ var pboGroupParams = new tcuTestCase.DeqpTest(
+ 'teximage2d_pbo', 'glTexImage2D() from PBO'
+ );
+ this.addChild(pboGroupParams);
+ /**
+ * @type {Array<{name: string, format: number, width: number,
+ * height: number, rowLength: number, skipRows: number,
+ * skipPixels: number, alignment: number, offset: number}>}
+ */
+ var parameterCases = [{
+ name: 'rgb8_offset', format: gl.RGB8, width: 31,
+ height: 30, rowLength: 0, skipRows: 0, skipPixels: 0,
+ alignment: 4, offset: 67
+ }, {
+ name: 'rgb8_alignment', format: gl.RGB8, width: 31,
+ height: 30, rowLength: 0, skipRows: 0, skipPixels: 0,
+ alignment: 2, offset: 0
+ }, {
+ name: 'rgb8_row_length', format: gl.RGB8, width: 31,
+ height: 30, rowLength: 50, skipRows: 0, skipPixels: 0,
+ alignment: 4, offset: 0
+ }, {
+ name: 'rgb8_skip_rows', format: gl.RGB8, width: 31,
+ height: 30, rowLength: 0, skipRows: 3, skipPixels: 0,
+ alignment: 4, offset: 0
+ }, {
+ name: 'rgb8_skip_pixels', format: gl.RGB8, width: 31,
+ height: 30, rowLength: 36, skipRows: 0, skipPixels: 5,
+ alignment: 4, offset: 0
+ }
+ ];
+ for (var ndx = 0; ndx < parameterCases.length; ndx++) {
+ pboGroupParams.addChild(
+ new es3fTextureSpecificationTests.TexImage2DBufferCase(
+ parameterCases[ndx].name + '_2d', '',
+ parameterCases[ndx].format, parameterCases[ndx].width,
+ parameterCases[ndx].height, parameterCases[ndx].rowLength,
+ parameterCases[ndx].skipRows,
+ parameterCases[ndx].skipPixels,
+ parameterCases[ndx].alignment,
+ parameterCases[ndx].offset
+ )
+ );
+ pboGroupParams.addChild(
+ new es3fTextureSpecificationTests.TexImageCubeBufferCase(
+ parameterCases[ndx].name + '_cube', '',
+ parameterCases[ndx].format, parameterCases[ndx].width,
+ parameterCases[ndx].rowLength, parameterCases[ndx].skipRows,
+ parameterCases[ndx].skipPixels,
+ parameterCases[ndx].alignment, parameterCases[ndx].offset
+ )
+ );
+ }
+
+ // glTexImage2D() depth cases.
+ /** @type {tcuTestCase.DeqpTest} */
+ var shadow2dGroup = new tcuTestCase.DeqpTest(
+ 'teximage2d_depth',
+ 'glTexImage2D() with depth or depth/stencil format'
+ );
+ this.addChild(shadow2dGroup);
+
+ for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
+ // WebGL 2 specific constraint.
+ if (depthStencilFormats[ndx].internalFormat == gl.DEPTH32F_STENCIL8)
+ continue;
+ var tex2DWidth = 64;
+ var tex2DHeight = 128;
+
+ shadow2dGroup.addChild(
+ new es3fTextureSpecificationTests.TexImage2DDepthCase(
+ depthStencilFormats[ndx].name, '',
+ depthStencilFormats[ndx].internalFormat,
+ tex2DWidth, tex2DHeight
+ )
+ );
+ }
+
+ // glTexImage2D() depth cases with pbo.
+ shadow2dGroup = new tcuTestCase.DeqpTest(
+ 'teximage2d_depth_pbo',
+ 'glTexImage2D() with depth or depth/stencil format with pbo'
+ );
+ this.addChild(shadow2dGroup);
+
+ for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
+ tex2DWidth = 64;
+ tex2DHeight = 128;
+
+ shadow2dGroup.addChild(
+ new es3fTextureSpecificationTests.TexImage2DDepthBufferCase(
+ depthStencilFormats[ndx].name, '',
+ depthStencilFormats[ndx].internalFormat,
+ tex2DWidth, tex2DHeight
+ )
+ );
+ }
+
+ // Basic TexSubImage2D usage.
+ splitBasicTex2D = 3;
+ splitBasicTexCube = 5;
+ /** @type {Array<{tcuTestCase.DeqpTest}>} */
+ var basicTexSubImageGroup2D = [];
+ for (var ii = 0; ii < splitBasicTex2D; ++ii) {
+ basicTexSubImageGroup2D.push(
+ new tcuTestCase.DeqpTest('basic_texsubimage2d', 'Basic glTexSubImage2D() usage')
+ );
+ this.addChild(basicTexSubImageGroup2D[ii]);
+ }
+ /** @type {Array<{tcuTestCase.DeqpTest}>} */
+ var basicTexSubImageGroupCube = [];
+ for (var ii = 0; ii < splitBasicTexCube; ++ii) {
+ basicTexSubImageGroupCube.push(
+ new tcuTestCase.DeqpTest('basic_texsubimage2d', 'Basic glTexSubImage2D() usage')
+ );
+ this.addChild(basicTexSubImageGroupCube[ii]);
+ }
+ for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
+ fmtName = colorFormats[formatNdx].name;
+ format = colorFormats[formatNdx].internalFormat;
+ tex2DWidth = 64;
+ tex2DHeight = 128;
+ texCubeSize = 64;
+
+ basicTexSubImageGroup2D[formatNdx % splitBasicTex2D].addChild(
+ es3fTextureSpecificationTests.newBasicTexSubImage2DCaseInternal(
+ fmtName + '_2d', '', format, tex2DWidth, tex2DHeight
+ )
+ );
+ basicTexSubImageGroupCube[formatNdx % splitBasicTexCube].addChild(
+ es3fTextureSpecificationTests.newBasicTexImageCubeCaseInternal(
+ fmtName + '_cube', '', format, texCubeSize
+ )
+ );
+ }
+
+ // TexSubImage2D to empty texture.
+ /** @type {tcuTestCase.DeqpTest} */
+ var texSubImageEmptyTexGroup = new tcuTestCase.DeqpTest(
+ 'texsubimage2d_empty_tex',
+ 'glTexSubImage2D() to texture that has storage but no data'
+ );
+ this.addChild(texSubImageEmptyTexGroup);
+ for (var formatNdx = 0; formatNdx < unsizedFormats.length; formatNdx++) {
+ fmtName = unsizedFormats[formatNdx].name;
+ format = unsizedFormats[formatNdx].format;
+ /** @type {number} */
+ var dataType = unsizedFormats[formatNdx].dataType;
+ tex2DWidth = 64;
+ tex2DHeight = 32;
+ texCubeSize = 32;
+
+ texSubImageEmptyTexGroup.addChild(
+ new es3fTextureSpecificationTests.TexSubImage2DEmptyTexCase(
+ fmtName + '_2d', '', format, dataType, tex2DWidth, tex2DHeight
+ )
+ );
+ texSubImageEmptyTexGroup.addChild(
+ new es3fTextureSpecificationTests.TexSubImageCubeEmptyTexCase(
+ fmtName + '_cube', '', format, dataType, texCubeSize
+ )
+ );
+ }
+
+ // TexSubImage2D alignment cases.
+ alignGroup = new tcuTestCase.DeqpTest(
+ 'texsubimage2d_align', 'glTexSubImage2D() unpack alignment tests'
+ );
+ this.addChild(alignGroup);
+
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_r8_1_1', '', gl.R8, 64, 64, 13, 17, 1, 6, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_r8_1_2', '', gl.R8, 64, 64, 13, 17, 1, 6, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_r8_1_4', '', gl.R8, 64, 64, 13, 17, 1, 6, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_r8_1_8', '', gl.R8, 64, 64, 13, 17, 1, 6, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_r8_63_1', '', gl.R8, 64, 64, 1, 9, 63, 30, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_r8_63_2', '', gl.R8, 64, 64, 1, 9, 63, 30, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_r8_63_4', '', gl.R8, 64, 64, 1, 9, 63, 30, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_r8_63_8', '', gl.R8, 64, 64, 1, 9, 63, 30, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_rgba4_51_1', '', gl.RGBA4, 64, 64, 7, 29, 51, 30, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_rgba4_51_2', '', gl.RGBA4, 64, 64, 7, 29, 51, 30, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_rgba4_51_4', '', gl.RGBA4, 64, 64, 7, 29, 51, 30, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_rgba4_51_8', '', gl.RGBA4, 64, 64, 7, 29, 51, 30, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_rgb8_39_1', '', gl.RGB8, 64, 64, 11, 8, 39, 43, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_rgb8_39_2', '', gl.RGB8, 64, 64, 11, 8, 39, 43, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_rgb8_39_4', '', gl.RGB8, 64, 64, 11, 8, 39, 43, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_rgb8_39_8', '', gl.RGB8, 64, 64, 11, 8, 39, 43, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_rgba8_47_1', '', gl.RGBA8, 64, 64, 10, 1, 47, 27, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_rgba8_47_2', '', gl.RGBA8, 64, 64, 10, 1, 47, 27, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_rgba8_47_4', '', gl.RGBA8, 64, 64, 10, 1, 47, 27, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImage2DAlignCaseInternal(
+ '2d_rgba8_47_8', '', gl.RGBA8, 64, 64, 10, 1, 47, 27, 8
+ )
+ );
+
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_r8_1_1', '', gl.R8, 64, 13, 17, 1, 6, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_r8_1_2', '', gl.R8, 64, 13, 17, 1, 6, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_r8_1_4', '', gl.R8, 64, 13, 17, 1, 6, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_r8_1_8', '', gl.R8, 64, 13, 17, 1, 6, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_r8_63_1', '', gl.R8, 64, 1, 9, 63, 30, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_r8_63_2', '', gl.R8, 64, 1, 9, 63, 30, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_r8_63_4', '', gl.R8, 64, 1, 9, 63, 30, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_r8_63_8', '', gl.R8, 64, 1, 9, 63, 30, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_rgba4_51_1', '', gl.RGBA4, 64, 7, 29, 51, 30, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_rgba4_51_2', '', gl.RGBA4, 64, 7, 29, 51, 30, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_rgba4_51_4', '', gl.RGBA4, 64, 7, 29, 51, 30, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_rgba4_51_8', '', gl.RGBA4, 64, 7, 29, 51, 30, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_rgb8_39_1', '', gl.RGB8, 64, 11, 8, 39, 43, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_rgb8_39_2', '', gl.RGB8, 64, 11, 8, 39, 43, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_rgb8_39_4', '', gl.RGB8, 64, 11, 8, 39, 43, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_rgb8_39_8', '', gl.RGB8, 64, 11, 8, 39, 43, 8
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_rgba8_47_1', '', gl.RGBA8, 64, 10, 1, 47, 27, 1
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_rgba8_47_2', '', gl.RGBA8, 64, 10, 1, 47, 27, 2
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_rgba8_47_4', '', gl.RGBA8, 64, 10, 1, 47, 27, 4
+ )
+ );
+ alignGroup.addChild(
+ es3fTextureSpecificationTests.newTexSubImageCubeAlignCaseInternal(
+ 'cube_rgba8_47_8', '', gl.RGBA8, 64, 10, 1, 47, 27, 8
+ )
+ );
+
+ // glTexSubImage2D() pixel transfer mode cases.
+ paramGroup = new tcuTestCase.DeqpTest(
+ 'texsubimage2d_unpack_params',
+ 'glTexSubImage2D() pixel transfer mode cases'
+ );
+ this.addChild(paramGroup);
+
+ cases = [{
+ name: 'rgb8_alignment', format: gl.RGB8, width: 54,
+ height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
+ rowLength: 0, skipRows: 0, skipPixels: 0, alignment: 2
+ }, {
+ name: 'rgb8_row_length', format: gl.RGB8, width: 54,
+ height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
+ rowLength: 50, skipRows: 0, skipPixels: 0, alignment: 4
+ }, {
+ name: 'rgb8_skip_rows', format: gl.RGB8, width: 54,
+ height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
+ rowLength: 0, skipRows: 3, skipPixels: 0, alignment: 4
+ }, {
+ name: 'rgb8_skip_pixels', format: gl.RGB8, width: 54,
+ height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
+ rowLength: 36, skipRows: 0, skipPixels: 5, alignment: 4
+ }, {
+ name: 'r8_complex1', format: gl.R8, width: 54,
+ height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
+ rowLength: 64, skipRows: 1, skipPixels: 3, alignment: 1
+ }, {
+ name: 'r8_complex2', format: gl.R8, width: 54,
+ height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
+ rowLength: 64, skipRows: 1, skipPixels: 3, alignment: 2
+ }, {
+ name: 'r8_complex3', format: gl.R8, width: 54,
+ height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
+ rowLength: 64, skipRows: 1, skipPixels: 3, alignment: 4
+ }, {
+ name: 'r8_complex4', format: gl.R8, width: 54,
+ height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
+ rowLength: 64, skipRows: 1, skipPixels: 3, alignment: 8
+ }, {
+ name: 'rgba8_complex1', format: gl.RGBA8, width: 92,
+ height: 84, subX: 13, subY: 19, subW: 56, subH: 61,
+ rowLength: 69, skipRows: 0, skipPixels: 0, alignment: 8
+ }, {
+ name: 'rgba8_complex2', format: gl.RGBA8, width: 92,
+ height: 84, subX: 13, subY: 19, subW: 56, subH: 61,
+ rowLength: 69, skipRows: 0, skipPixels: 7, alignment: 8
+ }, {
+ name: 'rgba8_complex3', format: gl.RGBA8, width: 92,
+ height: 84, subX: 13, subY: 19, subW: 56, subH: 61,
+ rowLength: 69, skipRows: 3, skipPixels: 0, alignment: 8
+ }, {
+ name: 'rgba8_complex4', format: gl.RGBA8, width: 92,
+ height: 84, subX: 13, subY: 19, subW: 56, subH: 61,
+ rowLength: 69, skipRows: 3, skipPixels: 7, alignment: 8
+ }, {
+ name: 'rgba32f_complex', format: gl.RGBA32F, width: 92,
+ height: 84, subX: 13, subY: 19, subW: 56, subH: 61,
+ rowLength: 69, skipRows: 3, skipPixels: 7, alignment: 8
+ }
+ ];
+
+ for (var ndx = 0; ndx < cases.length; ndx++)
+ paramGroup.addChild(
+ new es3fTextureSpecificationTests.TexSubImage2DParamsCase(
+ cases[ndx].name, '', cases[ndx].format, cases[ndx].width,
+ cases[ndx].height, cases[ndx].subX, cases[ndx].subY,
+ cases[ndx].subW, cases[ndx].subH, cases[ndx].rowLength,
+ cases[ndx].skipRows, cases[ndx].skipPixels,
+ cases[ndx].alignment
+ )
+ );
+
+ // glTexSubImage2D() PBO cases.
+ splitPboTex2D = 2;
+ splitPboTexCube = 5;
+ pboGroup2D = [];
+ for (var ii = 0; ii < splitPboTex2D; ++ii) {
+ pboGroup2D.push(new tcuTestCase.DeqpTest(
+ 'texsubimage2d_pbo',
+ 'glTexSubImage2D() pixel buffer object tests'
+ ));
+ this.addChild(pboGroup2D[ii]);
+ }
+ pboGroupCube = [];
+ for (var ii = 0; ii < splitPboTexCube; ++ii) {
+ pboGroupCube.push(new tcuTestCase.DeqpTest(
+ 'texsubimage2d_pbo',
+ 'glTexSubImage2D() pixel buffer object tests'
+ ));
+ this.addChild(pboGroupCube[ii]);
+ }
+
+ for (var ndx = 0; ndx < colorFormats.length; ndx++) {
+ pboGroup2D[ndx % splitPboTex2D].addChild(
+ new es3fTextureSpecificationTests.TexSubImage2DBufferCase(
+ colorFormats[ndx].name + '_2d', '',
+ colorFormats[ndx].internalFormat,
+ 54, // Width
+ 60, // Height
+ 11, // Sub X
+ 7, // Sub Y
+ 31, // Sub W
+ 30, // Sub H
+ 0, // Row len
+ 0, // Skip rows
+ 0, // Skip pixels
+ 4, // Alignment
+ 0 /* offset */
+ )
+ );
+ pboGroupCube[ndx % splitPboTexCube].addChild(
+ new es3fTextureSpecificationTests.TexSubImageCubeBufferCase(
+ colorFormats[ndx].name + '_cube', '',
+ colorFormats[ndx].internalFormat,
+ 64, // Size
+ 11, // Sub X
+ 7, // Sub Y
+ 31, // Sub W
+ 30, // Sub H
+ 0, // Row len
+ 0, // Skip rows
+ 0, // Skip pixels
+ 4, // Alignment
+ 0 /* offset */
+ )
+ );
+ }
+
+ pboGroupParams = new tcuTestCase.DeqpTest(
+ 'texsubimage2d_pbo',
+ 'glTexSubImage2D() pixel buffer object tests'
+ );
+ this.addChild(pboGroupParams);
+ /** @type {Array<{name: string, format: number, width: number,
+ * height: number, subX: number, subY: number,
+ * subW: number, subH: number, rowLength: number, skipRows: number,
+ * skipPixels: number, alignment: number, offset: number}>}
+ */
+ var paramCases = [{
+ name: 'rgb8_offset', format: gl.RGB8, width: 54,
+ height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
+ rowLength: 0, skipRows: 0, skipPixels: 0,
+ alignment: 4, offset: 67
+ }, {
+ name: 'rgb8_alignment', format: gl.RGB8, width: 54,
+ height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
+ rowLength: 0, skipRows: 0, skipPixels: 0,
+ alignment: 2, offset: 0
+ }, {
+ name: 'rgb8_row_length', format: gl.RGB8, width: 54,
+ height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
+ rowLength: 50, skipRows: 0, skipPixels: 0,
+ alignment: 4, offset: 0
+ }, {
+ name: 'rgb8_skip_rows', format: gl.RGB8, width: 54,
+ height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
+ rowLength: 0, skipRows: 3, skipPixels: 0,
+ alignment: 4, offset: 0
+ }, {
+ name: 'rgb8_skip_pixels', format: gl.RGB8, width: 54,
+ height: 60, subX: 11, subY: 7, subW: 31, subH: 30,
+ rowLength: 36, skipRows: 0, skipPixels: 5,
+ alignment: 4, offset: 0
+ }
+ ];
+
+ for (var ndx = 0; ndx < paramCases.length; ndx++) {
+ pboGroupParams.addChild(
+ new es3fTextureSpecificationTests.TexSubImage2DBufferCase(
+ paramCases[ndx].name + '_2d', '',
+ paramCases[ndx].format,
+ paramCases[ndx].width,
+ paramCases[ndx].height,
+ paramCases[ndx].subX,
+ paramCases[ndx].subY,
+ paramCases[ndx].subW,
+ paramCases[ndx].subH,
+ paramCases[ndx].rowLength,
+ paramCases[ndx].skipRows,
+ paramCases[ndx].skipPixels,
+ paramCases[ndx].alignment,
+ paramCases[ndx].offset));
+ pboGroupParams.addChild(
+ new es3fTextureSpecificationTests.TexSubImageCubeBufferCase(
+ paramCases[ndx].name + '_cube', '',
+ paramCases[ndx].format,
+ paramCases[ndx].width,
+ paramCases[ndx].subX,
+ paramCases[ndx].subY,
+ paramCases[ndx].subW,
+ paramCases[ndx].subH,
+ paramCases[ndx].rowLength,
+ paramCases[ndx].skipRows,
+ paramCases[ndx].skipPixels,
+ paramCases[ndx].alignment,
+ paramCases[ndx].offset
+ )
+ );
+ }
+
+ // glTexSubImage2D() depth cases.
+ shadow2dGroup = new tcuTestCase.DeqpTest(
+ 'texsubimage2d_depth',
+ 'glTexSubImage2D() with depth or depth/stencil format'
+ );
+ this.addChild(shadow2dGroup);
+
+ for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
+ // WebGL 2 specific constraint.
+ if (depthStencilFormats[ndx].internalFormat == gl.DEPTH32F_STENCIL8)
+ continue;
+ tex2DWidth = 64;
+ tex2DHeight = 32;
+
+ shadow2dGroup.addChild(
+ new es3fTextureSpecificationTests.TexSubImage2DDepthCase(
+ depthStencilFormats[ndx].name, '',
+ depthStencilFormats[ndx].internalFormat,
+ tex2DWidth, tex2DHeight
+ )
+ );
+ }
+
+ // Basic glCopyTexImage2D() cases
+ /** @type {tcuTestCase.DeqpTest} */
+ var copyTexImageGroup = new tcuTestCase.DeqpTest(
+ 'basic_copyteximage2d', 'Basic glCopyTexImage2D() usage'
+ );
+ this.addChild(copyTexImageGroup);
+
+ copyTexImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexImage2DCase(
+ '2d_alpha', '', gl.ALPHA, 128, 64
+ )
+ );
+ copyTexImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexImage2DCase(
+ '2d_luminance', '', gl.LUMINANCE, 128, 64
+ )
+ );
+ copyTexImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexImage2DCase(
+ '2d_luminance_alpha', '', gl.LUMINANCE_ALPHA, 128, 64
+ )
+ );
+ copyTexImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexImage2DCase(
+ '2d_rgb', '', gl.RGB, 128, 64
+ )
+ );
+ copyTexImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexImage2DCase(
+ '2d_rgba', '', gl.RGBA, 128, 64
+ )
+ );
+
+ copyTexImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexImageCubeCase(
+ 'cube_alpha', '', gl.ALPHA, 64
+ )
+ );
+ copyTexImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexImageCubeCase(
+ 'cube_luminance', '', gl.LUMINANCE, 64
+ )
+ );
+ copyTexImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexImageCubeCase(
+ 'cube_luminance_alpha', '', gl.LUMINANCE_ALPHA, 64
+ )
+ );
+ copyTexImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexImageCubeCase(
+ 'cube_rgb', '', gl.RGB, 64
+ )
+ );
+ copyTexImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexImageCubeCase(
+ 'cube_rgba', '', gl.RGBA, 64
+ )
+ );
+
+ // Basic glCopyTexSubImage2D() cases
+ /** @type {tcuTestCase.DeqpTest} */
+ var copyTexSubImageGroup = new tcuTestCase.DeqpTest(
+ 'basic_copytexsubimage2d', 'Basic glCopyTexSubImage2D() usage'
+ );
+ this.addChild(copyTexSubImageGroup);
+
+ copyTexSubImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase(
+ '2d_alpha', '', gl.ALPHA, gl.UNSIGNED_BYTE, 128, 64
+ )
+ );
+ copyTexSubImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase(
+ '2d_luminance', '', gl.LUMINANCE, gl.UNSIGNED_BYTE, 128, 64
+ )
+ );
+ copyTexSubImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase(
+ '2d_luminance_alpha', '', gl.LUMINANCE_ALPHA, gl.UNSIGNED_BYTE, 128, 64
+ )
+ );
+ copyTexSubImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase(
+ '2d_rgb', '', gl.RGB, gl.UNSIGNED_BYTE, 128, 64
+ )
+ );
+ copyTexSubImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexSubImage2DCase(
+ '2d_rgba', '', gl.RGBA, gl.UNSIGNED_BYTE, 128, 64
+ )
+ );
+
+ copyTexSubImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase(
+ 'cube_alpha', '', gl.ALPHA, gl.UNSIGNED_BYTE, 64
+ )
+ );
+ copyTexSubImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase(
+ 'cube_luminance', '', gl.LUMINANCE, gl.UNSIGNED_BYTE, 64
+ )
+ );
+ copyTexSubImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase(
+ 'cube_luminance_alpha', '', gl.LUMINANCE_ALPHA, gl.UNSIGNED_BYTE, 64
+ )
+ );
+ copyTexSubImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase(
+ 'cube_rgb', '', gl.RGB, gl.UNSIGNED_BYTE, 64
+ )
+ );
+ copyTexSubImageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicCopyTexSubImageCubeCase(
+ 'cube_rgba', '', gl.RGBA, gl.UNSIGNED_BYTE, 64
+ )
+ );
+
+ // Basic TexImage3D usage.
+ var splitBasicTex2DArray = 3, splitBasicTex3D = 5;
+ /** @type {Array<{tcuTestCase.DeqpTest}>} */
+ var basicTexImageGroup2DArray = [];
+ for (var ii = 0; ii < splitBasicTex2DArray; ++ii) {
+ basicTexImageGroup2DArray.push(
+ new tcuTestCase.DeqpTest('basic_teximage3d', 'Basic glTexImage3D() usage')
+ );
+ this.addChild(basicTexImageGroup2DArray[ii]);
+ }
+ /** @type {Array<{tcuTestCase.DeqpTest}>} */
+ var basicTexImageGroup3D = [];
+ for (var ii = 0; ii < splitBasicTex3D; ++ii) {
+ basicTexImageGroup3D.push(
+ new tcuTestCase.DeqpTest('basic_teximage3d', 'Basic glTexImage3D() usage')
+ );
+ this.addChild(basicTexImageGroup3D[ii]);
+ }
+ for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
+ fmtName = colorFormats[formatNdx].name;
+ format = colorFormats[formatNdx].internalFormat;
+ /** @type {number} */ var tex2DArrayWidth = 57;
+ /** @type {number} */ var tex2DArrayHeight = 44;
+ /** @type {number} */ var tex2DArrayLevels = 5;
+ /** @type {number} */ var tex3DWidth = 63;
+ /** @type {number} */ var tex3DHeight = 29;
+ /** @type {number} */ var tex3DDepth = 11;
+
+ basicTexImageGroup2DArray[formatNdx % splitBasicTex2DArray].addChild(
+ new es3fTextureSpecificationTests.BasicTexImage2DArrayCase(
+ fmtName + '_2d_array', '', format,
+ tex2DArrayWidth, tex2DArrayHeight, tex2DArrayLevels
+ )
+ );
+ basicTexImageGroup3D[formatNdx % splitBasicTex3D].addChild(
+ new es3fTextureSpecificationTests.BasicTexImage3DCase(
+ fmtName + '_3d', '', format,
+ tex3DWidth, tex3DHeight, tex3DDepth
+ )
+ );
+ }
+
+ // glTexImage3D() unpack params cases.
+ paramGroup = new tcuTestCase.DeqpTest(
+ 'teximage3d_unpack_params', 'glTexImage3D() unpack parameters'
+ );
+ this.addChild(paramGroup);
+
+ cases = [{
+ name: 'rgb8_image_height', format: gl.RGB8, width: 23,
+ height: 19, depth: 8, imageHeight: 26, rowLength: 0,
+ skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4
+ }, {
+ name: 'rgb8_row_length', format: gl.RGB8, width: 23,
+ height: 19, depth: 8, imageHeight: 0, rowLength: 27,
+ skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4
+ }, {
+ name: 'rgb8_skip_images', format: gl.RGB8, width: 23,
+ height: 19, depth: 8, imageHeight: 0, rowLength: 0,
+ skipImages: 3, skipRows: 0, skipPixels: 0, alignment: 4
+ }, {
+ name: 'rgb8_skip_rows', format: gl.RGB8, width: 23,
+ height: 19, depth: 8, imageHeight: 22, rowLength: 0,
+ skipImages: 0, skipRows: 3, skipPixels: 0, alignment: 4
+ }, {
+ name: 'rgb8_skip_pixels', format: gl.RGB8, width: 23,
+ height: 19, depth: 8, imageHeight: 0, rowLength: 25,
+ skipImages: 0, skipRows: 0, skipPixels: 2, alignment: 4
+ }, {
+ name: 'r8_complex1', format: gl.R8, width: 13,
+ height: 17, depth: 11, imageHeight: 23, rowLength: 15,
+ skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 1
+ }, {
+ name: 'r8_complex2', format: gl.R8, width: 13,
+ height: 17, depth: 11, imageHeight: 23, rowLength: 15,
+ skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 2
+ }, {
+ name: 'r8_complex3', format: gl.R8, width: 13,
+ height: 17, depth: 11, imageHeight: 23, rowLength: 15,
+ skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 4
+ }, {
+ name: 'r8_complex4', format: gl.R8, width: 13,
+ height: 17, depth: 11, imageHeight: 23, rowLength: 15,
+ skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 8
+ }, {
+ name: 'rgba8_complex1', format: gl.RGBA8, width: 11,
+ height: 20, depth: 8, imageHeight: 25, rowLength: 14,
+ skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 8
+ }, {
+ name: 'rgba8_complex2', format: gl.RGBA8, width: 11,
+ height: 20, depth: 8, imageHeight: 25, rowLength: 14,
+ skipImages: 0, skipRows: 2, skipPixels: 0, alignment: 8
+ }, {
+ name: 'rgba8_complex3', format: gl.RGBA8, width: 11,
+ height: 20, depth: 8, imageHeight: 25, rowLength: 14,
+ skipImages: 0, skipRows: 0, skipPixels: 3, alignment: 8
+ }, {
+ name: 'rgba8_complex4', format: gl.RGBA8, width: 11,
+ height: 20, depth: 8, imageHeight: 25, rowLength: 14,
+ skipImages: 0, skipRows: 2, skipPixels: 3, alignment: 8
+ }, {
+ name: 'rgba32f_complex', format: gl.RGBA32F, width: 11,
+ height: 20, depth: 8, imageHeight: 25, rowLength: 14,
+ skipImages: 0, skipRows: 2, skipPixels: 3, alignment: 8
+ }
+ ];
+
+ for (var ndx = 0; ndx < cases.length; ndx++)
+ paramGroup.addChild(
+ new es3fTextureSpecificationTests.TexImage3DParamsCase(
+ cases[ndx].name, '', cases[ndx].format, cases[ndx].width,
+ cases[ndx].height, cases[ndx].depth, cases[ndx].imageHeight,
+ cases[ndx].rowLength, cases[ndx].skipImages,
+ cases[ndx].skipRows, cases[ndx].skipPixels,
+ cases[ndx].alignment
+ )
+ );
+
+ // glTexImage3D() pbo cases.
+ var splitTex2DArray = 2, splitTex3D = 2;
+ /** @type {Array<{tcuTestCase.DeqpTest}>} */ var pboGroup2DArray = [];
+ for (var ii = 0; ii < splitTex2DArray; ++ii) {
+ pboGroup2DArray.push(
+ new tcuTestCase.DeqpTest('teximage3d_pbo', 'glTexImage3D() from PBO')
+ );
+ this.addChild(pboGroup2DArray[ii]);
+ }
+ /** @type {Array<{tcuTestCase.DeqpTest}>} */ var pboGroup3D = [];
+ for (var ii = 0; ii < splitTex3D; ++ii) {
+ pboGroup3D.push(
+ new tcuTestCase.DeqpTest('teximage3d_pbo', 'glTexImage3D() from PBO')
+ );
+ this.addChild(pboGroup3D[ii]);
+ }
+
+ for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
+ fmtName = colorFormats[formatNdx].name;
+ format = colorFormats[formatNdx].internalFormat;
+ tex3DWidth = 11;
+ tex3DHeight = 20;
+ tex3DDepth = 8;
+
+ pboGroup2DArray[formatNdx % splitTex2DArray].addChild(
+ new es3fTextureSpecificationTests.TexImage2DArrayBufferCase(
+ fmtName + '_2d_array', '', format, tex3DWidth, tex3DHeight,
+ tex3DDepth, 0, 0, 0, 0, 0, 4, 0
+ )
+ );
+ pboGroup3D[formatNdx % splitTex3D].addChild(
+ new es3fTextureSpecificationTests.TexImage3DBufferCase(
+ fmtName + '_3d', '', format, tex3DWidth, tex3DHeight,
+ tex3DDepth, 0, 0, 0, 0, 0, 4, 0
+ )
+ );
+ }
+
+ // Parameter cases
+ parameterCases = [{
+ name: 'rgb8_offset', format: gl.RGB8, width: 23,
+ height: 19, depth: 8, imageHeight: 0, rowLength: 0,
+ skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 1,
+ offset: 67
+ }, {
+ name: 'rgb8_alignment', format: gl.RGB8, width: 23,
+ height: 19, depth: 8, imageHeight: 0, rowLength: 0,
+ skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 2,
+ offset: 0
+ }, {
+ name: 'rgb8_image_height', format: gl.RGB8, width: 23,
+ height: 19, depth: 8, imageHeight: 26, rowLength: 0,
+ skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4,
+ offset: 0
+ }, {
+ name: 'rgb8_row_length', format: gl.RGB8, width: 23,
+ height: 19, depth: 8, imageHeight: 0, rowLength: 27,
+ skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4,
+ offset: 0
+ }, {
+ name: 'rgb8_skip_images', format: gl.RGB8, width: 23,
+ height: 19, depth: 8, imageHeight: 0, rowLength: 0,
+ skipImages: 3, skipRows: 0, skipPixels: 0, alignment: 4,
+ offset: 0
+ }, {
+ name: 'rgb8_skip_rows', format: gl.RGB8, width: 23,
+ height: 19, depth: 8, imageHeight: 22, rowLength: 0,
+ skipImages: 0, skipRows: 3, skipPixels: 0, alignment: 4,
+ offset: 0
+ }, {
+ name: 'rgb8_skip_pixels', format: gl.RGB8, width: 23,
+ height: 19, depth: 8, imageHeight: 0, rowLength: 25,
+ skipImages: 0, skipRows: 0, skipPixels: 2, alignment: 4,
+ offset: 0
+ }
+ ];
+
+ pboGroupParams = new tcuTestCase.DeqpTest('teximage3d_pbo', 'glTexImage3D() from PBO');
+ this.addChild(pboGroupParams);
+ for (var ndx = 0; ndx < parameterCases.length; ndx++) {
+ pboGroupParams.addChild(
+ new es3fTextureSpecificationTests.TexImage2DArrayBufferCase(
+ parameterCases[ndx].name + '_2d_array', '',
+ parameterCases[ndx].format, parameterCases[ndx].width,
+ parameterCases[ndx].height, parameterCases[ndx].depth,
+ parameterCases[ndx].imageHeight,
+ parameterCases[ndx].rowLength,
+ parameterCases[ndx].skipImages,
+ parameterCases[ndx].skipRows,
+ parameterCases[ndx].skipPixels,
+ parameterCases[ndx].alignment, parameterCases[ndx].offset
+ )
+ );
+ pboGroupParams.addChild(
+ new es3fTextureSpecificationTests.TexImage3DBufferCase(
+ parameterCases[ndx].name + '_3d', '',
+ parameterCases[ndx].format, parameterCases[ndx].width,
+ parameterCases[ndx].height, parameterCases[ndx].depth,
+ parameterCases[ndx].imageHeight,
+ parameterCases[ndx].rowLength,
+ parameterCases[ndx].skipImages,
+ parameterCases[ndx].skipRows,
+ parameterCases[ndx].skipPixels,
+ parameterCases[ndx].alignment, parameterCases[ndx].offset
+ )
+ );
+ }
+
+ // glTexImage3D() depth cases.
+ /** @type {tcuTestCase.DeqpTest} */
+ var shadow3dGroup = new tcuTestCase.DeqpTest(
+ 'teximage3d_depth',
+ 'glTexImage3D() with depth or depth/stencil format'
+ );
+ this.addChild(shadow3dGroup);
+
+ for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
+ // WebGL 2 specific constraint.
+ if (depthStencilFormats[ndx].internalFormat == gl.DEPTH32F_STENCIL8)
+ continue;
+ tex3DWidth = 32;
+ tex3DHeight = 64;
+ tex3DDepth = 8;
+
+ shadow3dGroup.addChild(
+ new es3fTextureSpecificationTests.TexImage2DArrayDepthCase(
+ depthStencilFormats[ndx].name + '_2d_array', '',
+ depthStencilFormats[ndx].internalFormat,
+ tex3DWidth, tex3DHeight, tex3DDepth
+ )
+ );
+ }
+
+ // glTexImage3D() depth cases with pbo.
+ shadow3dGroup = new tcuTestCase.DeqpTest(
+ 'teximage3d_depth_pbo',
+ 'glTexImage3D() with depth or depth/stencil format with pbo'
+ );
+ this.addChild(shadow3dGroup);
+
+ for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
+ tex3DWidth = 32;
+ tex3DHeight = 64;
+ tex3DDepth = 8;
+
+ shadow3dGroup.addChild(
+ new es3fTextureSpecificationTests.TexImage2DArrayDepthBufferCase(
+ depthStencilFormats[ndx].name + '_2d_array', '',
+ depthStencilFormats[ndx].internalFormat,
+ tex3DWidth, tex3DHeight, tex3DDepth
+ )
+ );
+ }
+
+ // Basic TexSubImage3D usage.
+ splitTex3D = 5;
+ /** @type {Array<{tcuTestCase.DeqpTest}>} */ var basicTexSubImageGroup = [];
+ for (var ii = 0; ii < splitTex3D; ++ii) {
+ basicTexSubImageGroup.push(
+ new tcuTestCase.DeqpTest('basic_texsubimage3d', 'Basic glTexSubImage3D() usage')
+ );
+ this.addChild(basicTexSubImageGroup[ii]);
+ }
+
+ for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
+ fmtName = colorFormats[formatNdx].name;
+ format = colorFormats[formatNdx].internalFormat;
+ tex3DWidth = 32;
+ tex3DHeight = 64;
+ tex3DDepth = 8;
+
+ basicTexSubImageGroup[formatNdx % splitTex3D].addChild(
+ new es3fTextureSpecificationTests.BasicTexSubImage3DCase(
+ fmtName + '_3d', '', format,
+ tex3DWidth, tex3DHeight, tex3DDepth
+ )
+ );
+ }
+
+ // glTexSubImage3D() unpack params cases.
+ paramGroup = new tcuTestCase.DeqpTest(
+ 'texsubimage3d_unpack_params', 'glTexSubImage3D() unpack parameters'
+ );
+ this.addChild(paramGroup);
+
+ /** @type {Array<{name: string, format: number, width: number,
+ * height: number, depth: number, subX: number, subY: number,
+ * subZ: number, subW: number, subH: number, subD: number,
+ * imageHeight: number, rowLength: number, skipImages: number,
+ * skipRows: number, skipPixels: number, alignment: number}>}
+ */
+ var casesSubImage3D = [{
+ name: 'rgb8_image_height', format: gl.RGB8, width: 26,
+ height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
+ subH: 19, subD: 8, imageHeight: 26, rowLength: 0,
+ skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4
+ }, {
+ name: 'rgb8_row_length', format: gl.RGB8, width: 26,
+ height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
+ subH: 19, subD: 8, imageHeight: 0, rowLength: 27,
+ skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 4
+ }, {
+ name: 'rgb8_skip_images', format: gl.RGB8, width: 26,
+ height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
+ subH: 19, subD: 8, imageHeight: 0, rowLength: 0,
+ skipImages: 3, skipRows: 0, skipPixels: 0, alignment: 4
+ }, {
+ name: 'rgb8_skip_rows', format: gl.RGB8, width: 26,
+ height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
+ subH: 19, subD: 8, imageHeight: 22, rowLength: 0,
+ skipImages: 0, skipRows: 3, skipPixels: 0, alignment: 4
+ }, {
+ name: 'rgb8_skip_pixels', format: gl.RGB8, width: 26,
+ height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
+ subH: 19, subD: 8, imageHeight: 0, rowLength: 25,
+ skipImages: 0, skipRows: 0, skipPixels: 2, alignment: 4
+ }, {
+ name: 'r8_complex1', format: gl.R8, width: 15,
+ height: 20, depth: 11, subX: 1, subY: 1, subZ: 0, subW: 13,
+ subH: 17, subD: 11, imageHeight: 23, rowLength: 15,
+ skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 1
+ }, {
+ name: 'r8_complex2', format: gl.R8, width: 15,
+ height: 20, depth: 11, subX: 1, subY: 1, subZ: 0, subW: 13,
+ subH: 17, subD: 11, imageHeight: 23, rowLength: 15,
+ skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 2
+ }, {
+ name: 'r8_complex3', format: gl.R8, width: 15,
+ height: 20, depth: 11, subX: 1, subY: 1, subZ: 0, subW: 13,
+ subH: 17, subD: 11, imageHeight: 23, rowLength: 15,
+ skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 4
+ }, {
+ name: 'r8_complex4', format: gl.R8, width: 15,
+ height: 20, depth: 11, subX: 1, subY: 1, subZ: 0, subW: 13,
+ subH: 17, subD: 11, imageHeight: 23, rowLength: 15,
+ skipImages: 2, skipRows: 3, skipPixels: 1, alignment: 8
+ }, {
+ name: 'rgba8_complex1', format: gl.RGBA8, width: 15,
+ height: 25, depth: 10, subX: 0, subY: 5, subZ: 1, subW: 11,
+ subH: 20, subD: 8, imageHeight: 25, rowLength: 14,
+ skipImages: 0, skipRows: 0, skipPixels: 0, alignment: 8
+ }, {
+ name: 'rgba8_complex2', format: gl.RGBA8, width: 15,
+ height: 25, depth: 10, subX: 0, subY: 5, subZ: 1, subW: 11,
+ subH: 20, subD: 8, imageHeight: 25, rowLength: 14,
+ skipImages: 0, skipRows: 2, skipPixels: 0, alignment: 8
+ }, {
+ name: 'rgba8_complex3', format: gl.RGBA8, width: 15,
+ height: 25, depth: 10, subX: 0, subY: 5, subZ: 1, subW: 11,
+ subH: 20, subD: 8, imageHeight: 25, rowLength: 14,
+ skipImages: 0, skipRows: 0, skipPixels: 3, alignment: 8
+ }, {
+ name: 'rgba8_complex4', format: gl.RGBA8, width: 15,
+ height: 25, depth: 10, subX: 0, subY: 5, subZ: 1, subW: 11,
+ subH: 20, subD: 8, imageHeight: 25, rowLength: 14,
+ skipImages: 0, skipRows: 2, skipPixels: 3, alignment: 8
+ }, {
+ name: 'rgba32f_complex', format: gl.RGBA32F, width: 15,
+ height: 25, depth: 10, subX: 0, subY: 5, subZ: 1, subW: 11,
+ subH: 20, subD: 8, imageHeight: 25, rowLength: 14,
+ skipImages: 0, skipRows: 2, skipPixels: 3, alignment: 8
+ }
+ ];
+
+ for (var ndx = 0; ndx < casesSubImage3D.length; ndx++)
+ paramGroup.addChild(
+ new es3fTextureSpecificationTests.TexSubImage3DParamsCase(
+ casesSubImage3D[ndx].name, '', casesSubImage3D[ndx].format,
+ casesSubImage3D[ndx].width, casesSubImage3D[ndx].height, casesSubImage3D[ndx].depth,
+ casesSubImage3D[ndx].subX, casesSubImage3D[ndx].subY, casesSubImage3D[ndx].subZ,
+ casesSubImage3D[ndx].subW, casesSubImage3D[ndx].subH, casesSubImage3D[ndx].subD,
+ casesSubImage3D[ndx].imageHeight, casesSubImage3D[ndx].rowLength,
+ casesSubImage3D[ndx].skipImages, casesSubImage3D[ndx].skipRows,
+ casesSubImage3D[ndx].skipPixels, casesSubImage3D[ndx].alignment
+ )
+ );
+
+ // glTexSubImage3D() PBO cases.
+ splitTex2DArray = 2;
+ pboGroup2DArray = [];
+ for (var ii = 0; ii < splitTex2DArray; ++ii) {
+ pboGroup2DArray.push(
+ new tcuTestCase.DeqpTest('texsubimage3d_pbo', 'glTexSubImage3D() pixel buffer object tests')
+ );
+ this.addChild(pboGroup2DArray[ii]);
+ }
+
+ splitTex3D = 2;
+ pboGroup3D = [];
+ for (var ii = 0; ii < splitTex3D; ++ii) {
+ pboGroup3D.push(
+ new tcuTestCase.DeqpTest('texsubimage3d_pbo', 'glTexSubImage3D() pixel buffer object tests')
+ );
+ this.addChild(pboGroup3D[ii]);
+ }
+
+ for (var ndx = 0; ndx < colorFormats.length; ndx++) {
+ pboGroup2DArray[ndx % splitTex2DArray].addChild(
+ new es3fTextureSpecificationTests.TexSubImage2DArrayBufferCase(
+ colorFormats[ndx].name + '_2d_array', '',
+ colorFormats[ndx].internalFormat,
+ 26, // Width
+ 25, // Height
+ 10, // Depth
+ 1, // Sub X
+ 2, // Sub Y
+ 0, // Sub Z
+ 23, // Sub W
+ 19, // Sub H
+ 8, // Sub D
+ 0, // Image height
+ 0, // Row length
+ 0, // Skip images
+ 0, // Skip rows
+ 0, // Skip pixels
+ 4, // Alignment
+ 0 // offset
+ )
+ );
+ pboGroup3D[ndx % splitTex3D].addChild(
+ new es3fTextureSpecificationTests.TexSubImage3DBufferCase(
+ colorFormats[ndx].name + '_3d', '',
+ colorFormats[ndx].internalFormat,
+ 26, // Width
+ 25, // Height
+ 10, // Depth
+ 1, // Sub X
+ 2, // Sub Y
+ 0, // Sub Z
+ 23, // Sub W
+ 19, // Sub H
+ 8, // Sub D
+ 0, // Image height
+ 0, // Row length
+ 0, // Skip images
+ 0, // Skip rows
+ 0, // Skip pixels
+ 4, // Alignment
+ 0 // offset
+ )
+ );
+ }
+
+ paramCases = [{
+ name: 'rgb8_offset', format: gl.RGB8, width: 26,
+ height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
+ subH: 19, subD: 8, imageHeight: 0, rowLength: 0, skipImages: 0,
+ skipRows: 0, skipPixels: 0, alignment: 4, offset: 67
+ }, {
+ name: 'rgb8_image_height', format: gl.RGB8, width: 26,
+ height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
+ subH: 19, subD: 8, imageHeight: 26, rowLength: 0, skipImages: 0,
+ skipRows: 0, skipPixels: 0, alignment: 4, offset: 0
+ }, {
+ name: 'rgb8_row_length', format: gl.RGB8, width: 26,
+ height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
+ subH: 19, subD: 8, imageHeight: 0, rowLength: 27, skipImages: 0,
+ skipRows: 0, skipPixels: 0, alignment: 4, offset: 0
+ }, {
+ name: 'rgb8_skip_images', format: gl.RGB8, width: 26,
+ height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
+ subH: 19, subD: 8, imageHeight: 0, rowLength: 0, skipImages: 3,
+ skipRows: 0, skipPixels: 0, alignment: 4, offset: 0
+ }, {
+ name: 'rgb8_skip_rows', format: gl.RGB8, width: 26,
+ height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
+ subH: 19, subD: 8, imageHeight: 22, rowLength: 0, skipImages: 0,
+ skipRows: 3, skipPixels: 0, alignment: 4, offset: 0
+ }, {
+ name: 'rgb8_skip_pixels', format: gl.RGB8, width: 26,
+ height: 25, depth: 10, subX: 1, subY: 2, subZ: 1, subW: 23,
+ subH: 19, subD: 8, imageHeight: 0, rowLength: 25, skipImages: 0,
+ skipRows: 0, skipPixels: 2, alignment: 4, offset: 0
+ }
+ ];
+
+ pboGroupParams = new tcuTestCase.DeqpTest(
+ 'texsubimage3d_pbo', 'glTexSubImage3D() pixel buffer object tests'
+ );
+ this.addChild(pboGroupParams);
+
+ for (var ndx = 0; ndx < paramCases.length; ndx++) {
+ pboGroupParams.addChild(
+ new es3fTextureSpecificationTests.TexSubImage2DArrayBufferCase(
+ paramCases[ndx].name + '_2d_array', '',
+ paramCases[ndx].format, paramCases[ndx].width,
+ paramCases[ndx].height, paramCases[ndx].depth,
+ paramCases[ndx].subX, paramCases[ndx].subY,
+ paramCases[ndx].subZ, paramCases[ndx].subW,
+ paramCases[ndx].subH, paramCases[ndx].subD,
+ paramCases[ndx].imageHeight, paramCases[ndx].rowLength,
+ paramCases[ndx].skipImages, paramCases[ndx].skipRows,
+ paramCases[ndx].skipPixels, paramCases[ndx].alignment,
+ paramCases[ndx].offset
+ )
+ );
+ pboGroupParams.addChild(
+ new es3fTextureSpecificationTests.TexSubImage3DBufferCase(
+ paramCases[ndx].name + '_3d', '',
+ paramCases[ndx].format, paramCases[ndx].width,
+ paramCases[ndx].height, paramCases[ndx].depth,
+ paramCases[ndx].subX, paramCases[ndx].subY,
+ paramCases[ndx].subZ, paramCases[ndx].subW,
+ paramCases[ndx].subH, paramCases[ndx].subD,
+ paramCases[ndx].imageHeight, paramCases[ndx].rowLength,
+ paramCases[ndx].skipImages, paramCases[ndx].skipRows,
+ paramCases[ndx].skipPixels, paramCases[ndx].alignment,
+ paramCases[ndx].offset
+ )
+ );
+ }
+
+ // glTexSubImage3D() depth cases.
+ shadow3dGroup = new tcuTestCase.DeqpTest(
+ 'texsubimage3d_depth',
+ 'glTexSubImage3D() with depth or depth/stencil format'
+ );
+ this.addChild(shadow3dGroup);
+
+ for (var ndx = 0; ndx < depthStencilFormats.length; ndx++) {
+ // WebGL 2 specific constraint.
+ if (depthStencilFormats[ndx].internalFormat == gl.DEPTH32F_STENCIL8)
+ continue;
+ tex2DArrayWidth = 57;
+ tex2DArrayHeight = 44;
+ tex2DArrayLevels = 5;
+
+ shadow3dGroup.addChild(
+ new es3fTextureSpecificationTests.TexSubImage2DArrayDepthCase(
+ depthStencilFormats[ndx].name + '_2d_array', '',
+ depthStencilFormats[ndx].internalFormat, tex2DArrayWidth,
+ tex2DArrayHeight, tex2DArrayLevels
+ )
+ );
+ }
+
+ // glTexStorage2D() cases.
+
+ // Color formats
+ var splitStorage2D = 3, splitStorageCube = 5;
+ /** @type {Array<{tcuTestCase.DeqpTest}>} */ var colorFormatGroup2D = [];
+ for (var ii = 0; ii < splitStorage2D; ++ii) {
+ colorFormatGroup2D.push(
+ new tcuTestCase.DeqpTest('texstorage2d.format', 'glTexStorage2D() with all formats')
+ );
+ this.addChild(colorFormatGroup2D[ii]);
+ }
+ /** @type {Array<{tcuTestCase.DeqpTest}>} */ var colorFormatGroupCube = [];
+ for (var ii = 0; ii < splitStorageCube; ++ii) {
+ colorFormatGroupCube.push(
+ new tcuTestCase.DeqpTest('texstorage2d.format', 'glTexStorage2D() with all formats')
+ );
+ this.addChild(colorFormatGroupCube[ii]);
+ }
+
+ for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
+ fmtName = colorFormats[formatNdx].name;
+ /** @type {number} */ var internalFormat = colorFormats[formatNdx].internalFormat;
+ var tex2DWidth = 117;
+ var tex2DHeight = 97;
+ var tex2DLevels = es3fTextureSpecificationTests.maxLevelCount(tex2DWidth, tex2DHeight);
+ /** @type {number} */ var cubeSize = 57;
+ /** @type {number} */
+ var cubeLevels = es3fTextureSpecificationTests.maxLevelCount(
+ cubeSize, cubeSize
+ );
+
+ colorFormatGroup2D[formatNdx % splitStorage2D].addChild(
+ new es3fTextureSpecificationTests.BasicTexStorage2DCase(
+ fmtName + '_2d', '', internalFormat,
+ tex2DWidth, tex2DHeight, tex2DLevels
+ )
+ );
+ colorFormatGroupCube[formatNdx % splitStorageCube].addChild(
+ new es3fTextureSpecificationTests.BasicTexStorageCubeCase(
+ fmtName + '_cube', '', internalFormat, cubeSize, cubeLevels
+ )
+ );
+ }
+
+ // Depth / stencil formats.
+ /** @type {tcuTestCase.DeqpTest} */
+ var storageGroup = new tcuTestCase.DeqpTest(
+ 'texstorage2d.format',
+ 'glTexStorage2D() with all formats'
+ );
+ this.addChild(storageGroup);
+
+ for (var formatNdx = 0; formatNdx < depthStencilFormats.length; formatNdx++) {
+ fmtName = depthStencilFormats[formatNdx].name;
+ internalFormat = depthStencilFormats[formatNdx].internalFormat;
+ // WebGL 2 specific constraint.
+ if (internalFormat == gl.DEPTH32F_STENCIL8)
+ continue;
+
+ tex2DWidth = 117;
+ tex2DHeight = 97;
+ tex2DLevels = es3fTextureSpecificationTests.maxLevelCount(
+ tex2DWidth, tex2DHeight
+ );
+ cubeSize = 57;
+ cubeLevels = es3fTextureSpecificationTests.maxLevelCount(
+ cubeSize, cubeSize
+ );
+
+ storageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicTexStorage2DCase(
+ fmtName + '_2d', '', internalFormat,
+ tex2DWidth, tex2DHeight, tex2DLevels
+ )
+ );
+ storageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicTexStorageCubeCase(
+ fmtName + '_cube', '', internalFormat, cubeSize, cubeLevels
+ )
+ );
+ }
+
+ // Sizes.
+ storageGroup = new tcuTestCase.DeqpTest(
+ 'texstorage2d.size',
+ 'glTexStorage2D() with various sizes'
+ );
+ this.addChild(storageGroup);
+
+ // W H L
+ /** @type {Array<{width: number, height: number, levels: number}>} */
+ var tex2DSizes = [{
+ width: 1, height: 1, levels: 1
+ }, {
+ width: 2, height: 2, levels: 2
+ }, {
+ width: 64, height: 32, levels: 7
+ }, {
+ width: 32, height: 64, levels: 4
+ }, {
+ width: 57, height: 63, levels: 1
+ }, {
+ width: 57, height: 63, levels: 2
+ }, {
+ width: 57, height: 63, levels: 6
+ }
+ ];
+
+ // S L
+ /** @type {Array<{sizes: number, levels: number}>} */
+ var cubeSizes = [{
+ sizes: 1, levels: 1
+ }, {
+ sizes: 2, levels: 2
+ }, {
+ sizes: 57, levels: 1
+ }, {
+ sizes: 57, levels: 2
+ }, {
+ sizes: 57, levels: 6
+ }, {
+ sizes: 64, levels: 4
+ }, {
+ sizes: 64, levels: 7
+ }
+ ];
+
+ for (var ndx = 0; ndx < tex2DSizes.length; ndx++) {
+ format = gl.RGBA8;
+ /** @type {number} */ var width = tex2DSizes[ndx].width;
+ /** @type {number} */ var height = tex2DSizes[ndx].height;
+ /** @type {number} */ var levels = tex2DSizes[ndx].levels;
+ /** @type {string} */
+ var name = '2d_' + width + 'x' + height + '_' + levels + '_levels';
+
+ storageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicTexStorage2DCase(
+ name, '', format, width, height, levels
+ )
+ );
+ }
+
+ for (var ndx = 0; ndx < cubeSizes.length; ndx++) {
+ format = gl.RGBA8;
+ size = cubeSizes[ndx].sizes;
+ levels = cubeSizes[ndx].levels;
+ name = 'cube_' + size + 'x' + size + '_' + levels + '_levels';
+
+ storageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicTexStorageCubeCase(
+ name, '', format, size, levels
+ )
+ );
+ }
+
+ // glTexStorage3D() cases.
+
+ // Color formats.
+ var splitStorage2DArray = 3, splitStorage3D = 4;
+ /** @type {Array<{tcuTestCase.DeqpTest}>} */ var colorFormatGroup2DArray = [];
+ for (var ii = 0; ii < splitStorage2DArray; ++ii) {
+ colorFormatGroup2DArray.push(
+ new tcuTestCase.DeqpTest('texstorage3d.format', 'glTexStorage3D() with all formats')
+ );
+ this.addChild(colorFormatGroup2DArray[ii]);
+ }
+ /** @type {Array<{tcuTestCase.DeqpTest}>} */ var colorFormatGroup3D = [];
+ for (var ii = 0; ii < splitStorage3D; ++ii) {
+ colorFormatGroup3D.push(
+ new tcuTestCase.DeqpTest('texstorage3d.format', 'glTexStorage3D() with all formats')
+ );
+ this.addChild(colorFormatGroup3D[ii]);
+ }
+
+ // Color formats.
+ for (var formatNdx = 0; formatNdx < colorFormats.length; formatNdx++) {
+ fmtName = colorFormats[formatNdx].name;
+ internalFormat = colorFormats[formatNdx].internalFormat;
+ tex2DArrayWidth = 57;
+ tex2DArrayHeight = 13;
+ var tex2DArrayLayers = 7;
+ tex2DArrayLevels = es3fTextureSpecificationTests.maxLevelCount(
+ tex2DArrayWidth, tex2DArrayHeight
+ );
+ tex3DWidth = 59;
+ tex3DHeight = 37;
+ tex3DDepth = 11;
+ var tex3DLevels = es3fTextureSpecificationTests.maxLevelCount(
+ tex3DWidth, tex3DHeight, tex3DDepth
+ );
+
+ colorFormatGroup2DArray[formatNdx % splitStorage2DArray].addChild(
+ new es3fTextureSpecificationTests.BasicTexStorage2DArrayCase(
+ fmtName + '_2d_array', '', internalFormat, tex2DArrayWidth,
+ tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels
+ )
+ );
+ colorFormatGroup3D[formatNdx % splitStorage3D].addChild(
+ new es3fTextureSpecificationTests.BasicTexStorage3DCase(
+ fmtName + '_3d', '', internalFormat, tex3DWidth,
+ tex3DHeight, tex3DDepth, tex3DLevels
+ )
+ );
+ }
+
+ storageGroup = new tcuTestCase.DeqpTest(
+ 'texstorage3d.format',
+ 'glTexStorage3D() with all formats'
+ );
+ this.addChild(storageGroup);
+
+ // Depth/stencil formats (only 2D texture array is supported).
+ for (var formatNdx = 0;
+ formatNdx < depthStencilFormats.length;
+ formatNdx++) {
+ fmtName = depthStencilFormats[formatNdx].name;
+ internalFormat = depthStencilFormats[formatNdx].internalFormat;
+ // WebGL 2 specific constraint.
+ if (internalFormat == gl.DEPTH32F_STENCIL8)
+ continue;
+
+ tex2DArrayWidth = 57;
+ tex2DArrayHeight = 13;
+ tex2DArrayLayers = 7;
+ tex2DArrayLevels = es3fTextureSpecificationTests.maxLevelCount(
+ tex2DArrayWidth, tex2DArrayHeight
+ );
+
+ storageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicTexStorage2DArrayCase(
+ fmtName + '_2d_array', '', internalFormat, tex2DArrayWidth,
+ tex2DArrayHeight, tex2DArrayLayers, tex2DArrayLevels
+ )
+ );
+ }
+
+ // Sizes.
+ // W H La Le
+ /**
+ * @type {Array<{width: number, height: number,
+ * layers: number, levels: number}>}
+ */
+ var tex2DArraySizes = [{
+ width: 1, height: 1, layers: 1, levels: 1
+ }, {
+ width: 2, height: 2, layers: 2, levels: 2
+ }, {
+ width: 64, height: 32, layers: 3, levels: 7
+ }, {
+ width: 32, height: 64, layers: 3, levels: 4
+ }, {
+ width: 57, height: 63, layers: 5, levels: 1
+ }, {
+ width: 57, height: 63, layers: 5, levels: 2
+ }, {
+ width: 57, height: 63, layers: 5, levels: 6
+ }
+ ];
+
+ // W H D L
+ /**
+ * @type {Array<{width: number, height: number,
+ * depth: number, levels: number}>}
+ */
+ var tex3DSizes = [{
+ width: 1, height: 1, depth: 1, levels: 1
+ }, {
+ width: 2, height: 2, depth: 2, levels: 2
+ }, {
+ width: 64, height: 32, depth: 16, levels: 7
+ }, {
+ width: 32, height: 64, depth: 16, levels: 4
+ }, {
+ width: 32, height: 16, depth: 64, levels: 4
+ }, {
+ width: 57, height: 63, depth: 11, levels: 1
+ }, {
+ width: 57, height: 63, depth: 11, levels: 2
+ }, {
+ width: 57, height: 63, depth: 11, levels: 6
+ }
+ ];
+
+ storageGroup = new tcuTestCase.DeqpTest(
+ 'texstorage3d.size', 'glTexStorage3D() with various sizes'
+ );
+ this.addChild(storageGroup);
+
+ for (var ndx = 0; ndx < tex2DArraySizes.length; ndx++) {
+ format = gl.RGBA8;
+ width = tex2DArraySizes[ndx].width;
+ height = tex2DArraySizes[ndx].height;
+ /** @type {number} */ var layers = tex2DArraySizes[ndx].layers;
+ levels = tex2DArraySizes[ndx].levels;
+ name = '2d_array_' + width + 'x' + height + 'x' +
+ layers + '_' + levels + '_levels';
+
+ storageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicTexStorage2DArrayCase(
+ name, '', format, width, height, layers, levels
+ )
+ );
+ }
+
+ for (var ndx = 0; ndx < tex3DSizes.length; ndx++) {
+ format = gl.RGBA8;
+ width = tex3DSizes[ndx].width;
+ height = tex3DSizes[ndx].height;
+ var depth = tex3DSizes[ndx].depth;
+ levels = tex3DSizes[ndx].levels;
+ name = '3d_' + width + 'x' + height + 'x' +
+ depth + '_' + levels + '_levels';
+
+ storageGroup.addChild(
+ new es3fTextureSpecificationTests.BasicTexStorage3DCase(
+ name, '', format, width, height, depth, levels
+ )
+ );
+ }
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ * @param {Array<number>=} range Test range
+ */
+ es3fTextureSpecificationTests.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fTextureSpecificationTests.TextureSpecificationTests());
+ if (range)
+ state.setRange(range);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fTextureSpecificationTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureStateQuery.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureStateQuery.js
new file mode 100644
index 0000000000..ab1f4d6bb9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureStateQuery.js
@@ -0,0 +1,376 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fTextureStateQuery');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('functional.gles3.es3fApiCase');
+goog.require('modules.shared.glsStateQuery');
+
+goog.scope(function() {
+var es3fTextureStateQuery = functional.gles3.es3fTextureStateQuery;
+var tcuTestCase = framework.common.tcuTestCase;
+var glsStateQuery = modules.shared.glsStateQuery;
+var es3fApiCase = functional.gles3.es3fApiCase;
+var deRandom = framework.delibs.debase.deRandom;
+
+var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+};
+
+/**
+ * @constructor
+ * @extends {es3fApiCase.ApiCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} textureTarget
+ */
+es3fTextureStateQuery.TextureCase = function(name, description, textureTarget) {
+ es3fApiCase.ApiCase.call(this, name, description, gl);
+ /** @type {WebGLTexture} */ this.m_texture;
+ this.m_textureTarget = textureTarget;
+};
+
+setParentClass(es3fTextureStateQuery.TextureCase, es3fApiCase.ApiCase);
+
+es3fTextureStateQuery.TextureCase.prototype.testTexture = function() {
+ throw new Error('Virtual function. Please override.');
+};
+
+es3fTextureStateQuery.TextureCase.prototype.test = function() {
+ this.m_texture = gl.createTexture();
+ gl.bindTexture(this.m_textureTarget, this.m_texture);
+
+ this.testTexture();
+
+ gl.bindTexture(this.m_textureTarget, null);
+ gl.deleteTexture(this.m_texture);
+};
+
+/**
+ * @constructor
+ * @extends {es3fTextureStateQuery.TextureCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} textureTarget
+ */
+es3fTextureStateQuery.IsTextureCase = function(name, description, textureTarget) {
+ es3fTextureStateQuery.TextureCase.call(this, name, description, textureTarget);
+};
+
+setParentClass(es3fTextureStateQuery.IsTextureCase, es3fTextureStateQuery.TextureCase);
+
+es3fTextureStateQuery.IsTextureCase.prototype.testTexture = function() {
+ this.check(glsStateQuery.compare(gl.isTexture(this.m_texture), true), 'gl.isTexture() should have returned true');
+};
+
+/**
+ * @constructor
+ * @extends {es3fTextureStateQuery.TextureCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} textureTarget
+ * @param {number} valueName
+ * @param {number} initialValue
+ * @param {Array<number>} valueRange
+ */
+es3fTextureStateQuery.TextureParamCase = function(name, description, textureTarget, valueName, initialValue, valueRange) {
+ es3fTextureStateQuery.TextureCase.call(this, name, description, textureTarget);
+ this.m_valueName = valueName;
+ this.m_initialValue = initialValue;
+ this.m_valueRange = valueRange;
+};
+
+setParentClass(es3fTextureStateQuery.TextureParamCase, es3fTextureStateQuery.TextureCase);
+
+es3fTextureStateQuery.TextureParamCase.prototype.testTexture = function() {
+ this.check(glsStateQuery.verifyTexture(this.m_textureTarget, this.m_valueName, this.m_initialValue));
+
+ for (var ndx = 0; ndx < this.m_valueRange.length; ++ndx) {
+ gl.texParameteri(this.m_textureTarget, this.m_valueName, this.m_valueRange[ndx]);
+
+ this.check(glsStateQuery.verifyTexture(this.m_textureTarget, this.m_valueName, this.m_valueRange[ndx]));
+ }
+
+ //check unit conversions with float
+
+ for (var ndx = 0; ndx < this.m_valueRange.length; ++ndx) {
+ gl.texParameterf(this.m_textureTarget, this.m_valueName, this.m_valueRange[ndx]);
+
+ this.check(glsStateQuery.verifyTexture(this.m_textureTarget, this.m_valueName, this.m_valueRange[ndx]));
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fTextureStateQuery.TextureCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} textureTarget
+ * @param {number} lodTarget
+ * @param {number} initialValue
+ */
+es3fTextureStateQuery.TextureLODCase = function(name, description, textureTarget, lodTarget, initialValue) {
+ es3fTextureStateQuery.TextureCase.call(this, name, description, textureTarget);
+ this.m_lodTarget = lodTarget;
+ this.m_initialValue = initialValue;
+};
+
+setParentClass(es3fTextureStateQuery.TextureLODCase, es3fTextureStateQuery.TextureCase);
+
+es3fTextureStateQuery.TextureLODCase.prototype.testTexture = function() {
+ var rnd = new deRandom.Random(0xabcdef);
+
+ this.check(glsStateQuery.verifyTexture(this.m_textureTarget, this.m_lodTarget, this.m_initialValue));
+
+ var numIterations = 60;
+ for (var ndx = 0; ndx < numIterations; ++ndx) {
+ var ref = rnd.getFloat(-64000, 64000);
+
+ gl.texParameterf(this.m_textureTarget, this.m_lodTarget, ref);
+
+ this.check(glsStateQuery.verifyTexture(this.m_textureTarget, this.m_lodTarget, ref));
+ }
+
+ // check unit conversions with int
+
+ for (var ndx = 0; ndx < numIterations; ++ndx) {
+ var ref = rnd.getInt(-64000, 64000);
+
+ gl.texParameteri(this.m_textureTarget, this.m_lodTarget, ref);
+
+ this.check(glsStateQuery.verifyTexture(this.m_textureTarget, this.m_lodTarget, ref));
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fTextureStateQuery.TextureCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} textureTarget
+ * @param {number} levelTarget
+ * @param {number} initialValue
+ */
+es3fTextureStateQuery.TextureLevelCase = function(name, description, textureTarget, levelTarget, initialValue) {
+ es3fTextureStateQuery.TextureCase.call(this, name, description, textureTarget);
+ this.m_levelTarget = levelTarget;
+ this.m_initialValue = initialValue;
+};
+
+setParentClass(es3fTextureStateQuery.TextureLevelCase, es3fTextureStateQuery.TextureCase);
+
+es3fTextureStateQuery.TextureLevelCase.prototype.testTexture = function() {
+ var rnd = new deRandom.Random(0xabcdef);
+
+ this.check(glsStateQuery.verifyTexture(this.m_textureTarget, this.m_levelTarget, this.m_initialValue));
+
+ var numIterations = 60;
+ for (var ndx = 0; ndx < numIterations; ++ndx) {
+ var ref = rnd.getInt(0, 64000);
+
+ gl.texParameteri(this.m_textureTarget, this.m_levelTarget, ref);
+
+ this.check(glsStateQuery.verifyTexture(this.m_textureTarget, this.m_levelTarget, ref));
+ }
+
+ // check unit conversions with float
+ var nonSignificantOffsets = [-0.45, -0.25, 0, 0.45]; // offsets O so that for any integers z in Z, o in O roundToClosestInt(z+o)==z
+
+ for (var ndx = 0; ndx < numIterations; ++ndx) {
+ var ref = rnd.getInt(0, 64000);
+
+ for (var i = 0; i < nonSignificantOffsets.length; i++) {
+ gl.texParameterf(this.m_textureTarget, this.m_levelTarget, ref + nonSignificantOffsets[i]);
+ this.check(glsStateQuery.verifyTexture(this.m_textureTarget, this.m_levelTarget, ref));
+ }
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fTextureStateQuery.TextureCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} textureTarget
+ */
+es3fTextureStateQuery.TextureImmutableLevelsCase = function(name, description, textureTarget) {
+ es3fTextureStateQuery.TextureCase.call(this, name, description, textureTarget);
+};
+
+setParentClass(es3fTextureStateQuery.TextureImmutableLevelsCase, es3fTextureStateQuery.TextureCase);
+
+es3fTextureStateQuery.TextureImmutableLevelsCase.prototype.testTexture = function() {
+ this.check(glsStateQuery.verifyTexture(this.m_textureTarget, gl.TEXTURE_IMMUTABLE_LEVELS, 0));
+ for (var level = 1; level <= 8; ++level) {
+ var textureID = gl.createTexture();
+ gl.bindTexture(this.m_textureTarget, textureID);
+
+ if (this.m_textureTarget == gl.TEXTURE_2D_ARRAY || this.m_textureTarget == gl.TEXTURE_3D)
+ gl.texStorage3D(this.m_textureTarget, level, gl.RGB8, 256, 256, 256);
+ else
+ gl.texStorage2D(this.m_textureTarget, level, gl.RGB8, 256, 256);
+
+ this.check(glsStateQuery.verifyTexture(this.m_textureTarget, gl.TEXTURE_IMMUTABLE_LEVELS, level));
+ gl.deleteTexture(textureID);
+ }
+};
+
+/**
+ * @constructor
+ * @extends {es3fTextureStateQuery.TextureCase}
+ * @param {string} name
+ * @param {string} description
+ * @param {number} textureTarget
+ */
+es3fTextureStateQuery.TextureImmutableFormatCase = function(name, description, textureTarget) {
+ es3fTextureStateQuery.TextureCase.call(this, name, description, textureTarget);
+};
+
+setParentClass(es3fTextureStateQuery.TextureImmutableFormatCase, es3fTextureStateQuery.TextureCase);
+
+es3fTextureStateQuery.TextureImmutableFormatCase.prototype.testTexture = function() {
+ this.check(glsStateQuery.verifyTexture(this.m_textureTarget, gl.TEXTURE_IMMUTABLE_LEVELS, 0));
+ var testSingleFormat = function(format) {
+ var textureID = gl.createTexture();
+ gl.bindTexture(this.m_textureTarget, textureID);
+
+ if (this.m_textureTarget == gl.TEXTURE_2D_ARRAY || this.m_textureTarget == gl.TEXTURE_3D)
+ gl.texStorage3D(this.m_textureTarget, 1, format, 32, 32, 32);
+ else
+ gl.texStorage2D(this.m_textureTarget, 1, format, 32, 32);
+
+ this.check(glsStateQuery.verifyTexture(this.m_textureTarget, gl.TEXTURE_IMMUTABLE_FORMAT, 1));
+ gl.deleteTexture(textureID);
+ };
+
+ var formats = [
+ gl.RGBA32I, gl.RGBA32UI, gl.RGBA16I, gl.RGBA16UI, gl.RGBA8, gl.RGBA8I,
+ gl.RGBA8UI, gl.SRGB8_ALPHA8, gl.RGB10_A2, gl.RGB10_A2UI, gl.RGBA4,
+ gl.RGB5_A1, gl.RGB8, gl.RGB565, gl.RG32I, gl.RG32UI, gl.RG16I, gl.RG16UI,
+ gl.RG8, gl.RG8I, gl.RG8UI, gl.R32I, gl.R32UI, gl.R16I, gl.R16UI, gl.R8,
+ gl.R8I, gl.R8UI,
+
+ gl.RGBA32F, gl.RGBA16F, gl.RGBA8_SNORM, gl.RGB32F,
+ gl.RGB32I, gl.RGB32UI, gl.RGB16F, gl.RGB16I, gl.RGB16UI, gl.RGB8_SNORM,
+ gl.RGB8I, gl.RGB8UI, gl.SRGB8, gl.R11F_G11F_B10F, gl.RGB9_E5, gl.RG32F,
+ gl.RG16F, gl.RG8_SNORM, gl.R32F, gl.R16F, gl.R8_SNORM
+ ];
+
+ var non3dFormats = [
+ gl.DEPTH_COMPONENT32F, gl.DEPTH_COMPONENT24, gl.DEPTH_COMPONENT16,
+ gl.DEPTH32F_STENCIL8, gl.DEPTH24_STENCIL8
+ ];
+
+ for (var formatNdx = 0; formatNdx < formats.length; ++formatNdx)
+ testSingleFormat.bind(this, formats[formatNdx]);
+
+ if (this.m_textureTarget != gl.TEXTURE_3D)
+ for (var formatNdx = 0; formatNdx < non3dFormats.length; ++formatNdx)
+ testSingleFormat.bind(this, non3dFormats[formatNdx]);
+};
+
+/**
+* @constructor
+* @extends {tcuTestCase.DeqpTest}
+*/
+es3fTextureStateQuery.TextureStateQuery = function() {
+ tcuTestCase.DeqpTest.call(this, 'texture', 'Texture State Query tests');
+};
+
+es3fTextureStateQuery.TextureStateQuery.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fTextureStateQuery.TextureStateQuery.prototype.constructor = es3fTextureStateQuery.TextureStateQuery;
+
+es3fTextureStateQuery.TextureStateQuery.prototype.init = function() {
+ var textureTargets = [
+ ['texture_2d', gl.TEXTURE_2D],
+ ['texture_3d', gl.TEXTURE_3D],
+ ['texture_2d_array', gl.TEXTURE_2D_ARRAY],
+ ['texture_cube_map', gl.TEXTURE_CUBE_MAP]
+ ];
+
+ var state = this;
+ var wrapValues = [gl.CLAMP_TO_EDGE, gl.REPEAT, gl.MIRRORED_REPEAT];
+ var magValues = [gl.NEAREST, gl.LINEAR];
+ var minValues = [gl.NEAREST, gl.LINEAR, gl.NEAREST_MIPMAP_NEAREST, gl.NEAREST_MIPMAP_LINEAR, gl.LINEAR_MIPMAP_NEAREST, gl.LINEAR_MIPMAP_LINEAR];
+ var modes = [gl.COMPARE_REF_TO_TEXTURE, gl.NONE];
+ var compareFuncs = [gl.LEQUAL, gl.GEQUAL, gl.LESS, gl.GREATER, gl.EQUAL, gl.NOTEQUAL, gl.ALWAYS, gl.NEVER];
+ textureTargets.forEach(function(elem) {
+ var name = elem[0];
+ var target = elem[1];
+ state.addChild(new es3fTextureStateQuery.IsTextureCase(name + '_is_texture', 'IsTexture', target));
+ state.addChild(new es3fTextureStateQuery.TextureParamCase(name + '_texture_wrap_s' , 'TEXTURE_WRAP_S',
+ target, gl.TEXTURE_WRAP_S, gl.REPEAT, wrapValues));
+ if (target == gl.TEXTURE_2D ||
+ target == gl.TEXTURE_3D ||
+ target == gl.TEXTURE_CUBE_MAP)
+ state.addChild(new es3fTextureStateQuery.TextureParamCase(name + '_texture_wrap_t' , 'TEXTURE_WRAP_T',
+ target, gl.TEXTURE_WRAP_T, gl.REPEAT, wrapValues));
+
+ if (target == gl.TEXTURE_3D)
+ state.addChild(new es3fTextureStateQuery.TextureParamCase(name + '_texture_wrap_r' , 'TEXTURE_WRAP_R',
+ target, gl.TEXTURE_WRAP_R, gl.REPEAT, wrapValues));
+
+ state.addChild(new es3fTextureStateQuery.TextureParamCase(name + '_texture_mag_filter' , 'TEXTURE_MAG_FILTER',
+ target, gl.TEXTURE_MAG_FILTER, gl.LINEAR, magValues));
+ state.addChild(new es3fTextureStateQuery.TextureParamCase(name + '_texture_min_filter' , 'TEXTURE_MIN_FILTER',
+ target, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_LINEAR, minValues));
+ state.addChild(new es3fTextureStateQuery.TextureLODCase(name + '_texture_min_lod' , 'TEXTURE_MIN_LOD', target, gl.TEXTURE_MIN_LOD, -1000));
+ state.addChild(new es3fTextureStateQuery.TextureLODCase(name + '_texture_max_lod' , 'TEXTURE_MAX_LOD', target, gl.TEXTURE_MAX_LOD, 1000));
+ state.addChild(new es3fTextureStateQuery.TextureLevelCase(name + '_texture_base_level' , 'TEXTURE_BASE_LEVEL', target, gl.TEXTURE_BASE_LEVEL, 0));
+ state.addChild(new es3fTextureStateQuery.TextureLevelCase(name + '_texture_max_level' , 'TEXTURE_MAX_LEVEL', target, gl.TEXTURE_MAX_LEVEL, 1000));
+
+ state.addChild(new es3fTextureStateQuery.TextureParamCase(name + '_texture_compare_mode' , 'TEXTURE_COMPARE_MODE',
+ target, gl.TEXTURE_COMPARE_MODE, gl.NONE, modes));
+ state.addChild(new es3fTextureStateQuery.TextureParamCase(name + '_texture_compare_func' , 'TEXTURE_COMPARE_FUNC',
+ target, gl.TEXTURE_COMPARE_FUNC, gl.LEQUAL, compareFuncs));
+
+ state.addChild(new es3fTextureStateQuery.TextureImmutableLevelsCase(name + '_texture_immutable_levels', 'TEXTURE_IMMUTABLE_LEVELS', target));
+ state.addChild(new es3fTextureStateQuery.TextureImmutableFormatCase(name + '_texture_immutable_format', 'TEXTURE_IMMUTABLE_FORMAT', target));
+ });
+};
+
+/**
+* Run test
+* @param {WebGL2RenderingContext} context
+*/
+es3fTextureStateQuery.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fTextureStateQuery.TextureStateQuery());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fTextureStateQuery.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureWrapTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureWrapTests.js
new file mode 100644
index 0000000000..a6d6e96d14
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTextureWrapTests.js
@@ -0,0 +1,434 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fTextureWrapTests');
+goog.require('framework.common.tcuCompressedTexture');
+goog.require('framework.common.tcuPixelFormat');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexLookupVerifier');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.common.tcuTextureUtil');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTexture');
+goog.require('framework.opengl.gluTextureUtil');
+goog.require('modules.shared.glsTextureTestUtil');
+
+goog.scope(function() {
+ /** @type {?WebGL2RenderingContext} */ var gl;
+
+ var es3fTextureWrapTests = functional.gles3.es3fTextureWrapTests;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var gluTexture = framework.opengl.gluTexture;
+ var gluTextureUtil = framework.opengl.gluTextureUtil;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var glsTextureTestUtil = modules.shared.glsTextureTestUtil;
+ var tcuCompressedTexture = framework.common.tcuCompressedTexture;
+ var deRandom = framework.delibs.debase.deRandom;
+ var deMath = framework.delibs.debase.deMath;
+ var tcuPixelFormat = framework.common.tcuPixelFormat;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuTexLookupVerifier = framework.common.tcuTexLookupVerifier;
+ var tcuTexture = framework.common.tcuTexture;
+ var tcuTextureUtil = framework.common.tcuTextureUtil;
+ var deString = framework.delibs.debase.deString;
+
+ /**
+ * @enum {number}
+ */
+ var Viewport = {
+ WIDTH: 256,
+ HEIGHT: 256
+ };
+
+ /**
+ * @constructor
+ * @param {Array<number>=} bl
+ * @param {Array<number>=} tr
+ */
+ es3fTextureWrapTests.Case = function(bl, tr) {
+ /** @type {?Array<number>} */ this.bottomLeft = bl || null;
+ /** @type {?Array<number>} */ this.topRight = tr || null;
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} description
+ * @param {?tcuCompressedTexture.Format} compressedFormat
+ * @param {number} wrapS
+ * @param {number} wrapT
+ * @param {number} minFilter
+ * @param {number} magFilter
+ * @param {number} width
+ * @param {number} height
+ */
+ es3fTextureWrapTests.TextureWrapCase = function(name, description, compressedFormat, wrapS, wrapT, minFilter, magFilter, width, height) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ /** @type {number} */ this.m_format = gl.NONE;
+ /** @type {number} */ this.m_dataType = gl.NONE;
+ /** @type {?tcuCompressedTexture.Format} */ this.m_compressedFormat = compressedFormat;
+ /** @type {number} */ this.m_wrapS = wrapS;
+ /** @type {number} */ this.m_wrapT = wrapT;
+ /** @type {number} */ this.m_minFilter = minFilter;
+ /** @type {number} */ this.m_magFilter = magFilter;
+ /** @type {number} */ this.m_width = width;
+ /** @type {number} */ this.m_height = height;
+ /** @type {Array<es3fTextureWrapTests.Case>} */ this.m_cases = [];
+ /** @type {number} */ this.m_caseNdx = 0;
+ /** @type {gluTexture.Texture2D} */ this.m_texture = null;
+ /** @type {glsTextureTestUtil.TextureRenderer} */
+ this.m_renderer = new glsTextureTestUtil.TextureRenderer(gluShaderUtil.getGLSLVersionString(gluShaderUtil.GLSLVersion.V300_ES), gluShaderUtil.precision.PRECISION_MEDIUMP);
+ };
+
+ es3fTextureWrapTests.TextureWrapCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+
+ /** Copy the constructor */
+ es3fTextureWrapTests.TextureWrapCase.prototype.constructor = es3fTextureWrapTests.TextureWrapCase;
+
+ /**
+ * @param {string} name
+ * @param {string} description
+ * @param {number} format
+ * @param {number} dataType
+ * @param {number} wrapS
+ * @param {number} wrapT
+ * @param {number} minFilter
+ * @param {number} magFilter
+ * @param {number} width
+ * @param {number} height
+ * @return {es3fTextureWrapTests.TextureWrapCase}
+ */
+ es3fTextureWrapTests.textureWrapCaseFromFormat = function(name, description, format, dataType, wrapS, wrapT, minFilter, magFilter, width, height) {
+ var texWrapCase = new es3fTextureWrapTests.TextureWrapCase(name, description, null, wrapS, wrapT, minFilter, magFilter, width, height);
+ texWrapCase.m_format = gl.RGBA;
+ texWrapCase.m_dataType = gl.UNSIGNED_BYTE;
+ return texWrapCase;
+ };
+
+ /**
+ */
+ es3fTextureWrapTests.TextureWrapCase.prototype.init = function() {
+ if (this.m_compressedFormat !== null) {
+ // Generate compressed texture.
+
+ assertMsgOptions(this.m_format == gl.NONE && this.m_dataType == gl.NONE, 'init/compressedFormat', false, true);
+ if (tcuCompressedTexture.isEtcFormat(this.m_compressedFormat)) {
+ // Create ETC texture. Any content is valid.
+
+ /** @type {tcuCompressedTexture.CompressedTexture}*/
+ var compressedTexture = new tcuCompressedTexture.CompressedTexture(this.m_compressedFormat, this.m_width, this.m_height);
+ /** @type {number} */ var dataSize = compressedTexture.getDataSize();
+ /** @type {goog.NumberArray} */ var data = compressedTexture.getData();
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name));
+
+ for (var i = 0; i < dataSize; i++)
+ data[i] = rnd.getFloat() & 0xff;
+
+ this.m_texture = gluTexture.texture2DFromCompressedTexture(gl, 1, [compressedTexture]);
+ } else
+ throw new Error('Only ETC2 and EAC are supported.');
+ } else{
+ this.m_texture = gluTexture.texture2DFromFormat(gl, this.m_format, this.m_dataType, this.m_width, this.m_height);
+
+ // Fill level 0.
+ this.m_texture.getRefTexture().allocLevel(0);
+ tcuTextureUtil.fillWithComponentGradients(this.m_texture.getRefTexture().getLevel(0), [-0.5, -0.5, -0.5, 2.0], [1.0, 1.0, 1.0, 0.0]);
+
+ this.m_texture.upload();
+ }
+
+ // Sub-cases.
+
+ this.m_cases.push(new es3fTextureWrapTests.Case([-1.5, -3.0], [1.5, 2.5]));
+ this.m_cases.push(new es3fTextureWrapTests.Case([-0.5, 0.75], [0.25, 1.25]));
+ assertMsgOptions(this.m_caseNdx == 0, 'm_caseNdx != 0', false, true);
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fTextureWrapTests.TextureWrapCase.prototype.iterate = function() {
+ /** @type {glsTextureTestUtil.RandomViewport} */ var viewport = new glsTextureTestUtil.RandomViewport(gl.canvas, Viewport.WIDTH, Viewport.HEIGHT, deString.deStringHash(this.name) + this.m_caseNdx);
+ /** @type {tcuSurface.Surface} */ var renderedFrame = new tcuSurface.Surface(viewport.width, viewport.height);
+ /** @type {tcuSurface.Surface} */ var referenceFrame = new tcuSurface.Surface(viewport.width, viewport.height);
+ /** @type {glsTextureTestUtil.ReferenceParams} */ var refParams = new glsTextureTestUtil.ReferenceParams(glsTextureTestUtil.textureType.TEXTURETYPE_2D);
+ /** @type {tcuTexture.TextureFormat} */ var texFormat = this.m_texture.getRefTexture().getFormat();
+ /** @type {Array<number>} */ var texCoord;
+ /** @type {tcuTextureUtil.TextureFormatInfo} */ var texFormatInfo = tcuTextureUtil.getTextureFormatInfo(texFormat);
+ /** @type {boolean} */ var useDefaultColorScaleAndBias = true;
+
+ // Bind to unit 0.
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, this.m_texture.getGLTexture());
+
+ // Setup filtering and wrap modes.
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, this.m_wrapS);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, this.m_wrapT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.m_minFilter);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.m_magFilter);
+
+ // Parameters for reference images.
+ refParams.sampler = gluTextureUtil.mapGLSamplerWrapST(this.m_wrapS, this.m_wrapT, this.m_minFilter, this.m_magFilter);
+ refParams.lodMode = glsTextureTestUtil.lodMode.EXACT;
+ refParams.samplerType = glsTextureTestUtil.getSamplerType(this.m_texture.getRefTexture().getFormat());
+ refParams.colorScale = useDefaultColorScaleAndBias ? texFormatInfo.lookupScale : [1.0, 1.0, 1.0, 1.0];
+ refParams.colorBias = useDefaultColorScaleAndBias ? texFormatInfo.lookupBias : [0, 0, 0, 0];
+
+ gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
+ texCoord = glsTextureTestUtil.computeQuadTexCoord2D(this.m_cases[this.m_caseNdx].bottomLeft, this.m_cases[this.m_caseNdx].topRight);
+ this.m_renderer.renderQuad(0, texCoord, refParams);
+
+ // gluPixelTransfer.readPixels(viewport.x, viewport.y, renderedFrame.getAccess());
+ /** @type {number} */ var pixelSize = renderedFrame.getAccess().getFormat().getPixelSize();
+ /** @type {number} */ var param = deMath.deIsPowerOfTwo32(pixelSize) ? Math.min(pixelSize, 8) : 1;
+
+ gl.pixelStorei(gl.PACK_ALIGNMENT, param);
+ /** @type {gluTextureUtil.TransferFormat} */ var format = gluTextureUtil.getTransferFormat(renderedFrame.getAccess().getFormat());
+
+ renderedFrame.readViewport(gl, viewport);
+
+ // const tcu::ScopedLogSection section (log, string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
+ /** @type {boolean} */ var isNearestOnly = this.m_minFilter == gl.NEAREST && this.m_magFilter == gl.NEAREST;
+ /** @type {boolean} */ var isSRGB = texFormat.order == tcuTexture.ChannelOrder.sRGB || texFormat.order == tcuTexture.ChannelOrder.sRGBA;
+ /** @type {tcuPixelFormat.PixelFormat} */ var pixelFormat = new tcuPixelFormat.PixelFormat(8, 8, 8, 8);
+ /** @type {Array<number>} */ var colorBits = deMath.max(deMath.subtract(glsTextureTestUtil.getBitsVec(pixelFormat), (isNearestOnly && !isSRGB ? [1, 1, 1, 1] : [2, 2, 2, 2])), [0, 0, 0, 0]);
+ /** @type {tcuTexLookupVerifier.LodPrecision} */ var lodPrecision = new tcuTexLookupVerifier.LodPrecision(18, 5);
+ /** @type {tcuTexLookupVerifier.LookupPrecision} */
+ var lookupPrecision = new tcuTexLookupVerifier.LookupPrecision(
+ [20, 20, 0],
+ [5, 5, 0],
+ deMath.divide(tcuTexLookupVerifier.computeFixedPointThreshold(colorBits), refParams.colorScale),
+ glsTextureTestUtil.getCompareMask(pixelFormat)
+ );
+
+ // log << TestLog::Message << "Note: lookup coordinates: bottom-left " << m_cases[m_caseNdx].bottomLeft << ", top-right " << m_cases[m_caseNdx].topRight << TestLog::EndMessage;
+
+ /** @type {boolean} */ var isOk = glsTextureTestUtil.verifyTexture2DResult(renderedFrame.getAccess(), this.m_texture.getRefTexture(), texCoord, refParams, lookupPrecision, lodPrecision, pixelFormat);
+
+ if (!isOk)
+ testFailedOptions('Case ' + this.m_caseNdx + ': verifyTexture2DResult is false', false);
+ else
+ testPassedOptions('Case ' + this.m_caseNdx + ': OK', true);
+
+ this.m_caseNdx++;
+
+ return this.m_caseNdx < this.m_cases.length ? tcuTestCase.IterateResult.CONTINUE : tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * Initialize test
+ */
+ es3fTextureWrapTests.init = function() {
+ var testGroup = tcuTestCase.runner.testCases;
+ /** @type {string} */ var name;
+ /**
+ * @constructor
+ * @struct
+ * @param {string} name
+ * @param {number} mode
+ */
+ var WrapMode = function(name, mode) {
+ /** @type {string} */ this.name = name;
+ /** @type {number} */ this.mode = mode;
+ };
+
+ /** @type {Array<WrapMode>} */ var wrapModes = [
+ new WrapMode('clamp', gl.CLAMP_TO_EDGE),
+ new WrapMode('repeat', gl.REPEAT),
+ new WrapMode('mirror', gl.MIRRORED_REPEAT)
+ ];
+
+ /**
+ * @constructor
+ * @struct
+ * @param {string} name
+ * @param {number} mode
+ */
+ var FilteringMode = function(name, mode) {
+ /** @type {string} */ this.name = name;
+ /** @type {number} */ this.mode = mode;
+ };
+
+ /** @type {Array<FilteringMode>} */ var filteringModes = [
+ new FilteringMode('nearest', gl.NEAREST),
+ new FilteringMode('linear', gl.LINEAR)
+ ];
+
+ /* Begin RGBA8 Cases */
+ /**
+ * @constructor
+ * @struct
+ * @param {string} name
+ * @param {number} width
+ * @param {number} height
+ */
+ var Rgba8Size = function(name, width, height) {
+ /** @type {string} */ this.name = name;
+ /** @type {number} */ this.width = width;
+ /** @type {number} */ this.height = height;
+ };
+
+ /** @type {Array<Rgba8Size>} */ var rgba8Sizes = [
+ new Rgba8Size('pot', 64, 128),
+ new Rgba8Size('npot', 63, 112)
+ ];
+
+ for (var size = 0; size < rgba8Sizes.length; size++) {
+ /** @type {tcuTestCase.DeqpTest} */ var rgba8Group = tcuTestCase.newTest('rgba8', '');
+ testGroup.addChild(rgba8Group);
+ for (var wrapS = 0; wrapS < wrapModes.length; wrapS++) {
+ for (var wrapT = 0; wrapT < wrapModes.length; wrapT++) {
+ for (var filter = 0; filter < filteringModes.length; filter++) {
+ name = [
+ wrapModes[wrapS].name,
+ wrapModes[wrapT].name,
+ filteringModes[filter].name,
+ rgba8Sizes[size].name
+ ].join('_');
+
+ rgba8Group.addChild(es3fTextureWrapTests.textureWrapCaseFromFormat(
+ name, '',
+ gl.RGBA, gl.UNSIGNED_BYTE,
+ wrapModes[wrapS].mode,
+ wrapModes[wrapT].mode,
+ filteringModes[filter].mode, filteringModes[filter].mode,
+ rgba8Sizes[size].width, rgba8Sizes[size].height
+ ));
+ }
+ }
+ }
+ }
+ /* End RGBA8 Cases */
+
+ /* Begin ETC-2 (and EAC) cases */
+ /**
+ * @constructor
+ * @struct
+ * @param {string} name
+ * @param {tcuCompressedTexture.Format} format
+ */
+ var Etc2Format = function(name, format) {
+ /** @type {string} */ this.name = name;
+ /** @type {tcuCompressedTexture.Format} */ this.format = format;
+ };
+
+ var etc2Formats = [
+ new Etc2Format('eac_r11', tcuCompressedTexture.Format.EAC_R11),
+ new Etc2Format('eac_signed_r11', tcuCompressedTexture.Format.EAC_SIGNED_R11),
+ new Etc2Format('eac_rg11', tcuCompressedTexture.Format.EAC_RG11),
+ new Etc2Format('eac_signed_rg11', tcuCompressedTexture.Format.EAC_SIGNED_RG11),
+ new Etc2Format('etc2_rgb8', tcuCompressedTexture.Format.ETC2_RGB8),
+ new Etc2Format('etc2_srgb8', tcuCompressedTexture.Format.ETC2_SRGB8),
+ new Etc2Format('etc2_rgb8_punchthrough_alpha1', tcuCompressedTexture.Format.ETC2_RGB8_PUNCHTHROUGH_ALPHA1),
+ new Etc2Format('etc2_srgb8_punchthrough_alpha1', tcuCompressedTexture.Format.ETC2_SRGB8_PUNCHTHROUGH_ALPHA1),
+ new Etc2Format('etc2_eac_rgba8', tcuCompressedTexture.Format.ETC2_EAC_RGBA8),
+ new Etc2Format('etc2_eac_srgb8_alpha8', tcuCompressedTexture.Format.ETC2_EAC_SRGB8_ALPHA8)
+ ];
+ if (!gluTextureUtil.enableCompressedTextureETC()) {
+ debug('Skipping ETC2/EAC texture format tests: no support for WEBGL_compressed_texture_etc');
+ etc2Formats = [];
+ }
+
+ /**
+ * @constructor
+ * @struct
+ * @param {string} name
+ * @param {number} width
+ * @param {number} height
+ */
+ var Etc2Size = function(name, width, height) {
+ /** @type {string} */ this.name = name;
+ /** @type {number} */ this.width = width;
+ /** @type {number} */ this.height = height;
+ };
+
+ /** @type {Array<Etc2Size>} */ var etc2Sizes = [
+ new Etc2Size('pot', 64, 128),
+ new Etc2Size('npot', 123, 107)
+ ];
+
+ for (var formatNdx = 0; formatNdx < etc2Formats.length; formatNdx++) {
+ for (var size = 0; size < etc2Sizes.length; size++) {
+ /** @type {tcuTestCase.DeqpTest} */ var formatGroup = tcuTestCase.newTest(etc2Formats[formatNdx].name, '');
+ testGroup.addChild(formatGroup);
+ for (var wrapS = 0; wrapS < wrapModes.length; wrapS++) {
+ for (var wrapT = 0; wrapT < wrapModes.length; wrapT++) {
+ for (var filter = 0; filter < filteringModes.length; filter++) {
+ name = [
+ wrapModes[wrapS].name,
+ wrapModes[wrapT].name,
+ filteringModes[filter].name,
+ etc2Sizes[size].name
+ ].join('_');
+
+ formatGroup.addChild(new es3fTextureWrapTests.TextureWrapCase(
+ name, '',
+ etc2Formats[formatNdx].format,
+ wrapModes[wrapS].mode,
+ wrapModes[wrapT].mode,
+ filteringModes[filter].mode, filteringModes[filter].mode,
+ etc2Sizes[size].width, etc2Sizes[size].height
+ ));
+ }
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fTextureWrapTests.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var testName = 'texture_wrap';
+ var testDescription = 'Texture Wrap Tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.setRoot(tcuTestCase.newTest(testName, testDescription, null));
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ es3fTextureWrapTests.init();
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fTextureWrapTests.run tests', false);
+ state.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTransformFeedbackTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTransformFeedbackTests.js
new file mode 100644
index 0000000000..5beae6985d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fTransformFeedbackTests.js
@@ -0,0 +1,1914 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fTransformFeedbackTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluDrawUtil');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluVarType');
+goog.require('framework.opengl.gluVarTypeUtil');
+
+goog.scope(function() {
+
+ var es3fTransformFeedbackTests = functional.gles3.es3fTransformFeedbackTests;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluDrawUtil = framework.opengl.gluDrawUtil;
+ var gluVarType = framework.opengl.gluVarType;
+ var gluVarTypeUtil = framework.opengl.gluVarTypeUtil;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var deRandom = framework.delibs.debase.deRandom;
+ var deMath = framework.delibs.debase.deMath;
+ var deString = framework.delibs.debase.deString;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuImageCompare = framework.common.tcuImageCompare;
+
+ /** @type {WebGL2RenderingContext} */ var gl;
+
+ var setParentClass = function(child, parent) {
+ child.prototype = Object.create(parent.prototype);
+ child.prototype.constructor = child;
+ };
+
+ /**
+ * @enum
+ */
+ es3fTransformFeedbackTests.State = {
+ DRAW: 0,
+ VERIFY: 1,
+ FINISH: 2
+ };
+
+ /* Maximum time to wait for query result (in seconds) */
+ /** @const */ es3fTransformFeedbackTests.MAX_VERIFY_WAIT = 5;
+
+ /** @const @type {number} */ es3fTransformFeedbackTests.VIEWPORT_WIDTH = 128;
+ /** @const @type {number} */ es3fTransformFeedbackTests.VIEWPORT_HEIGHT = 128;
+ /** @const @type {number} */ es3fTransformFeedbackTests.BUFFER_GUARD_MULTIPLIER = 2;
+
+ /**
+ * Enums for es3fTransformFeedbackTests.interpolation
+ * @enum {number}
+ */
+ es3fTransformFeedbackTests.interpolation = {
+ SMOOTH: 0,
+ FLAT: 1,
+ CENTROID: 2
+
+ };
+
+ /**
+ * Returns es3fTransformFeedbackTests.interpolation name: smooth, flat or centroid
+ * @param {number} interpol es3fTransformFeedbackTests.interpolation enum value
+ * @return {string}
+ */
+ es3fTransformFeedbackTests.getInterpolationName = function(interpol) {
+
+ switch (interpol) {
+ case es3fTransformFeedbackTests.interpolation.SMOOTH: return 'smooth';
+ case es3fTransformFeedbackTests.interpolation.FLAT: return 'flat';
+ case es3fTransformFeedbackTests.interpolation.CENTROID: return 'centroid';
+ default:
+ throw new Error('Unrecognized es3fTransformFeedbackTests.interpolation name ' + interpol);
+ }
+
+ };
+
+ /**
+ * @struct
+ * @param {string} name
+ * @param {gluVarType.VarType} type
+ * @param {number} interpolation
+ * @constructor
+ */
+ es3fTransformFeedbackTests.Varying = function(name, type, interpolation) {
+ this.name = name;
+ this.type = type;
+ this.interpolation = interpolation;
+ };
+
+ /** es3fTransformFeedbackTests.findAttributeNameEquals
+ * Replaces original implementation of "VaryingNameEquals" and "AttributeNameEquals" in the C++ version
+ * Returns an es3fTransformFeedbackTests.Attribute or es3fTransformFeedbackTests.Varying object which matches its name with the passed string value in the function
+ * @param {(Array<es3fTransformFeedbackTests.Attribute> | Array<es3fTransformFeedbackTests.Varying>)} array
+ * @param {string} name
+ * @return { (es3fTransformFeedbackTests.Attribute | es3fTransformFeedbackTests.Varying | null)}
+ */
+ es3fTransformFeedbackTests.findAttributeNameEquals = function(array, name) {
+ for (var pos = 0; pos < array.length; pos++) {
+ if (array[pos].name === name) {
+ return array[pos];
+ }
+ }
+ return null;
+ };
+
+ /**
+ * @struct
+ * @param {string} name
+ * @param {gluVarType.VarType} type
+ * @param {number} offset
+ * @constructor
+ */
+ es3fTransformFeedbackTests.Attribute = function(name, type, offset) {
+ this.name = name;
+ this.type = type;
+ this.offset = offset;
+ };
+
+ /**
+ * Constructs an es3fTransformFeedbackTests.Output object
+ * @constructor
+ */
+ es3fTransformFeedbackTests.Output = function() {
+ /** @type {number} */ this.bufferNdx = 0;
+ /** @type {number} */ this.offset = 0;
+ /** @type {string} */ this.name;
+ /** @type {gluVarType.VarType} */ this.type = null;
+ /** @type {Array<es3fTransformFeedbackTests.Attribute>} */ this.inputs = [];
+ };
+
+ /**
+ * Constructs an object type es3fTransformFeedbackTests.DrawCall.
+ * Contains the number of elements as well as whether the Transform Feedback is enabled or not.
+ * @struct
+ * @param {number} numElements
+ * @param {boolean} tfEnabled is Transform Feedback enabled or not
+ * @constructor
+ */
+ es3fTransformFeedbackTests.DrawCall = function(numElements, tfEnabled) {
+ this.numElements = numElements;
+ this.transformFeedbackEnabled = tfEnabled;
+ };
+
+ /**
+ * @constructor
+ */
+ es3fTransformFeedbackTests.ProgramSpec = function() {
+
+ /** @type {Array<gluVarType.StructType>} */ var m_structs = [];
+ /** @type {Array<es3fTransformFeedbackTests.Varying>} */ var m_varyings = [];
+ /** @type {Array<string>} */ var m_transformFeedbackVaryings = [];
+
+ this.createStruct = function(name) {
+ var struct = gluVarType.newStructType(name);
+ m_structs.push(struct);
+ return struct;
+ };
+
+ this.addVarying = function(name, type, interp) {
+ m_varyings.push(new es3fTransformFeedbackTests.Varying(name, type, interp));
+ };
+
+ this.addTransformFeedbackVarying = function(name) {
+ m_transformFeedbackVaryings.push(name);
+ };
+
+ this.getStructs = function() {
+ return m_structs;
+ };
+ this.getVaryings = function() {
+ return m_varyings;
+ };
+ this.getTransformFeedbackVaryings = function() {
+ return m_transformFeedbackVaryings;
+ };
+
+ this.isPointSizeUsed = function() {
+ for (var i = 0; i < m_transformFeedbackVaryings.length; ++i) {
+ if (m_transformFeedbackVaryings[i] == 'gl_PointSize') return true;
+ }
+ return false;
+ };
+
+ };
+
+ /** Returns if the program is supported or not
+ * @param {es3fTransformFeedbackTests.ProgramSpec} spec
+ * @param {number} tfMode
+ * @return {boolean}
+ */
+ es3fTransformFeedbackTests.isProgramSupported = function(spec, tfMode) {
+ var maxVertexAttribs = Number(gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ var maxTfInterleavedComponents = Number(gl.getParameter(gl.MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS));
+ var maxTfSeparateAttribs = Number(gl.getParameter(gl.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS));
+ var maxTfSeparateComponents = Number(gl.getParameter(gl.MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS));
+
+ // Check vertex attribs.
+ /** @type {number} */ var totalVertexAttribs = (
+ 1 /* a_position */ + (spec.isPointSizeUsed() ? 1 : 0)
+ );
+
+ for (var i = 0; i < spec.getVaryings().length; ++i) {
+ for (var v_iter = new gluVarTypeUtil.VectorTypeIterator(spec.getVaryings()[i].type); !v_iter.end(); v_iter.next()) {
+ totalVertexAttribs += 1;
+ }
+ }
+
+ if (totalVertexAttribs > maxVertexAttribs)
+ return false; // Vertex attribute es3fTransformFeedbackTests.count exceeded.
+
+ // check varyings
+ /** @type {number} */ var totalTfComponents = 0;
+ /** @type {number} */ var totalTfAttribs = 0;
+ /** @type {Object.<number, number>} */ var presetNumComponents = {
+ gl_Position: 4,
+ gl_PointSize: 1
+ };
+ for (var i = 0; i < spec.getTransformFeedbackVaryings().length; ++i) {
+ var name = spec.getTransformFeedbackVaryings()[i];
+ var numComponents = 0;
+
+ if (typeof(presetNumComponents[name]) != 'undefined') {
+ numComponents = presetNumComponents[name];
+ } else {
+ var varName = gluVarTypeUtil.parseVariableName(name);
+ // find the varying called varName
+ /** @type {es3fTransformFeedbackTests.Varying} */ var varying = (function(varyings) {
+ for (var i = 0; i < varyings.length; ++i) {
+ if (varyings[i].name == varName) {
+ return varyings[i];
+ }
+ }
+ return null;
+ }(spec.getVaryings()));
+
+ // glu::TypeComponentVector
+ var varPath = gluVarTypeUtil.parseTypePath(name, varying.type);
+ numComponents = gluVarTypeUtil.getVarType(varying.type, varPath).getScalarSize();
+ }
+
+ if (tfMode == gl.SEPARATE_ATTRIBS && numComponents > maxTfSeparateComponents)
+ return false; // Per-attribute component es3fTransformFeedbackTests.count exceeded.
+
+ totalTfComponents += numComponents;
+ totalTfAttribs += 1;
+ }
+
+ if (tfMode == gl.SEPARATE_ATTRIBS && totalTfAttribs > maxTfSeparateAttribs)
+ return false;
+
+ if (tfMode == gl.INTERLEAVED_ATTRIBS && totalTfComponents > maxTfInterleavedComponents)
+ return false;
+
+ return true;
+
+ };
+
+ /**
+ * @param {string} varyingName
+ * @param {Array<gluVarTypeUtil.VarTypeComponent>} path
+ * @return {string}
+ */
+ es3fTransformFeedbackTests.getAttributeName = function(varyingName, path) {
+ /** @type {string} */ var str = 'a_' + varyingName.substr(/^v_/.test(varyingName) ? 2 : 0);
+
+ for (var i = 0; i < path.length; ++i) {
+ /** @type {string} */ var prefix;
+
+ switch (path[i].type) {
+ case gluVarTypeUtil.VarTypeComponent.s_Type.STRUCT_MEMBER: prefix = '_m'; break;
+ case gluVarTypeUtil.VarTypeComponent.s_Type.ARRAY_ELEMENT: prefix = '_e'; break;
+ case gluVarTypeUtil.VarTypeComponent.s_Type.MATRIX_COLUMN: prefix = '_c'; break;
+ case gluVarTypeUtil.VarTypeComponent.s_Type.VECTOR_COMPONENT: prefix = '_s'; break;
+ default:
+ throw new Error('invalid type in the component path.');
+ }
+ str += prefix + path[i].index;
+ }
+ return str;
+ };
+
+ /**
+ * original definition:
+ * static void es3fTransformFeedbackTests.genShaderSources (const es3fTransformFeedbackTests.ProgramSpec& spec, std::string& vertSource, std::string& fragSource, bool pointSizeRequired)
+ * in place of the std::string references, this function returns those params in an object
+ *
+ * @param {es3fTransformFeedbackTests.ProgramSpec} spec
+ * @param {boolean} pointSizeRequired
+ * @return {Object.<string, string>}
+ */
+ es3fTransformFeedbackTests.genShaderSources = function(spec, pointSizeRequired) {
+
+ var vtx = { str: null };
+ var frag = { str: null };
+ var addPointSize = spec.isPointSizeUsed();
+
+ vtx.str = '#version 300 es\n' +
+ 'in highp vec4 a_position;\n';
+ frag.str = '#version 300 es\n' +
+ 'layout(location = 0) out mediump vec4 o_color;\n' +
+ 'uniform highp vec4 u_scale;\n' +
+ 'uniform highp vec4 u_bias;\n';
+ //vtx.str = 'attribute highp vec4 a_position;\n';
+ //frag.str = 'uniform highp vec4 u_scale;\n' +
+ // 'uniform highp vec4 u_bias;\n';
+
+ if (addPointSize) {
+ vtx.str += 'in highp float a_pointSize;\n';
+ //vtx.str += 'attribute highp float a_pointSize;\n';
+ }
+
+ // Declare attributes.
+ for (var i = 0; i < spec.getVaryings().length; ++i) {
+
+ /** @type {string} */ var name = spec.getVaryings()[i].name;
+ /** @type {gluVarType.VarType} */ var type = spec.getVaryings()[i].type;
+
+ for (var vecIter = new gluVarTypeUtil.VectorTypeIterator(type); !vecIter.end(); vecIter.next()) {
+
+ /** @type {gluVarType.VarType} */
+ var attribType = gluVarTypeUtil.getVarType(type, vecIter.getPath());
+
+ /** @type {string} */
+ var attribName = es3fTransformFeedbackTests.getAttributeName(name, vecIter.getPath());
+ vtx.str += 'in ' + gluVarType.declareVariable(attribType, attribName) + ';\n';
+
+ }
+ }
+
+ // Declare varyings.
+ for (var ndx = 0; ndx < 2; ++ndx) {
+ var inout = ndx ? 'in' : 'out';
+ var shader = ndx ? frag : vtx;
+
+ for (var i = 0; i < spec.getStructs().length; ++i) {
+ var struct = spec.getStructs()[i];
+ if (struct.hasTypeName()) {
+ shader.str += gluVarType.declareStructType(struct) + ';\n';
+ }
+ }
+
+ /** @type {Array<es3fTransformFeedbackTests.Varying>} */ var varyings = spec.getVaryings();
+ for (var i = 0; i < varyings.length; ++i) {
+ var varying = varyings[i];
+ shader.str += es3fTransformFeedbackTests.getInterpolationName(varying.interpolation) +
+ ' ' + inout + ' ' +
+ gluVarType.declareVariable(varying.type, varying.name) +
+ ';\n';
+ }
+ }
+
+ vtx.str += '\nvoid main (void)\n {\n' +
+ '\tgl_Position = a_position;\n';
+ frag.str += '\nvoid main (void)\n {\n' +
+ '\thighp vec4 res = vec4(0.0);\n';
+
+ if (addPointSize) {
+ vtx.str += '\tgl_PointSize = a_pointSize;\n';
+ } else if (pointSizeRequired) {
+ vtx.str += '\tgl_PointSize = 1.0;\n';
+ }
+
+ for (var i = 0; i < spec.getVaryings().length; ++i) {
+ var name = spec.getVaryings()[i].name;
+ var type = spec.getVaryings()[i].type;
+
+ for (var vecIter = new gluVarTypeUtil.VectorTypeIterator(type); !vecIter.end(); vecIter.next()) {
+ /** @type {gluVarType.VarType} */var subType = gluVarTypeUtil.getVarType(type, vecIter.getPath());
+ var attribName = es3fTransformFeedbackTests.getAttributeName(name, vecIter.getPath());
+
+ if (!(
+ subType.isBasicType() &&
+ gluShaderUtil.isDataTypeScalarOrVector(subType.getBasicType())
+ )) throw new Error('Not a scalar or vector.');
+
+ // Vertex: assign from attribute.
+ vtx.str += '\t' + name + vecIter.toString() + ' = ' + attribName + ';\n';
+
+ // Fragment: add to res variable.
+ var scalarSize = gluShaderUtil.getDataTypeScalarSize(subType.getBasicType());
+
+ frag.str += '\tres += ';
+ if (scalarSize == 1) frag.str += 'vec4(' + name + vecIter.toString() + ')';
+ else if (scalarSize == 2) frag.str += 'vec2(' + name + vecIter.toString() + ').xxyy';
+ else if (scalarSize == 3) frag.str += 'vec3(' + name + vecIter.toString() + ').xyzx';
+ else if (scalarSize == 4) frag.str += 'vec4(' + name + vecIter.toString() + ')';
+
+ frag.str += ';\n';
+ }
+ }
+
+ frag.str += '\to_color = res * u_scale + u_bias;\n}\n';
+ //frag.str += '\tgl_FragColor = res * u_scale + u_bias;\n}\n';
+ vtx.str += '}\n';
+
+ return {
+ vertSource: vtx.str,
+ fragSource: frag.str
+ };
+ };
+
+ /**
+ * Returns a Shader program
+ * @param {es3fTransformFeedbackTests.ProgramSpec} spec
+ * @param {number} bufferMode
+ * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
+ * @return {gluShaderProgram.ShaderProgram}
+ */
+ es3fTransformFeedbackTests.createVertexCaptureProgram = function(spec, bufferMode, primitiveType) {
+
+ /** @type {Object.<string, string>} */ var source = es3fTransformFeedbackTests.genShaderSources(spec, primitiveType === gluDrawUtil.primitiveType.POINTS /* Is point size required? */);
+
+ var programSources = new gluShaderProgram.ProgramSources();
+ programSources.add(new gluShaderProgram.VertexSource(source.vertSource))
+ .add(new gluShaderProgram.FragmentSource(source.fragSource))
+ .add(new gluShaderProgram.TransformFeedbackVaryings(spec.getTransformFeedbackVaryings()))
+ .add(new gluShaderProgram.TransformFeedbackMode(bufferMode));
+
+ return new gluShaderProgram.ShaderProgram(gl, programSources);
+
+ };
+
+ /**
+ * @param {Array<es3fTransformFeedbackTests.Attribute>} attributes
+ * @param {Array<es3fTransformFeedbackTests.Varying>} varyings
+ * @param {boolean} usePointSize
+ * @return {number} input stride
+ */
+ es3fTransformFeedbackTests.computeInputLayout = function(attributes, varyings, usePointSize) {
+
+ var inputStride = 0;
+
+ // Add position
+ var dataTypeVec4 = gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.precision.PRECISION_HIGHP);
+ attributes.push(new es3fTransformFeedbackTests.Attribute('a_position', dataTypeVec4, inputStride));
+ inputStride += 4 * 4; /*sizeof(deUint32)*/
+
+ if (usePointSize) {
+ var dataTypeFloat = gluVarType.newTypeBasic(gluShaderUtil.DataType.FLOAT, gluShaderUtil.precision.PRECISION_HIGHP);
+ attributes.push(new es3fTransformFeedbackTests.Attribute('a_pointSize', dataTypeFloat, inputStride));
+ inputStride += 1 * 4; /*sizeof(deUint32)*/
+ }
+
+ for (var i = 0; i < varyings.length; i++) {
+ for (var vecIter = new gluVarTypeUtil.VectorTypeIterator(varyings[i].type); !vecIter.end(); vecIter.next()) {
+ var type = vecIter.getType(); // originally getType() in getVarType() within gluVARTypeUtil.hpp.
+ var name = es3fTransformFeedbackTests.getAttributeName(varyings[i].name, vecIter.getPath());
+
+ attributes.push(new es3fTransformFeedbackTests.Attribute(name, type, inputStride));
+ inputStride += gluShaderUtil.getDataTypeScalarSize(type.getBasicType()) * 4; /*sizeof(deUint32)*/
+ }
+ }
+
+ return inputStride;
+ };
+
+ /**
+ * @param {Array<es3fTransformFeedbackTests.Output>} transformFeedbackOutputs
+ * @param {Array<es3fTransformFeedbackTests.Attribute>} attributes
+ * @param {Array<es3fTransformFeedbackTests.Varying>} varyings
+ * @param {Array<string>} transformFeedbackVaryings
+ * @param {number} bufferMode
+ */
+ es3fTransformFeedbackTests.computeTransformFeedbackOutputs = function(transformFeedbackOutputs, attributes, varyings, transformFeedbackVaryings, bufferMode) {
+
+ /** @type {number} */ var accumulatedSize = 0;
+
+ // transformFeedbackOutputs.resize(transformFeedbackVaryings.size());
+ for (var varNdx = 0; varNdx < transformFeedbackVaryings.length; varNdx++) {
+ /** @type {string} */ var name = transformFeedbackVaryings[varNdx];
+ /** @type {number} */ var bufNdx = (bufferMode === gl.SEPARATE_ATTRIBS ? varNdx : 0);
+ /** @type {number} */ var offset = (bufferMode === gl.SEPARATE_ATTRIBS ? 0 : accumulatedSize);
+ /** @type {es3fTransformFeedbackTests.Output} */ var output = new es3fTransformFeedbackTests.Output();
+
+ output.name = name;
+ output.bufferNdx = bufNdx;
+ output.offset = offset;
+
+ if (name === 'gl_Position') {
+ var posIn = es3fTransformFeedbackTests.findAttributeNameEquals(attributes, 'a_position');
+ output.type = posIn.type;
+ output.inputs.push(posIn);
+ } else if (name === 'gl_PointSize') {
+ var sizeIn = es3fTransformFeedbackTests.findAttributeNameEquals(attributes, 'a_pointSize');
+ output.type = sizeIn.type;
+ output.inputs.push(sizeIn);
+ } else {
+ var varName = gluVarTypeUtil.parseVariableName(name);
+ var varying = es3fTransformFeedbackTests.findAttributeNameEquals(varyings, varName);
+
+ var varPath = gluVarTypeUtil.parseTypePath(name, varying.type);
+ output.type = gluVarTypeUtil.getVarType(varying.type, varPath);
+
+ // Add all vectorized attributes as inputs.
+ for (var iter = new gluVarTypeUtil.VectorTypeIterator(output.type); !iter.end(); iter.next()) {
+ var fullpath = varPath.concat(iter.getPath());
+ var attribName = es3fTransformFeedbackTests.getAttributeName(varName, fullpath);
+ var attrib = es3fTransformFeedbackTests.findAttributeNameEquals(attributes, attribName);
+ output.inputs.push(attrib);
+ }
+ }
+ transformFeedbackOutputs.push(output);
+ accumulatedSize += output.type.getScalarSize() * 4; /*sizeof(deUint32)*/
+ }
+ };
+
+ /**
+ * @param {es3fTransformFeedbackTests.Attribute} attrib
+ * @param {ArrayBuffer} buffer
+ * @param {number} stride
+ * @param {number} numElements
+ * @param {deRandom.Random} rnd
+ */
+ es3fTransformFeedbackTests.genAttributeData = function(attrib, buffer, stride, numElements, rnd) {
+
+ /** @type {number} */ var elementSize = 4; /*sizeof(deUint32)*/
+ /** @type {boolean} */ var isFloat = gluShaderUtil.isDataTypeFloatOrVec(attrib.type.getBasicType());
+ /** @type {boolean} */ var isInt = gluShaderUtil.isDataTypeIntOrIVec(attrib.type.getBasicType());
+ /** @type {boolean} */ var isUint = gluShaderUtil.isDataTypeUintOrUVec(attrib.type.getBasicType());
+
+ /** @type {gluShaderUtil.precision} */ var precision = attrib.type.getPrecision();
+
+ /** @type {number} */ var numComps = gluShaderUtil.getDataTypeScalarSize(attrib.type.getBasicType());
+
+ for (var elemNdx = 0; elemNdx < numElements; elemNdx++) {
+ for (var compNdx = 0; compNdx < numComps; compNdx++) {
+ /** @type {number} */ var offset = attrib.offset + elemNdx * stride + compNdx * elementSize;
+ if (isFloat) {
+ var pos = new Float32Array(buffer, offset, 1);
+ switch (precision) {
+ case gluShaderUtil.precision.PRECISION_LOWP: pos[0] = 0.25 * rnd.getInt(0, 4); break;
+ case gluShaderUtil.precision.PRECISION_MEDIUMP: pos[0] = rnd.getFloat(-1e3, 1e3); break;
+ case gluShaderUtil.precision.PRECISION_HIGHP: pos[0] = rnd.getFloat(-1e5, 1e5); break;
+ default: throw new Error('Unknown precision: ' + precision);
+ }
+ } else if (isInt) {
+ var pos = new Int32Array(buffer, offset, 1);
+ switch (precision) {
+ case gluShaderUtil.precision.PRECISION_LOWP: pos[0] = rnd.getInt(-128, 127); break;
+ case gluShaderUtil.precision.PRECISION_MEDIUMP: pos[0] = rnd.getInt(-32768, 32767); break;
+ case gluShaderUtil.precision.PRECISION_HIGHP: pos[0] = rnd.getInt(); break;
+ default: throw new Error('Unknown precision: ' + precision);
+ }
+ } else if (isUint) {
+ var pos = new Uint32Array(buffer, offset, 1);
+ switch (precision) {
+ case gluShaderUtil.precision.PRECISION_LOWP: pos[0] = rnd.getInt(0, 255); break;
+ case gluShaderUtil.precision.PRECISION_MEDIUMP: pos[0] = rnd.getInt(0, 65535); break;
+ case gluShaderUtil.precision.PRECISION_HIGHP: pos[0] = Math.abs(rnd.getInt()); break;
+ default: throw new Error('Unknown precision: ' + precision);
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * @param {Array<es3fTransformFeedbackTests.Attribute>} attributes
+ * @param {number} numInputs
+ * @param {number} inputStride
+ * @param {deRandom.Random} rnd
+ * @return {ArrayBuffer}
+ */
+ es3fTransformFeedbackTests.genInputData = function(attributes, numInputs, inputStride, rnd) {
+ var buffer = new ArrayBuffer(numInputs * inputStride);
+
+ var position = es3fTransformFeedbackTests.findAttributeNameEquals(attributes, 'a_position');
+ if (!position)
+ throw new Error('Position attribute not found.');
+
+ for (var ndx = 0; ndx < numInputs; ndx++) {
+ var pos = new Float32Array(buffer, position.offset + inputStride * ndx, 4);
+ pos[0] = rnd.getFloat(-1.2, 1.2);
+ pos[1] = rnd.getFloat(-1.2, 1.2);
+ pos[2] = rnd.getFloat(-1.2, 1.2);
+ pos[3] = rnd.getFloat(0.1, 2.0);
+ }
+
+ var pointSizePos = es3fTransformFeedbackTests.findAttributeNameEquals(attributes, 'a_pointSize');
+ if (pointSizePos) {
+ for (var ndx = 0; ndx < numInputs; ndx++) {
+ var pos = new Float32Array(buffer, pointSizePos.offset + inputStride * ndx, 1);
+ pos[0] = rnd.getFloat(1, 8);
+ }
+ }
+
+ // Random data for rest of components.
+ for (var i = 0; i < attributes.length; i++) {
+ if (attributes[i].name != 'a_position' && attributes[i].name != 'a_pointSize')
+ es3fTransformFeedbackTests.genAttributeData(attributes[i], buffer, inputStride, numInputs, rnd);
+ }
+
+ return buffer;
+ };
+
+ /**
+ * Returns the number of outputs with the es3fTransformFeedbackTests.count for the Primitives in the Transform Feedback.
+ * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
+ * @param {number} numElements
+ * @return {number}
+ */
+ es3fTransformFeedbackTests.getTransformFeedbackOutputCount = function(primitiveType, numElements) {
+
+ switch (primitiveType) {
+ case gluDrawUtil.primitiveType.TRIANGLES: return numElements - numElements % 3;
+ case gluDrawUtil.primitiveType.TRIANGLE_STRIP: return Math.max(0, numElements - 2) * 3;
+ case gluDrawUtil.primitiveType.TRIANGLE_FAN: return Math.max(0, numElements - 2) * 3;
+ case gluDrawUtil.primitiveType.LINES: return numElements - numElements % 2;
+ case gluDrawUtil.primitiveType.LINE_STRIP: return Math.max(0, numElements - 1) * 2;
+ case gluDrawUtil.primitiveType.LINE_LOOP: return numElements > 1 ? numElements * 2 : 0;
+ case gluDrawUtil.primitiveType.POINTS: return numElements;
+ default:
+ throw new Error('Unrecognized primitiveType ' + primitiveType);
+ }
+
+ };
+
+ /**
+ * Returns a number with the es3fTransformFeedbackTests.count for the Primitives in the Transform Feedback.
+ * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
+ * @param {number} numElements
+ * @return {number}
+ */
+ es3fTransformFeedbackTests.getTransformFeedbackPrimitiveCount = function(primitiveType, numElements) {
+
+ switch (primitiveType) {
+ case gluDrawUtil.primitiveType.TRIANGLES: return Math.floor(numElements / 3);
+ case gluDrawUtil.primitiveType.TRIANGLE_STRIP: return Math.max(0, numElements - 2);
+ case gluDrawUtil.primitiveType.TRIANGLE_FAN: return Math.max(0, numElements - 2);
+ case gluDrawUtil.primitiveType.LINES: return Math.floor(numElements / 2);
+ case gluDrawUtil.primitiveType.LINE_STRIP: return Math.max(0, numElements - 1);
+ case gluDrawUtil.primitiveType.LINE_LOOP: return numElements > 1 ? numElements : 0;
+ case gluDrawUtil.primitiveType.POINTS: return numElements;
+ default:
+ throw new Error('Unrecognized primitiveType ' + primitiveType);
+ }
+
+ };
+
+ /**
+ * Returns the type of Primitive Mode: Triangles for all Triangle Primitive's type and same for Line and Points.
+ * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
+ * @return {number} primitiveType
+ */
+ es3fTransformFeedbackTests.getTransformFeedbackPrimitiveMode = function(primitiveType) {
+
+ switch (primitiveType) {
+ case gluDrawUtil.primitiveType.TRIANGLES:
+ case gluDrawUtil.primitiveType.TRIANGLE_STRIP:
+ case gluDrawUtil.primitiveType.TRIANGLE_FAN:
+ return gl.TRIANGLES;
+
+ case gluDrawUtil.primitiveType.LINES:
+ case gluDrawUtil.primitiveType.LINE_STRIP:
+ case gluDrawUtil.primitiveType.LINE_LOOP:
+ return gl.LINES;
+
+ case gluDrawUtil.primitiveType.POINTS:
+ return gl.POINTS;
+
+ default:
+ throw new Error('Unrecognized primitiveType ' + primitiveType);
+ }
+
+ };
+
+ /**
+ * Returns the attribute index for a certain primitive type.
+ * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
+ * @param {number} numInputs
+ * @param {number} outNdx
+ * @return {number}
+ */
+ es3fTransformFeedbackTests.getAttributeIndex = function(primitiveType, numInputs, outNdx) {
+
+ switch (primitiveType) {
+
+ case gluDrawUtil.primitiveType.TRIANGLES: return outNdx;
+ case gluDrawUtil.primitiveType.LINES: return outNdx;
+ case gluDrawUtil.primitiveType.POINTS: return outNdx;
+
+ case gluDrawUtil.primitiveType.TRIANGLE_STRIP: {
+ /** @type {number} */ var triNdx = outNdx / 3;
+ /** @type {number} */ var vtxNdx = outNdx % 3;
+ return (triNdx % 2 != 0 && vtxNdx < 2) ? (triNdx + 1 - vtxNdx) : (triNdx + vtxNdx);
+ }
+
+ case gluDrawUtil.primitiveType.TRIANGLE_FAN:
+ return (outNdx % 3 != 0) ? (outNdx / 3 + outNdx % 3) : 0;
+
+ case gluDrawUtil.primitiveType.LINE_STRIP:
+ return outNdx / 2 + outNdx % 2;
+
+ case gluDrawUtil.primitiveType.LINE_LOOP: {
+ var inNdx = outNdx / 2 + outNdx % 2;
+ return inNdx < numInputs ? inNdx : 0;
+ }
+
+ default:
+ throw new Error('Unrecognized primitiveType ' + primitiveType);
+ }
+
+ };
+
+ /**
+ * @param {gluDrawUtil.primitiveType} primitiveType type number in gluDrawUtil.primitiveType
+ * @param {es3fTransformFeedbackTests.Output} output
+ * @param {number} numInputs
+ * @param {Object} buffers
+ * @return {boolean} isOk
+ */
+ es3fTransformFeedbackTests.compareTransformFeedbackOutput = function(primitiveType, output, numInputs, buffers) {
+ /** @type {boolean} */ var isOk = true;
+ /** @type {number} */ var outOffset = output.offset;
+
+ for (var attrNdx = 0; attrNdx < output.inputs.length; attrNdx++) {
+ /** @type {es3fTransformFeedbackTests.Attribute} */ var attribute = output.inputs[attrNdx];
+ /** @type {gluShaderUtil.DataType} */ var type = attribute.type.getBasicType();
+ /** @type {number} */ var numComponents = gluShaderUtil.getDataTypeScalarSize(type);
+
+ /** @type {gluShaderUtil.precision} */ var precision = attribute.type.getPrecision();
+
+ /** @type {string} */ var scalarType = gluShaderUtil.getDataTypeScalarType(type);
+ /** @type {number} */ var numOutputs = es3fTransformFeedbackTests.getTransformFeedbackOutputCount(primitiveType, numInputs);
+
+ for (var outNdx = 0; outNdx < numOutputs; outNdx++) {
+ /** @type {number} */ var inNdx = es3fTransformFeedbackTests.getAttributeIndex(primitiveType, numInputs, outNdx);
+
+ for (var compNdx = 0; compNdx < numComponents; compNdx++) {
+ /** @type {boolean} */ var isEqual = false;
+
+ if (scalarType === 'float') {
+ var outBuffer = new Float32Array(buffers.output.buffer, buffers.output.offset + buffers.output.stride * outNdx + outOffset + compNdx * 4, 1);
+ var inBuffer = new Float32Array(buffers.input.buffer, buffers.input.offset + buffers.input.stride * inNdx + attribute.offset + compNdx * 4, 1);
+ var difInOut = inBuffer[0] - outBuffer[0];
+ /* TODO: Original code used ULP comparison for highp and mediump precision. This could cause failures. */
+ switch (precision) {
+ case gluShaderUtil.precision.PRECISION_HIGHP: {
+ isEqual = Math.abs(difInOut) < 0.1;
+ break;
+ }
+
+ case gluShaderUtil.precision.PRECISION_MEDIUMP: {
+ isEqual = Math.abs(difInOut) < 0.1;
+ break;
+ }
+
+ case gluShaderUtil.precision.PRECISION_LOWP: {
+ isEqual = Math.abs(difInOut) < 0.1;
+ break;
+ }
+ default:
+ throw new Error('Unknown precision: ' + precision);
+ }
+ } else {
+ var outBuffer = new Uint32Array(buffers.output.buffer, buffers.output.offset + buffers.output.stride * outNdx + outOffset + compNdx * 4, 1);
+ var inBuffer = new Uint32Array(buffers.input.buffer, buffers.input.offset + buffers.input.stride * inNdx + attribute.offset + compNdx * 4, 1);
+ isEqual = (inBuffer[0] == outBuffer[0]); // Bit-exact match required for integer types.
+ }
+
+ if (!isEqual) {
+ bufferedLogToConsole('Mismatch in ' + output.name + ' (' + attribute.name + '), output = ' + outNdx + ', input = ' + inNdx + ', component = ' + compNdx);
+ isOk = false;
+ break;
+ }
+ }
+
+ if (!isOk)
+ break;
+ }
+
+ if (!isOk)
+ break;
+
+ outOffset += numComponents * 4; /*sizeof(deUint32)*/
+ }
+
+ return isOk;
+ };
+
+ /**
+ * Returns (for all the draw calls) the type of Primitive Mode, as it calls "es3fTransformFeedbackTests.getTransformFeedbackPrimitiveCount".
+ * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
+ * @param {Array<es3fTransformFeedbackTests.DrawCall>} array Object.<number, boolean>
+ * @return {number} primCount
+ */
+ es3fTransformFeedbackTests.computeTransformFeedbackPrimitiveCount = function(primitiveType, array) {
+
+ /** @type {number} */ var primCount = 0;
+
+ for (var i = 0; i < array.length; ++ i) {
+
+ if (array[i].transformFeedbackEnabled)
+ primCount += es3fTransformFeedbackTests.getTransformFeedbackPrimitiveCount(primitiveType, array[i].numElements);
+ }
+
+ return primCount;
+ };
+
+ /**
+ * @param {number} target
+ * @param {number} bufferSize
+ * @param {number} guardSize
+ */
+ es3fTransformFeedbackTests.writeBufferGuard = function(target, bufferSize, guardSize) {
+ var buffer = new ArrayBuffer(guardSize);
+ var view = new Uint8Array(buffer);
+ for (var i = 0; i < guardSize; ++i) view[i] = 0xcd;
+ gl.bufferSubData(target, bufferSize, buffer);
+ };
+
+ /**
+ * Verifies guard
+ * @param {ArrayBuffer} buffer
+ * @param {number} start
+ * @return {boolean}
+ */
+ es3fTransformFeedbackTests.verifyGuard = function(buffer, start) {
+ start = start || 0;
+ var view = new Uint8Array(buffer, start);
+ for (var i = 0; i < view.length; i++) {
+ if (view[i] != 0xcd)
+ return false;
+ }
+ return true;
+ };
+
+ /**
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} bufferMode
+ * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
+ * @constructor
+ */
+ es3fTransformFeedbackTests.TransformFeedbackCase = function(name, desc, bufferMode, primitiveType) {
+ tcuTestCase.DeqpTest.call(this, name, desc);
+ this.m_bufferMode = bufferMode;
+ this.m_primitiveType = primitiveType;
+ this.m_progSpec = new es3fTransformFeedbackTests.ProgramSpec();
+
+ // Derived from es3fTransformFeedbackTests.ProgramSpec in es3fTransformFeedbackTests.init()
+ this.m_inputStride = 0;
+ this.m_attributes = []; // vector<es3fTransformFeedbackTests.Attribute>
+ this.m_transformFeedbackOutputs = []; // vector<es3fTransformFeedbackTests.Output>
+ this.m_bufferStrides = []; // vector<int>
+
+ // GL state.
+ this.m_program = null; // glu::ShaderProgram
+ this.m_transformFeedback = null; // glu::TransformFeedback
+ this.m_outputBuffers = []; // vector<deUint32>
+
+ this.m_iterNdx = 0; // int
+ this.m_testPassed = true;
+ // State machine
+ this.m_state = es3fTransformFeedbackTests.State.DRAW;
+ this.m_verifyStart = null;
+
+ this.m_frameWithTf = null;
+ this.m_frameWithoutTf = null;
+
+ this.m_viewportW = 0;
+ this.m_viewportH = 0;
+ this.m_viewportX = 0;
+ this.m_viewportY = 0;
+
+ this.m_primitiveQuery = null;
+ this.m_outputsOk = true;
+
+ };
+
+ setParentClass(es3fTransformFeedbackTests.TransformFeedbackCase, tcuTestCase.DeqpTest);
+
+ es3fTransformFeedbackTests.TransformFeedbackCase.prototype.createVerificationResult = function(retry, result) {
+ return { retry: retry, result: result };
+ }
+
+ es3fTransformFeedbackTests.TransformFeedbackCase.prototype.dumpShaderText = function() {
+ var dbgext = gl.getExtension('WEBGL_debug_shaders');
+ for (var ii = 0; ii < this.m_program.shaders.length; ++ii) {
+ debug('Shader source ' + ii + ' before translation:')
+ debug(this.m_program.shaders[ii].info.source);
+ debug('');
+ debug('Shader source ' + ii + ' after translation:');
+ debug(dbgext.getTranslatedShaderSource(this.m_program.shaders[ii].shader));
+ }
+ };
+
+ es3fTransformFeedbackTests.TransformFeedbackCase.prototype.init = function() {
+ this.m_program = es3fTransformFeedbackTests.createVertexCaptureProgram(
+ this.m_progSpec,
+ this.m_bufferMode,
+ this.m_primitiveType
+ );
+
+ if (!this.m_program.isOk()) {
+ // this.dumpShaderText();
+
+ var linkFail = this.m_program.shadersOK &&
+ !this.m_program.getProgramInfo().linkOk;
+
+ if (linkFail) {
+ if (!es3fTransformFeedbackTests.isProgramSupported(this.m_progSpec, this.m_bufferMode)) {
+ var msg = 'Not Supported. Implementation limits exceeded.';
+ checkMessage(false, msg);
+ throw new TestFailedException(msg);
+ } else if (es3fTransformFeedbackTests.hasArraysInTFVaryings(this.m_progSpec)) {
+ msg = 'Capturing arrays is not supported (undefined in specification)';
+ checkMessage(false, msg);
+ throw new TestFailedException(msg);
+ } else {
+ throw new Error('Link failed: ' + this.m_program.getProgramInfo().infoLog);
+ }
+ } else {
+ throw new Error('Compile failed');
+ }
+ } else {
+ // debug('Program is ' +
+ // (gl.getProgramParameter(this.m_program.getProgram(), gl.LINK_STATUS) ? 'linked' : 'not linked'));
+ // this.dumpShaderText();
+ }
+
+// bufferedLogToConsole('Transform feedback varyings: ' + tcu.formatArray(this.m_progSpec.getTransformFeedbackVaryings()));
+ bufferedLogToConsole('Transform feedback varyings: ' + this.m_progSpec.getTransformFeedbackVaryings());
+
+ // Print out transform feedback points reported by GL.
+ // bufferedLogToConsole('Transform feedback varyings reported by compiler:');
+ //logTransformFeedbackVaryings(log, gl, this.m_program.getProgram());
+
+ // Compute input specification.
+ this.m_inputStride = es3fTransformFeedbackTests.computeInputLayout(this.m_attributes, this.m_progSpec.getVaryings(), this.m_progSpec.isPointSizeUsed());
+
+ // Build list of varyings used in transform feedback.
+ es3fTransformFeedbackTests.computeTransformFeedbackOutputs(
+ this.m_transformFeedbackOutputs,
+ this.m_attributes,
+ this.m_progSpec.getVaryings(),
+ this.m_progSpec.getTransformFeedbackVaryings(),
+ this.m_bufferMode
+ );
+ if (!this.m_transformFeedbackOutputs.length) {
+ throw new Error('transformFeedbackOutputs cannot be empty.');
+ }
+
+ if (this.m_bufferMode == gl.SEPARATE_ATTRIBS) {
+ for (var i = 0; i < this.m_transformFeedbackOutputs.length; ++i) {
+ this.m_bufferStrides.push(this.m_transformFeedbackOutputs[i].type.getScalarSize() * 4 /*sizeof(deUint32)*/);
+ }
+ } else {
+ var totalSize = 0;
+ for (var i = 0; i < this.m_transformFeedbackOutputs.length; ++i) {
+ totalSize += this.m_transformFeedbackOutputs[i].type.getScalarSize() * 4 /*sizeof(deUint32)*/;
+ }
+ this.m_bufferStrides.push(totalSize);
+ }
+
+ this.m_outputBuffers.length = this.m_bufferStrides.length;
+ for (var i = 0; i < this.m_outputBuffers.length; i++)
+ this.m_outputBuffers[i] = gl.createBuffer();
+
+ this.m_transformFeedback = gl.createTransformFeedback();
+
+ this.m_iterNdx = 0;
+// this.m_testCtx.setTestResult(QP_TEST_RESULT_PASS, 'Pass');
+
+ };
+
+ es3fTransformFeedbackTests.TransformFeedbackCase.prototype.deinit = function() {
+ for (var i = 0; i < this.m_outputBuffers.length; i++)
+ gl.deleteBuffer(this.m_outputBuffers[i]);
+
+ // delete this.m_transformFeedback;
+ this.m_transformFeedback = null;
+
+ // delete this.m_program;
+ this.m_program = null;
+
+ // Clean up state.
+ this.m_attributes = [];
+ this.m_transformFeedbackOutputs = [];
+ this.m_bufferStrides = [];
+ this.m_inputStride = 0;
+
+ };
+
+ es3fTransformFeedbackTests.TransformFeedbackCase.prototype.iterate = function() {
+ var s = es3fTransformFeedbackTests.TransformFeedbackCase.s_iterate;
+ var numIterations = s.iterations.length;
+ var seed = deMath.deMathHash(this.m_iterNdx);
+ switch(this.m_state) {
+ case es3fTransformFeedbackTests.State.DRAW:
+ bufferedLogToConsole('Testing ' +
+ s.testCases[s.iterations[this.m_iterNdx]].length +
+ ' draw calls, (element es3fTransformFeedbackTests.count, TF state): ' +
+ s.testCases[s.iterations[this.m_iterNdx]]
+ );
+ this.draw(s.testCases[s.iterations[this.m_iterNdx]], seed);
+ this.m_state = es3fTransformFeedbackTests.State.VERIFY;
+ break;
+ case es3fTransformFeedbackTests.State.VERIFY:
+ var verifyResult = this.verify(s.testCases[s.iterations[this.m_iterNdx]]);
+ if (verifyResult.retry) {
+ break;
+ }
+ this.m_testPassed = verifyResult.result;
+ this.m_iterNdx += 1;
+ if (this.m_testPassed && this.m_iterNdx < numIterations) {
+ this.m_state = es3fTransformFeedbackTests.State.DRAW;
+ break;
+ }
+ // Fall through
+ case es3fTransformFeedbackTests.State.FINISH:
+ if (!this.m_testPassed) testFailedOptions('Result comparison failed for iteration ' + s.iterations[this.m_iterNdx - 1], false);
+ else testPassedOptions('Result comparison succeeded', true);
+ return tcuTestCase.IterateResult.STOP;
+ }
+
+ return tcuTestCase.IterateResult.CONTINUE;
+
+ };
+
+ es3fTransformFeedbackTests.TransformFeedbackCase.prototype.draw = function(calls, seed) {
+ var _min = function(x, y) { return x < y ? x : y; };
+
+ var rnd = new deRandom.Random(seed);
+ var numInputs = 0;
+ var numOutputs = 0;
+ var width = gl.drawingBufferWidth;
+ var height = gl.drawingBufferHeight;
+ this.m_viewportW = _min(es3fTransformFeedbackTests.VIEWPORT_WIDTH, width);
+ this.m_viewportH = _min(es3fTransformFeedbackTests.VIEWPORT_HEIGHT, height);
+ this.m_viewportX = rnd.getInt(0, width - this.m_viewportW);
+ this.m_viewportY = rnd.getInt(0, height - this.m_viewportH);
+ this.m_frameWithTf = new tcuSurface.Surface(this.m_viewportW, this.m_viewportH); // tcu::Surface
+ this.m_frameWithoutTf = new tcuSurface.Surface(this.m_viewportW, this.m_viewportH); // tcu::Surface
+ this.m_primitiveQuery = gl.createQuery();
+ this.m_outputsOk = true;
+
+ // Compute totals.
+ for (var i = 0; i < calls.length; ++i) {
+ var call = calls[i];
+ numInputs += call.numElements;
+ numOutputs += call.transformFeedbackEnabled ? es3fTransformFeedbackTests.getTransformFeedbackOutputCount(this.m_primitiveType, call.numElements) : 0;
+ }
+
+ // Input data.
+ var inputData = es3fTransformFeedbackTests.genInputData(this.m_attributes, numInputs, this.m_inputStride, rnd);
+
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, this.m_transformFeedback);
+
+ // Allocate storage for transform feedback output buffers and bind to targets.
+ for (var bufNdx = 0; bufNdx < this.m_outputBuffers.length; ++bufNdx) {
+ var buffer = this.m_outputBuffers[bufNdx]; // deUint32
+ var stride = this.m_bufferStrides[bufNdx]; // int
+ var target = bufNdx; // int
+ var size = stride * numOutputs; // int
+ var guardSize = stride * es3fTransformFeedbackTests.BUFFER_GUARD_MULTIPLIER; // int
+ var usage = gl.DYNAMIC_READ; // const deUint32
+
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, buffer);
+ gl.bufferData(gl.TRANSFORM_FEEDBACK_BUFFER, size + guardSize, usage);
+ es3fTransformFeedbackTests.writeBufferGuard(gl.TRANSFORM_FEEDBACK_BUFFER, size, guardSize);
+
+ // \todo [2012-07-30 pyry] glBindBufferRange()?
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, target, buffer);
+ }
+
+ var attribBuffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, attribBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, inputData, gl.STATIC_DRAW);
+
+ // Setup attributes.
+ for (var i = 0; i < this.m_attributes.length; ++i) {
+ var attrib = this.m_attributes[i];
+ var loc = gl.getAttribLocation(this.m_program.getProgram(), attrib.name);
+ /** @type {string} */
+ var scalarType = gluShaderUtil.getDataTypeScalarType(attrib.type.getBasicType());
+ /** @type {number} */
+ var numComponents = gluShaderUtil.getDataTypeScalarSize(attrib.type.getBasicType());
+
+ if (loc >= 0) {
+ gl.enableVertexAttribArray(loc);
+ switch (scalarType) {
+ case 'float':
+ gl.vertexAttribPointer(loc, numComponents, gl.FLOAT, false, this.m_inputStride, attrib.offset); break;
+ case 'int':
+ gl.vertexAttribIPointer(loc, numComponents, gl.INT, this.m_inputStride, attrib.offset); break;
+ case 'uint':
+ gl.vertexAttribIPointer(loc, numComponents, gl.UNSIGNED_INT, this.m_inputStride, attrib.offset); break;
+ }
+ }
+ }
+
+ // Setup viewport.
+ gl.viewport(this.m_viewportX, this.m_viewportY, this.m_viewportW, this.m_viewportH);
+
+ // Setup program.
+ gl.useProgram(this.m_program.getProgram());
+
+ gl.uniform4fv(
+ gl.getUniformLocation(this.m_program.getProgram(), 'u_scale'),
+ [0.01, 0.01, 0.01, 0.01]
+ );
+ gl.uniform4fv(
+ gl.getUniformLocation(this.m_program.getProgram(), 'u_bias'),
+ [0.5, 0.5, 0.5, 0.5]
+ );
+
+ // Enable query.
+ gl.beginQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, this.m_primitiveQuery);
+
+ // Draw
+ var offset = 0;
+ var tfEnabled = true;
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ var tfPrimitiveMode = es3fTransformFeedbackTests.getTransformFeedbackPrimitiveMode(this.m_primitiveType);
+ gl.beginTransformFeedback(tfPrimitiveMode);
+
+ for (var i = 0; i < calls.length; ++i) {
+ var call = calls[i];
+
+ // Pause or resume transform feedback if necessary.
+ if (call.transformFeedbackEnabled != tfEnabled) {
+ if (call.transformFeedbackEnabled)
+ gl.resumeTransformFeedback();
+ else
+ gl.pauseTransformFeedback();
+ tfEnabled = call.transformFeedbackEnabled;
+ }
+
+ gl.drawArrays(gluDrawUtil.getPrimitiveGLType(gl, this.m_primitiveType), offset, call.numElements);
+ offset += call.numElements;
+ }
+
+ // Resume feedback before finishing it.
+ if (!tfEnabled)
+ gl.resumeTransformFeedback();
+
+ gl.endTransformFeedback();
+
+ gl.endQuery(gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+
+ // Check and log query status right after submit
+ var query = this.m_primitiveQuery;
+
+ var available = gl.getQueryParameter(query, gl.QUERY_RESULT_AVAILABLE);
+
+ if (available) {
+ this.m_testPassed = false;
+ this.m_state = es3fTransformFeedbackTests.State.FINISH;
+ testFailedOptions('Transform feedback query result must not be available the same frame as they are issued.', true);
+ }
+
+ // Compare result buffers.
+ for (var bufferNdx = 0; bufferNdx < this.m_outputBuffers.length; ++bufferNdx) {
+ var stride = this.m_bufferStrides[bufferNdx]; // int
+ var size = stride * numOutputs; // int
+ var guardSize = stride * es3fTransformFeedbackTests.BUFFER_GUARD_MULTIPLIER; // int
+ var buffer = new ArrayBuffer(size + guardSize); // const void*
+
+ // Bind buffer for reading.
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, this.m_outputBuffers[bufferNdx]);
+
+ gl.getBufferSubData(gl.TRANSFORM_FEEDBACK_BUFFER, 0, new Uint8Array(buffer));
+
+ // Verify all output variables that are written to this buffer.
+ for (var i = 0; i < this.m_transformFeedbackOutputs.length; ++i) {
+ var out = this.m_transformFeedbackOutputs[i];
+
+ if (out.bufferNdx != bufferNdx)
+ continue;
+
+ var inputOffset = 0;
+ var outputOffset = 0;
+
+ // Process all draw calls and check ones with transform feedback enabled
+ for (var callNdx = 0; callNdx < calls.length; ++callNdx) {
+ var call = calls[callNdx];
+
+ if (call.transformFeedbackEnabled) {
+ var inputPtr = inputData[0] + inputOffset * this.m_inputStride; // const deUint8*
+ var outputPtr = outputOffset * stride; // const deUint8*
+
+ if (!es3fTransformFeedbackTests.compareTransformFeedbackOutput(this.m_primitiveType, out, call.numElements, {
+ input: {
+ buffer: inputData,
+ offset: inputOffset * this.m_inputStride,
+ stride: this.m_inputStride
+ },
+ output: {
+ buffer: buffer,
+ offset: outputOffset * stride,
+ stride: stride
+ }
+ })) {
+ this.m_outputsOk = false;
+ break;
+ }
+ }
+
+ inputOffset += call.numElements;
+ outputOffset += call.transformFeedbackEnabled ? es3fTransformFeedbackTests.getTransformFeedbackOutputCount(this.m_primitiveType, call.numElements) : 0;
+ }
+ }
+
+ // Verify guardband.
+ if (!es3fTransformFeedbackTests.verifyGuard(buffer, size)) {
+ bufferedLogToConsole('Error: Transform feedback buffer overrun detected');
+ this.m_outputsOk = false;
+ }
+ }
+ };
+
+ es3fTransformFeedbackTests.TransformFeedbackCase.prototype.verify = function(calls) {
+ // Check status after mapping buffers.
+ var mustBeReady = this.m_outputBuffers.length > 0; // Mapping buffer forces synchronization. // const bool
+ var expectedCount = es3fTransformFeedbackTests.computeTransformFeedbackPrimitiveCount(this.m_primitiveType, calls); // const int
+ var available = /** @type {boolean} */ (gl.getQueryParameter(this.m_primitiveQuery, gl.QUERY_RESULT_AVAILABLE));
+ var verify_offset = 0;
+ var queryOk = true;
+ if (!available) {
+ if (!this.m_verifyStart)
+ this.m_verifyStart = new Date();
+ else {
+ var current = new Date();
+ var elapsedTime = 0.001 * (current.getTime() - this.m_verifyStart.getTime());
+ if (elapsedTime > es3fTransformFeedbackTests.MAX_VERIFY_WAIT) {
+ testFailed('Query result not available after ' + elapsedTime + ' seconds.');
+ this.m_state = es3fTransformFeedbackTests.State.FINISH;
+ return this.createVerificationResult(false, false);
+ }
+ }
+ return this.createVerificationResult(true, false);
+ }
+
+ var numPrimitives = /** @type {number} */ (gl.getQueryParameter(this.m_primitiveQuery, gl.QUERY_RESULT));
+
+ if (!mustBeReady && available == false)
+ bufferedLogToConsole('ERROR: gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN result not available after mapping buffers!');
+
+ bufferedLogToConsole('gl.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = ' + numPrimitives);
+
+ if (numPrimitives != expectedCount) {
+ queryOk = false;
+ bufferedLogToConsole('ERROR: Expected ' + expectedCount + ' primitives!');
+ }
+
+ // Clear transform feedback state.
+ gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK, null);
+ for (var bufNdx = 0; bufNdx < this.m_outputBuffers.length; ++bufNdx) {
+ gl.bindBuffer(gl.TRANSFORM_FEEDBACK_BUFFER, null);
+ gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, bufNdx, null);
+ }
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+
+ // Read back rendered image.
+ this.m_frameWithTf.readViewport(gl, [this.m_viewportX, this.m_viewportY, this.m_viewportW, this.m_viewportH]);
+
+ // Render without transform feedback.
+
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ for (var i = 0; i < calls.length; ++i) {
+ var call = calls[i];
+ gl.drawArrays(gluDrawUtil.getPrimitiveGLType(gl, this.m_primitiveType), verify_offset, call.numElements);
+ verify_offset += call.numElements;
+ }
+ this.m_frameWithoutTf.readViewport(gl, [this.m_viewportX, this.m_viewportY, this.m_viewportW, this.m_viewportH]);
+
+ // Compare images with and without transform feedback.
+ var imagesOk = tcuImageCompare.pixelThresholdCompare('Result', 'Image comparison result', this.m_frameWithoutTf, this.m_frameWithTf, [1, 1, 1, 1], tcuImageCompare.CompareLogMode.ON_ERROR);
+
+ if (imagesOk)
+ bufferedLogToConsole('Rendering result comparison between TF enabled and TF disabled passed.');
+ else
+ bufferedLogToConsole('ERROR: Rendering result comparison between TF enabled and TF disabled failed!');
+
+ return this.createVerificationResult(false, this.m_outputsOk && imagesOk && queryOk);
+
+ };
+
+ es3fTransformFeedbackTests.dc = function(numElements, tfEnabled) {
+ return new es3fTransformFeedbackTests.DrawCall(numElements, tfEnabled);
+ };
+
+ // static data
+ es3fTransformFeedbackTests.TransformFeedbackCase.s_iterate = {
+
+ testCases: {
+ elemCount1: [es3fTransformFeedbackTests.dc(1, true)],
+ elemCount2: [es3fTransformFeedbackTests.dc(2, true)],
+ elemCount3: [es3fTransformFeedbackTests.dc(3, true)],
+ elemCount4: [es3fTransformFeedbackTests.dc(4, true)],
+ elemCount123: [es3fTransformFeedbackTests.dc(123, true)],
+ basicPause1: [es3fTransformFeedbackTests.dc(64, true), es3fTransformFeedbackTests.dc(64, false), es3fTransformFeedbackTests.dc(64, true)],
+ basicPause2: [es3fTransformFeedbackTests.dc(13, true), es3fTransformFeedbackTests.dc(5, true), es3fTransformFeedbackTests.dc(17, false),
+ es3fTransformFeedbackTests.dc(3, true), es3fTransformFeedbackTests.dc(7, false)],
+ startPaused: [es3fTransformFeedbackTests.dc(123, false), es3fTransformFeedbackTests.dc(123, true)],
+ random1: [es3fTransformFeedbackTests.dc(65, true), es3fTransformFeedbackTests.dc(135, false), es3fTransformFeedbackTests.dc(74, true),
+ es3fTransformFeedbackTests.dc(16, false), es3fTransformFeedbackTests.dc(226, false), es3fTransformFeedbackTests.dc(9, true),
+ es3fTransformFeedbackTests.dc(174, false)],
+ random2: [es3fTransformFeedbackTests.dc(217, true), es3fTransformFeedbackTests.dc(171, true), es3fTransformFeedbackTests.dc(147, true),
+ es3fTransformFeedbackTests.dc(152, false), es3fTransformFeedbackTests.dc(55, true)]
+ },
+ iterations: [
+ 'elemCount1', 'elemCount2', 'elemCount3', 'elemCount4', 'elemCount123',
+ 'basicPause1', 'basicPause2', 'startPaused',
+ 'random1', 'random2'
+ ]
+ };
+
+ es3fTransformFeedbackTests.hasArraysInTFVaryings = function(spec) {
+
+ for (var i = 0; i < spec.getTransformFeedbackVaryings().length; ++i) {
+ var tfVar = spec.getTransformFeedbackVaryings()[i];
+ var varName = gluVarTypeUtil.parseVariableName(tfVar);
+
+ var attr = es3fTransformFeedbackTests.findAttributeNameEquals(spec.getVaryings(), varName);
+ if (attr && attr.type.isArrayType())
+ return true;
+ }
+ return false;
+
+ };
+
+ /** es3fTransformFeedbackTests.PositionCase
+ * @extends {es3fTransformFeedbackTests.TransformFeedbackCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} bufferMode
+ * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
+ * @constructor
+ */
+ es3fTransformFeedbackTests.PositionCase = function(name, desc, bufferMode, primitiveType) {
+ es3fTransformFeedbackTests.TransformFeedbackCase.call(this, name, desc, bufferMode, primitiveType);
+ this.m_progSpec.addTransformFeedbackVarying('gl_Position');
+ };
+
+ setParentClass(es3fTransformFeedbackTests.PositionCase, es3fTransformFeedbackTests.TransformFeedbackCase);
+
+ /** es3fTransformFeedbackTests.PointSizeCase
+ * @extends {es3fTransformFeedbackTests.TransformFeedbackCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} bufferMode
+ * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
+ * @constructor
+ */
+ es3fTransformFeedbackTests.PointSizeCase = function(name, desc, bufferMode, primitiveType) {
+ es3fTransformFeedbackTests.TransformFeedbackCase.call(this, name, desc, bufferMode, primitiveType);
+ this.m_progSpec.addTransformFeedbackVarying('gl_PointSize');
+
+ };
+
+ setParentClass(es3fTransformFeedbackTests.PointSizeCase, es3fTransformFeedbackTests.TransformFeedbackCase);
+
+ /** es3fTransformFeedbackTests.BasicTypeCase
+ * @extends {es3fTransformFeedbackTests.TransformFeedbackCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} bufferMode
+ * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
+ * @param {gluShaderUtil.DataType} type
+ * @param {gluShaderUtil.precision} precision
+ * @param {es3fTransformFeedbackTests.interpolation} interpolation enum number in this javascript
+ * @constructor
+ */
+ es3fTransformFeedbackTests.BasicTypeCase = function(name, desc, bufferMode, primitiveType, type, precision, interpolation) {
+ es3fTransformFeedbackTests.TransformFeedbackCase.call(this, name, desc, bufferMode, primitiveType);
+
+ this.m_progSpec.addVarying('v_varA', gluVarType.newTypeBasic(type, precision), interpolation);
+ this.m_progSpec.addVarying('v_varB', gluVarType.newTypeBasic(type, precision), interpolation);
+
+ this.m_progSpec.addTransformFeedbackVarying('v_varA');
+ this.m_progSpec.addTransformFeedbackVarying('v_varB');
+
+ };
+
+ setParentClass(es3fTransformFeedbackTests.BasicTypeCase, es3fTransformFeedbackTests.TransformFeedbackCase);
+
+ /** es3fTransformFeedbackTests.BasicArrayCase
+ * @extends {es3fTransformFeedbackTests.TransformFeedbackCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} bufferMode
+ * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
+ * @param {gluShaderUtil.DataType} type
+ * @param {gluShaderUtil.precision} precision
+ * @param {es3fTransformFeedbackTests.interpolation} interpolation enum number in this javascript
+ * @constructor
+ */
+ es3fTransformFeedbackTests.BasicArrayCase = function(name, desc, bufferMode, primitiveType, type, precision, interpolation) {
+ es3fTransformFeedbackTests.TransformFeedbackCase.call(this, name, desc, bufferMode, primitiveType);
+
+ if (gluShaderUtil.isDataTypeMatrix(type) || this.m_bufferMode === gl.SEPARATE_ATTRIBS) {
+ // note For matrix types we need to use reduced array sizes or otherwise we will exceed maximum attribute (16)
+ // or transform feedback component es3fTransformFeedbackTests.count (64).
+ // On separate attribs mode maximum component es3fTransformFeedbackTests.count per varying is 4.
+ this.m_progSpec.addVarying('v_varA', gluVarType.newTypeArray(gluVarType.newTypeBasic(type, precision), 1), interpolation);
+ this.m_progSpec.addVarying('v_varB', gluVarType.newTypeArray(gluVarType.newTypeBasic(type, precision), 2), interpolation);
+ } else {
+ this.m_progSpec.addVarying('v_varA', gluVarType.newTypeArray(gluVarType.newTypeBasic(type, precision), 3), interpolation);
+ this.m_progSpec.addVarying('v_varB', gluVarType.newTypeArray(gluVarType.newTypeBasic(type, precision), 4), interpolation);
+ }
+
+ this.m_progSpec.addTransformFeedbackVarying('v_varA');
+ this.m_progSpec.addTransformFeedbackVarying('v_varB');
+
+ };
+
+ setParentClass(es3fTransformFeedbackTests.BasicArrayCase, es3fTransformFeedbackTests.TransformFeedbackCase);
+
+ /** es3fTransformFeedbackTests.ArrayElementCase
+ * @extends {es3fTransformFeedbackTests.TransformFeedbackCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} bufferMode
+ * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
+ * @param {gluShaderUtil.DataType} type
+ * @param {gluShaderUtil.precision} precision
+ * @param {es3fTransformFeedbackTests.interpolation} interpolation enum number in this javascript
+ * @constructor
+ */
+ es3fTransformFeedbackTests.ArrayElementCase = function(name, desc, bufferMode, primitiveType, type, precision, interpolation) {
+
+ es3fTransformFeedbackTests.TransformFeedbackCase.call(this, name, desc, bufferMode, primitiveType);
+
+ this.m_progSpec.addVarying('v_varA', gluVarType.newTypeArray(gluVarType.newTypeBasic(type, precision), 3), interpolation);
+ this.m_progSpec.addVarying('v_varB', gluVarType.newTypeArray(gluVarType.newTypeBasic(type, precision), 4), interpolation);
+
+ this.m_progSpec.addTransformFeedbackVarying('v_varA[1]');
+ this.m_progSpec.addTransformFeedbackVarying('v_varB[0]');
+ this.m_progSpec.addTransformFeedbackVarying('v_varB[3]');
+
+ };
+
+ setParentClass(es3fTransformFeedbackTests.ArrayElementCase, es3fTransformFeedbackTests.TransformFeedbackCase);
+
+ /** es3fTransformFeedbackTests.RandomCase
+ * @extends {es3fTransformFeedbackTests.TransformFeedbackCase}
+ * @param {string} name
+ * @param {string} desc
+ * @param {number} bufferMode
+ * @param {gluDrawUtil.primitiveType} primitiveType GLenum that specifies what kind of primitive is
+ * @param {number} seed
+ * @constructor
+ */
+ es3fTransformFeedbackTests.RandomCase = function(name, desc, bufferMode, primitiveType, seed) {
+ es3fTransformFeedbackTests.TransformFeedbackCase.call(this, name, desc, bufferMode, primitiveType);
+
+ };
+
+ setParentClass(es3fTransformFeedbackTests.RandomCase, es3fTransformFeedbackTests.TransformFeedbackCase);
+
+ es3fTransformFeedbackTests.RandomCase.prototype.init = function() {
+
+ /** @type {number} */
+ var seed = /*deString.deStringHash(getName()) ^ */ deMath.deMathHash(this.m_iterNdx);
+
+ /** @type {Array<gluShaderUtil.DataType>} */
+ var typeCandidates = [
+ gluShaderUtil.DataType.FLOAT,
+ gluShaderUtil.DataType.FLOAT_VEC2,
+ gluShaderUtil.DataType.FLOAT_VEC3,
+ gluShaderUtil.DataType.FLOAT_VEC4,
+ gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT_VEC2,
+ gluShaderUtil.DataType.INT_VEC3,
+ gluShaderUtil.DataType.INT_VEC4,
+ gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT_VEC2,
+ gluShaderUtil.DataType.UINT_VEC3,
+ gluShaderUtil.DataType.UINT_VEC4,
+
+ gluShaderUtil.DataType.FLOAT_MAT2,
+ gluShaderUtil.DataType.FLOAT_MAT2X3,
+ gluShaderUtil.DataType.FLOAT_MAT2X4,
+
+ gluShaderUtil.DataType.FLOAT_MAT3X2,
+ gluShaderUtil.DataType.FLOAT_MAT3,
+ gluShaderUtil.DataType.FLOAT_MAT3X4,
+
+ gluShaderUtil.DataType.FLOAT_MAT4X2,
+ gluShaderUtil.DataType.FLOAT_MAT4X3,
+ gluShaderUtil.DataType.FLOAT_MAT4
+ ];
+
+ /** @type {Array<gluShaderUtil.precision>} */
+ var precisions = [
+ gluShaderUtil.precision.PRECISION_LOWP,
+ gluShaderUtil.precision.PRECISION_MEDIUMP,
+ gluShaderUtil.precision.PRECISION_HIGHP
+ ];
+
+ var interpModes = [{name: 'smooth', interp: es3fTransformFeedbackTests.interpolation.SMOOTH}, {name: 'flat', interp: es3fTransformFeedbackTests.interpolation.FLAT}, {name: 'centroid', interp: es3fTransformFeedbackTests.interpolation.CENTROID}
+ ];
+
+ /** @type {number} */ var maxAttributeVectors = 16;
+ //** @type {number} */ var maxTransformFeedbackComponents = 64; // note It is enough to limit attribute set size.
+ /** @type {boolean} */ var isSeparateMode = (this.m_bufferMode === gl.SEPARATE_ATTRIBS);
+ /** @type {number} */ var maxTransformFeedbackVars = isSeparateMode ? 4 : maxAttributeVectors;
+ /** @type {number} */ var arrayWeight = 0.3;
+ /** @type {number} */ var positionWeight = 0.7;
+ /** @type {number} */ var pointSizeWeight = 0.1;
+ /** @type {number} */ var captureFullArrayWeight = 0.5;
+
+ /** @type {deRandom.Random} */
+ var rnd = new deRandom.Random(seed);
+ /** @type {boolean} */ var usePosition = rnd.getFloat() < positionWeight;
+ /** @type {boolean} */ var usePointSize = rnd.getFloat() < pointSizeWeight;
+ /** @type {number} */ var numAttribVectorsToUse = rnd.getInt(
+ 1, maxAttributeVectors - 1/*position*/ - (usePointSize ? 1 : 0)
+ );
+
+ /** @type {number} */ var numAttributeVectors = 0;
+ /** @type {number} */ var varNdx = 0;
+
+ // Generate varyings.
+ while (numAttributeVectors < numAttribVectorsToUse) {
+ /** @type {number} */
+ var maxVecs = isSeparateMode ? Math.min(2 /*at most 2*mat2*/, numAttribVectorsToUse - numAttributeVectors) : numAttribVectorsToUse - numAttributeVectors;
+ /** @type {gluShaderUtil.DataType} */
+ var begin = typeCandidates[0];
+ /** @type {number} */
+ var endCandidates = begin + (
+ maxVecs >= 4 ? 21 : (
+ maxVecs >= 3 ? 18 : (
+ maxVecs >= 2 ? (isSeparateMode ? 13 : 15) : 12
+ )
+ )
+ );
+ /** @type {gluShaderUtil.DataType} */
+ var end = typeCandidates[endCandidates];
+
+ /** @type {gluShaderUtil.DataType} */
+ var type = rnd.choose(typeCandidates)[0];
+
+ /** @type {gluShaderUtil.precision} */
+ var precision = rnd.choose(precisions)[0];
+
+ /** @type {es3fTransformFeedbackTests.interpolation} */
+ var interp = (type === gluShaderUtil.DataType.FLOAT) ?
+ rnd.choose(interpModes)[0].interp :
+ es3fTransformFeedbackTests.interpolation.FLAT;
+
+ /** @type {number} */
+ var numVecs = gluShaderUtil.isDataTypeMatrix(type) ? gluShaderUtil.getDataTypeMatrixNumColumns(type) : 1;
+ /** @type {number} */
+ var numComps = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {number} */
+ var maxArrayLen = Math.max(1, isSeparateMode ? (4 / numComps) : (maxVecs / numVecs));
+ /** @type {boolean} */
+ var useArray = rnd.getFloat() < arrayWeight;
+ /** @type {number} */
+ var arrayLen = useArray ? rnd.getInt(1, maxArrayLen) : 1;
+ /** @type {string} */
+ var name = 'v_var' + varNdx;
+
+ if (useArray)
+ this.m_progSpec.addVarying(name, gluVarType.newTypeArray(gluVarType.newTypeBasic(type, precision), arrayLen), interp);
+ else
+ this.m_progSpec.addVarying(name, gluVarType.newTypeBasic(type, precision), interp);
+
+ numAttributeVectors += arrayLen * numVecs;
+ varNdx += 1;
+ }
+
+ // Generate transform feedback candidate set.
+ /** @type {Array<string>} */ var tfCandidates = [];
+
+ if (usePosition) tfCandidates.push('gl_Position');
+ if (usePointSize) tfCandidates.push('gl_PointSize');
+
+ for (var ndx = 0; ndx < varNdx; ndx++) {
+ /** @type {es3fTransformFeedbackTests.Varying} */
+ var varying = this.m_progSpec.getVaryings()[ndx];
+
+ if (varying.type.isArrayType()) {
+ /** @type {boolean} */
+ var captureFull = rnd.getFloat() < captureFullArrayWeight;
+
+ if (captureFull) {
+ tfCandidates.push(varying.name);
+ } else {
+ /** @type {number} */
+ var numElem = varying.type.getArraySize();
+ for (var elemNdx = 0; elemNdx < numElem; elemNdx++)
+ tfCandidates.push(varying.name + '[' + elemNdx + ']');
+ }
+ } else
+ tfCandidates.push(varying.name);
+ }
+
+ // Pick random selection.
+ var tfVaryings = [];
+ rnd.choose(tfCandidates, tfVaryings, Math.min(tfCandidates.length, maxTransformFeedbackVars));
+ rnd.shuffle(tfVaryings);
+ for (var i = 0; i < tfVaryings.length; i++)
+ this.m_progSpec.addTransformFeedbackVarying(tfVaryings[i]);
+
+ es3fTransformFeedbackTests.TransformFeedbackCase.prototype.init.call(this);
+
+ };
+
+ /**
+ * Creates the test in order to be executed
+ **/
+ es3fTransformFeedbackTests.init = function() {
+
+ /** @const @type {tcuTestCase.DeqpTest} */
+ var testGroup = tcuTestCase.runner.testCases;
+
+ var bufferModes = [{name: 'separate', mode: gl.SEPARATE_ATTRIBS}, {name: 'interleaved', mode: gl.INTERLEAVED_ATTRIBS}
+ ];
+
+ var primitiveTypes = [{name: 'points', type: gluDrawUtil.primitiveType.POINTS}, {name: 'lines', type: gluDrawUtil.primitiveType.LINES}, {name: 'triangles', type: gluDrawUtil.primitiveType.TRIANGLES}
+ ];
+
+ /** @type {Array<gluShaderUtil.DataType>} */
+ var basicTypes = [
+ gluShaderUtil.DataType.FLOAT,
+ gluShaderUtil.DataType.FLOAT_VEC2,
+ gluShaderUtil.DataType.FLOAT_VEC3,
+ gluShaderUtil.DataType.FLOAT_VEC4,
+ gluShaderUtil.DataType.FLOAT_MAT2,
+ gluShaderUtil.DataType.FLOAT_MAT2X3,
+ gluShaderUtil.DataType.FLOAT_MAT2X4,
+ gluShaderUtil.DataType.FLOAT_MAT3X2,
+ gluShaderUtil.DataType.FLOAT_MAT3,
+ gluShaderUtil.DataType.FLOAT_MAT3X4,
+ gluShaderUtil.DataType.FLOAT_MAT4X2,
+ gluShaderUtil.DataType.FLOAT_MAT4X3,
+ gluShaderUtil.DataType.FLOAT_MAT4,
+ gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT_VEC2,
+ gluShaderUtil.DataType.INT_VEC3,
+ gluShaderUtil.DataType.INT_VEC4,
+ gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT_VEC2,
+ gluShaderUtil.DataType.UINT_VEC3,
+ gluShaderUtil.DataType.UINT_VEC4
+ ];
+
+ /** @type {Array<gluShaderUtil.precision>} */
+ var precisions = [
+
+ gluShaderUtil.precision.PRECISION_LOWP,
+ gluShaderUtil.precision.PRECISION_MEDIUMP,
+ gluShaderUtil.precision.PRECISION_HIGHP
+
+ // glsUBC.UniformFlags.PRECISION_LOW,
+ // glsUBC.UniformFlags.PRECISION_MEDIUM,
+ // glsUBC.UniformFlags.PRECISION_HIGH
+ ];
+
+ var interpModes = [{name: 'smooth', interp: es3fTransformFeedbackTests.interpolation.SMOOTH}, {name: 'flat', interp: es3fTransformFeedbackTests.interpolation.FLAT}, {name: 'centroid', interp: es3fTransformFeedbackTests.interpolation.CENTROID}
+ ];
+
+ // .position
+ /** @type {tcuTestCase.DeqpTest} */
+ var positionGroup = tcuTestCase.newTest('position', 'gl_Position capture using transform feedback');
+ testGroup.addChild(positionGroup);
+
+ for (var primitiveType = 0; primitiveType < primitiveTypes.length; primitiveType++) {
+ for (var bufferMode = 0; bufferMode < bufferModes.length; bufferMode++) {
+ /** @type {string} */
+ var name = primitiveTypes[primitiveType].name + '_' + bufferModes[bufferMode].name;
+
+ positionGroup.addChild(new es3fTransformFeedbackTests.PositionCase(
+ name,
+ '',
+ bufferModes[bufferMode].mode,
+ primitiveTypes[primitiveType].type
+ ));
+ }
+ }
+
+ // .point_size
+ /** @type {tcuTestCase.DeqpTest} */ var pointSizeGroup = tcuTestCase.newTest('point_size', 'gl_PointSize capture using transform feedback');
+ testGroup.addChild(pointSizeGroup);
+
+ for (var primitiveType = 0; primitiveType < primitiveTypes.length; primitiveType++) {
+ for (var bufferMode = 0; bufferMode < bufferModes.length; bufferMode++) {
+ var name = primitiveTypes[primitiveType].name + '_' + bufferModes[bufferMode].name;
+
+ pointSizeGroup.addChild(new es3fTransformFeedbackTests.PointSizeCase(
+ name,
+ '',
+ bufferModes[bufferMode].mode,
+ primitiveTypes[primitiveType].type
+ ));
+ }
+ }
+
+ // .basic_type
+ for (var bufferModeNdx = 0; bufferModeNdx < bufferModes.length; bufferModeNdx++) {
+ /** @type {number} */
+ var bufferMode = bufferModes[bufferModeNdx].mode;
+ for (var primitiveTypeNdx = 0; primitiveTypeNdx < primitiveTypes.length; primitiveTypeNdx++) {
+ /** @type {tcuTestCase.DeqpTest} */
+ var primitiveGroup = tcuTestCase.newTest(
+ 'basic_types.' + bufferModes[bufferModeNdx].name + '.' + primitiveTypes[primitiveTypeNdx].name,
+ 'Basic types in transform feedback');
+ /** @type {number} */
+ var primitiveType = primitiveTypes[primitiveTypeNdx].type;
+ testGroup.addChild(primitiveGroup);
+
+ for (var typeNdx = 0; typeNdx < basicTypes.length; typeNdx++) {
+ /** @type {gluShaderUtil.DataType} */
+ var type = basicTypes[typeNdx];
+ /** @type {boolean} */
+ var isFloat = gluShaderUtil.getDataTypeScalarType(type) == gluShaderUtil.DataType.FLOAT;
+
+ for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
+ /** @type {gluShaderUtil.precision} */
+ var precision = precisions[precNdx];
+ var name = gluShaderUtil.getPrecisionName(precision) + '_' + gluShaderUtil.getDataTypeName(type);
+
+ primitiveGroup.addChild(new es3fTransformFeedbackTests.BasicTypeCase(
+ name,
+ '',
+ bufferMode,
+ primitiveType,
+ type,
+ precision,
+ isFloat ? es3fTransformFeedbackTests.interpolation.SMOOTH : es3fTransformFeedbackTests.interpolation.FLAT
+ ));
+ }
+ }
+ }
+ }
+
+ // .array
+ for (var bufferModeNdx = 0; bufferModeNdx < bufferModes.length; bufferModeNdx++) {
+ var bufferMode = bufferModes[bufferModeNdx].mode;
+ for (var primitiveTypeNdx = 0; primitiveTypeNdx < primitiveTypes.length; primitiveTypeNdx++) {
+ var primitiveGroup = tcuTestCase.newTest(
+ 'array.' + bufferModes[bufferModeNdx].name + '.' + primitiveTypes[primitiveTypeNdx].name,
+ 'Capturing whole array in TF');
+ /** @type {number} */
+ var primitiveType = primitiveTypes[primitiveTypeNdx].type;
+ testGroup.addChild(primitiveGroup);
+
+ for (var typeNdx = 0; typeNdx < basicTypes.length; typeNdx++) {
+ var type = basicTypes[typeNdx];
+ var isFloat = gluShaderUtil.getDataTypeScalarType(type) == gluShaderUtil.DataType.FLOAT;
+
+ for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
+ var precision = precisions[precNdx];
+ var name = gluShaderUtil.getPrecisionName(precision) + '_' + gluShaderUtil.getDataTypeName(type);
+
+ primitiveGroup.addChild(new es3fTransformFeedbackTests.BasicArrayCase(
+ name,
+ '',
+ bufferMode,
+ primitiveType,
+ type,
+ precision,
+ isFloat ? es3fTransformFeedbackTests.interpolation.SMOOTH : es3fTransformFeedbackTests.interpolation.FLAT
+ ));
+ }
+ }
+ }
+ }
+
+ // .array_element
+ for (var bufferModeNdx = 0; bufferModeNdx < bufferModes.length; bufferModeNdx++) {
+ var bufferMode = bufferModes[bufferModeNdx].mode;
+ for (var primitiveTypeNdx = 0; primitiveTypeNdx < primitiveTypes.length; primitiveTypeNdx++) {
+ var primitiveGroup = tcuTestCase.newTest(
+ 'array_element.' + bufferModes[bufferModeNdx].name + '.' + primitiveTypes[primitiveTypeNdx].name,
+ 'Capturing single array element in TF');
+ var primitiveType = primitiveTypes[primitiveTypeNdx].type;
+ testGroup.addChild(primitiveGroup);
+
+ for (var typeNdx = 0; typeNdx < basicTypes.length; typeNdx++) {
+ var type = basicTypes[typeNdx];
+ var isFloat = gluShaderUtil.getDataTypeScalarType(type) == gluShaderUtil.DataType.FLOAT;
+
+ for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
+ var precision = precisions[precNdx];
+ var name = gluShaderUtil.getPrecisionName(precision) + '_' + gluShaderUtil.getDataTypeName(type);
+
+ primitiveGroup.addChild(new es3fTransformFeedbackTests.ArrayElementCase(
+ name,
+ '',
+ bufferMode,
+ primitiveType,
+ type,
+ precision,
+ isFloat ? es3fTransformFeedbackTests.interpolation.SMOOTH : es3fTransformFeedbackTests.interpolation.FLAT
+ ));
+ }
+ }
+ }
+ }
+
+ // .interpolation
+ for (var modeNdx = 0; modeNdx < interpModes.length; modeNdx++) {
+ var interp = interpModes[modeNdx].interp;
+ var modeGroup = tcuTestCase.newTest(
+ 'interpolation.' + interpModes[modeNdx].name,
+ 'Different interpolation modes in transform feedback varyings');
+ testGroup.addChild(modeGroup);
+
+ for (var precNdx = 0; precNdx < precisions.length; precNdx++) {
+ var precision = precisions[precNdx];
+
+ for (var primitiveType = 0; primitiveType < primitiveTypes.length; primitiveType++) {
+ for (var bufferMode = 0; bufferMode < bufferModes.length; bufferMode++) {
+ var name = (
+ gluShaderUtil.getPrecisionName(precision) +
+ '_vec4_' + primitiveTypes[primitiveType].name +
+ '_' + bufferModes[bufferMode].name
+ );
+
+ modeGroup.addChild(new es3fTransformFeedbackTests.BasicTypeCase(
+ name,
+ '',
+ bufferModes[bufferMode].mode,
+ primitiveTypes[primitiveType].type,
+ gluShaderUtil.DataType.FLOAT_VEC4,
+ precision,
+ interp
+ ));
+ }
+ }
+ }
+ }
+
+ // .random
+ for (var bufferModeNdx = 0; bufferModeNdx < bufferModes.length; bufferModeNdx++) {
+ /** @type {number} */
+ var bufferMode = bufferModes[bufferModeNdx].mode;
+ for (var primitiveTypeNdx = 0; primitiveTypeNdx < primitiveTypes.length; primitiveTypeNdx++) {
+ var primitiveGroup = tcuTestCase.newTest(
+ 'random.' + bufferModes[bufferModeNdx].name + '.' + primitiveTypes[primitiveTypeNdx].name,
+ 'Randomized transform feedback cases');
+ /** @type {number} */
+ var primitiveType = primitiveTypes[primitiveTypeNdx].type;
+ testGroup.addChild(primitiveGroup);
+
+ for (var ndx = 0; ndx < 10; ndx++) {
+ /** @type {number} */
+ var seed = deMath.deMathHash(bufferMode) ^ deMath.deMathHash(primitiveType) ^ deMath.deMathHash(ndx);
+
+ primitiveGroup.addChild(new es3fTransformFeedbackTests.RandomCase(
+ (ndx + 1).toString(),
+ '',
+ bufferMode,
+ primitiveType,
+ seed
+ ));
+ }
+ }
+ }
+
+ };
+
+ /**
+ * Create and execute the test cases
+ */
+ es3fTransformFeedbackTests.run = function(context, range) {
+ gl = context;
+ var testName = 'transform_feedback';
+ var testDescription = 'Transform Feedback Tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.testCases = tcuTestCase.newTest(testName, testDescription, null);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+ try {
+ es3fTransformFeedbackTests.init();
+ if (range)
+ state.setRange(range);
+ tcuTestCase.runTestCases();
+ } catch (err) {
+ bufferedLogToConsole(err);
+ tcuTestCase.runner.terminate();
+ }
+
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fUniformApiTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fUniformApiTests.js
new file mode 100644
index 0000000000..59e50f1fc9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fUniformApiTests.js
@@ -0,0 +1,3203 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fUniformApiTests');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.opengl.gluDrawUtil');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTexture');
+goog.require('framework.opengl.gluVarType');
+
+goog.scope(function() {
+
+ var es3fUniformApiTests = functional.gles3.es3fUniformApiTests;
+ var gluDrawUtil = framework.opengl.gluDrawUtil;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var gluTexture = framework.opengl.gluTexture;
+ var gluVarType = framework.opengl.gluVarType;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuTexture = framework.common.tcuTexture;
+ var deMath = framework.delibs.debase.deMath;
+ var deString = framework.delibs.debase.deString;
+ var deRandom = framework.delibs.debase.deRandom;
+
+ /** @type {WebGL2RenderingContext} */ var gl;
+
+ /** @typedef {function(gluShaderUtil.DataType): boolean} */
+ es3fUniformApiTests.dataTypePredicate;
+
+ /** @type {number} */ es3fUniformApiTests.MAX_RENDER_WIDTH = 32;
+ /** @type {number} */ es3fUniformApiTests.MAX_RENDER_HEIGHT = 32;
+ /** @type {number} */ es3fUniformApiTests.MAX_NUM_SAMPLER_UNIFORMS = 16;
+
+ /** @type {Array<gluShaderUtil.DataType>} */ es3fUniformApiTests.s_testDataTypes = [
+ gluShaderUtil.DataType.FLOAT,
+ gluShaderUtil.DataType.FLOAT_VEC2,
+ gluShaderUtil.DataType.FLOAT_VEC3,
+ gluShaderUtil.DataType.FLOAT_VEC4,
+ gluShaderUtil.DataType.FLOAT_MAT2,
+ gluShaderUtil.DataType.FLOAT_MAT2X3,
+ gluShaderUtil.DataType.FLOAT_MAT2X4,
+ gluShaderUtil.DataType.FLOAT_MAT3X2,
+ gluShaderUtil.DataType.FLOAT_MAT3,
+ gluShaderUtil.DataType.FLOAT_MAT3X4,
+ gluShaderUtil.DataType.FLOAT_MAT4X2,
+ gluShaderUtil.DataType.FLOAT_MAT4X3,
+ gluShaderUtil.DataType.FLOAT_MAT4,
+
+ gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT_VEC2,
+ gluShaderUtil.DataType.INT_VEC3,
+ gluShaderUtil.DataType.INT_VEC4,
+
+ gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT_VEC2,
+ gluShaderUtil.DataType.UINT_VEC3,
+ gluShaderUtil.DataType.UINT_VEC4,
+
+ gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL_VEC2,
+ gluShaderUtil.DataType.BOOL_VEC3,
+ gluShaderUtil.DataType.BOOL_VEC4,
+
+ gluShaderUtil.DataType.SAMPLER_2D,
+ gluShaderUtil.DataType.SAMPLER_CUBE
+ // \note We don't test all sampler types here.
+ ];
+
+ /**
+ * Returns a substring from the beginning to the last occurence of the
+ * specified character
+ * @param {string} str The string in which to search
+ * @param {string} c A single character
+ * @return {string}
+ */
+ es3fUniformApiTests.beforeLast = function(str, c) {
+ return str.substring(0, str.lastIndexOf(c));
+ };
+
+ /**
+ * es3fUniformApiTests.fillWithColor
+ * @param {tcuTexture.PixelBufferAccess} access ,
+ * @param {Array<number>} color Array of four color components.
+ */
+ es3fUniformApiTests.fillWithColor = function(access, color) {
+ for (var z = 0; z < access.getDepth(); z++)
+ for (var y = 0; y < access.getHeight(); y++)
+ for (var x = 0; x < access.getWidth(); x++)
+ access.setPixel(color, x, y, z);
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} type
+ * @return {number}
+ */
+ es3fUniformApiTests.getSamplerNumLookupDimensions = function(type) {
+ switch (type) {
+ case gluShaderUtil.DataType.SAMPLER_2D:
+ case gluShaderUtil.DataType.INT_SAMPLER_2D:
+ case gluShaderUtil.DataType.UINT_SAMPLER_2D:
+ return 2;
+
+ case gluShaderUtil.DataType.SAMPLER_3D:
+ case gluShaderUtil.DataType.INT_SAMPLER_3D:
+ case gluShaderUtil.DataType.UINT_SAMPLER_3D:
+ case gluShaderUtil.DataType.SAMPLER_2D_SHADOW:
+ case gluShaderUtil.DataType.SAMPLER_2D_ARRAY:
+ case gluShaderUtil.DataType.INT_SAMPLER_2D_ARRAY:
+ case gluShaderUtil.DataType.UINT_SAMPLER_2D_ARRAY:
+ case gluShaderUtil.DataType.SAMPLER_CUBE:
+ case gluShaderUtil.DataType.INT_SAMPLER_CUBE:
+ case gluShaderUtil.DataType.UINT_SAMPLER_CUBE:
+ return 3;
+
+ case gluShaderUtil.DataType.SAMPLER_CUBE_SHADOW:
+ case gluShaderUtil.DataType.SAMPLER_2D_ARRAY_SHADOW:
+ return 4;
+
+ default:
+ throw new Error('es3fUniformApiTests.getSamplerNumLookupDimensions - Invalid type');
+ }
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} type
+ * @return {gluShaderUtil.DataType}
+ */
+ es3fUniformApiTests.getSamplerLookupReturnType = function(type) {
+ switch (type) {
+ case gluShaderUtil.DataType.SAMPLER_2D:
+ case gluShaderUtil.DataType.SAMPLER_CUBE:
+ case gluShaderUtil.DataType.SAMPLER_2D_ARRAY:
+ case gluShaderUtil.DataType.SAMPLER_3D:
+ return gluShaderUtil.DataType.FLOAT_VEC4;
+
+ case gluShaderUtil.DataType.UINT_SAMPLER_2D:
+ case gluShaderUtil.DataType.UINT_SAMPLER_CUBE:
+ case gluShaderUtil.DataType.UINT_SAMPLER_2D_ARRAY:
+ case gluShaderUtil.DataType.UINT_SAMPLER_3D:
+ return gluShaderUtil.DataType.UINT_VEC4;
+
+ case gluShaderUtil.DataType.INT_SAMPLER_2D:
+ case gluShaderUtil.DataType.INT_SAMPLER_CUBE:
+ case gluShaderUtil.DataType.INT_SAMPLER_2D_ARRAY:
+ case gluShaderUtil.DataType.INT_SAMPLER_3D:
+ return gluShaderUtil.DataType.INT_VEC4;
+
+ case gluShaderUtil.DataType.SAMPLER_2D_SHADOW:
+ case gluShaderUtil.DataType.SAMPLER_CUBE_SHADOW:
+ case gluShaderUtil.DataType.SAMPLER_2D_ARRAY_SHADOW:
+ return gluShaderUtil.DataType.FLOAT;
+
+ default:
+ throw new Error('es3fUniformApiTests.getSamplerLookupReturnType - Invalid type');
+ }
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} T DataType to compare the type. Used to be a template param
+ * @param {gluShaderUtil.DataType} t
+ * @return {boolean}
+ */
+ es3fUniformApiTests.dataTypeEquals = function(T, t) {
+ return t == T;
+ };
+
+ /**
+ * @param {number} N Row number. Used to be a template parameter
+ * @param {gluShaderUtil.DataType} t
+ * @return {boolean}
+ */
+ es3fUniformApiTests.dataTypeIsMatrixWithNRows = function(N, t) {
+ return gluShaderUtil.isDataTypeMatrix(t) && gluShaderUtil.getDataTypeMatrixNumRows(t) == N;
+ };
+
+ /**
+ * @param {gluVarType.VarType} type
+ * @param {es3fUniformApiTests.dataTypePredicate} predicate
+ * @return {boolean}
+ */
+ es3fUniformApiTests.typeContainsMatchingBasicType = function(type, predicate) {
+ if (type.isBasicType())
+ return predicate(type.getBasicType());
+ else if (type.isArrayType())
+ return es3fUniformApiTests.typeContainsMatchingBasicType(type.getElementType(), predicate);
+ else {
+ assertMsgOptions(type.isStructType(), 'es3fUniformApiTests.typeContainsMatchingBasicType - not a struct type', false, true);
+ /** @type {gluVarType.StructType} */ var structType = type.getStruct();
+ for (var i = 0; i < structType.getSize(); i++)
+ if (es3fUniformApiTests.typeContainsMatchingBasicType(structType.getMember(i).getType(), predicate))
+ return true;
+ return false;
+ }
+ };
+
+ /**
+ * @param {Array<gluShaderUtil.DataType>} dst
+ * @param {gluVarType.VarType} type
+ */
+ es3fUniformApiTests.getDistinctSamplerTypes = function(dst, type) {
+ if (type.isBasicType()) {
+ /** @type {gluShaderUtil.DataType} */ var basicType = type.getBasicType();
+ if (gluShaderUtil.isDataTypeSampler(basicType) && dst.indexOf(basicType) == -1)
+ dst.push(basicType);
+ } else if (type.isArrayType())
+ es3fUniformApiTests.getDistinctSamplerTypes(dst, type.getElementType());
+ else {
+ assertMsgOptions(type.isStructType(), 'es3fUniformApiTests.getDistinctSamplerTypes - not a struct type', false, true);
+ /** @type {gluVarType.StructType} */ var structType = type.getStruct();
+ for (var i = 0; i < structType.getSize(); i++)
+ es3fUniformApiTests.getDistinctSamplerTypes(dst, structType.getMember(i).getType());
+ }
+ };
+
+ /**
+ * @param {gluVarType.VarType} type
+ * @return {number}
+ */
+ es3fUniformApiTests.getNumSamplersInType = function(type) {
+ if (type.isBasicType())
+ return gluShaderUtil.isDataTypeSampler(type.getBasicType()) ? 1 : 0;
+ else if (type.isArrayType())
+ return es3fUniformApiTests.getNumSamplersInType(type.getElementType()) * type.getArraySize();
+ else {
+ assertMsgOptions(type.isStructType(), 'es3fUniformApiTests.getNumSamplersInType - not a struct type', false, true);
+ /** @type {gluVarType.StructType} */ var structType = type.getStruct();
+ /** @type {number} */ var sum = 0;
+ for (var i = 0; i < structType.getSize(); i++)
+ sum += es3fUniformApiTests.getNumSamplersInType(structType.getMember(i).getType());
+ return sum;
+ }
+ };
+
+ /** @typedef { {type: gluVarType.VarType, ndx: number}} */
+ es3fUniformApiTests.VarTypeWithIndex;
+
+ /**
+ * @param {number} maxDepth
+ * @param {number} curStructIdx Out parameter, instead returning it in the VarTypeWithIndex structure.
+ * @param {Array<gluVarType.StructType>} structTypesDst
+ * @param {deRandom.Random} rnd
+ * @return {es3fUniformApiTests.VarTypeWithIndex}
+ */
+ es3fUniformApiTests.generateRandomType = function(maxDepth, curStructIdx, structTypesDst, rnd) {
+ /** @type {boolean} */ var isStruct = maxDepth > 0 && rnd.getFloat() < 0.2;
+ /** @type {boolean} */ var isArray = rnd.getFloat() < 0.3;
+
+ if (isStruct) {
+ /** @type {number} */ var numMembers = rnd.getInt(1, 5);
+ /** @type {gluVarType.StructType} */ var structType = gluVarType.newStructType('structType' + curStructIdx++);
+
+ for (var i = 0; i < numMembers; i++) {
+ /** @type {es3fUniformApiTests.VarTypeWithIndex} */ var typeWithIndex = es3fUniformApiTests.generateRandomType(maxDepth - 1, curStructIdx, structTypesDst, rnd);
+ curStructIdx = typeWithIndex.ndx;
+ structType.addMember('m' + i, typeWithIndex.type);
+ }
+
+ structTypesDst.push(structType);
+ return (isArray ? {
+ type: gluVarType.newTypeArray(gluVarType.newTypeStruct(structType), rnd.getInt(1, 5)),
+ ndx: curStructIdx
+ }
+ : {
+ type: gluVarType.newTypeStruct(structType),
+ ndx: curStructIdx
+ });
+ } else {
+ /** @type {gluShaderUtil.DataType} */ var basicType = es3fUniformApiTests.s_testDataTypes[rnd.getInt(0, es3fUniformApiTests.s_testDataTypes.length - 1)];
+ /** @type {gluShaderUtil.precision} */ var precision;
+ if (!gluShaderUtil.isDataTypeBoolOrBVec(basicType))
+ precision = gluShaderUtil.precision.PRECISION_MEDIUMP;
+ return (isArray ? {
+ type: gluVarType.newTypeArray(gluVarType.newTypeBasic(basicType, precision), rnd.getInt(1, 5)),
+ ndx: curStructIdx
+ }
+ : {
+ type: gluVarType.newTypeBasic(basicType, precision),
+ ndx: curStructIdx
+ });
+ }
+ };
+
+ /**
+ * es3fUniformApiTests.SamplerV structure
+ * @constructor
+ */
+ es3fUniformApiTests.SamplerV = function() {
+ this.samplerV = {
+ /** @type {number} */ unit: 0,
+ /** @type {Array<number>} */ fillColor: []
+ };
+ };
+
+ /**
+ * es3fUniformApiTests.VarValue class. may contain different types.
+ * @constructor
+ */
+ es3fUniformApiTests.VarValue = function() {
+ /** @type {gluShaderUtil.DataType} */ this.type;
+ /** @type {Array<number | boolean> | es3fUniformApiTests.SamplerV} */ this.val = [];
+ };
+
+ /**
+ * @enum {number}
+ */
+ es3fUniformApiTests.CaseShaderType = {
+ VERTEX: 0,
+ FRAGMENT: 1,
+ BOTH: 2
+ };
+
+ /**
+ * es3fUniformApiTests.Uniform struct.
+ * @param {string} name_
+ * @param {gluVarType.VarType} type_
+ * @constructor
+ */
+ es3fUniformApiTests.Uniform = function(name_, type_) {
+ /** @type {string} */ this.name = name_;
+ /** @type {gluVarType.VarType} */ this.type = type_;
+ };
+
+ // A set of uniforms, along with related struct types.
+ /**
+ * class es3fUniformApiTests.UniformCollection
+ * @constructor
+ */
+ es3fUniformApiTests.UniformCollection = function() {
+ /** @type {Array<es3fUniformApiTests.Uniform>} */ this.m_uniforms = [];
+ /** @type {Array<gluVarType.StructType>} */ this.m_structTypes = [];
+ };
+
+ /**
+ * @return {number}
+ */
+ es3fUniformApiTests.UniformCollection.prototype.getNumUniforms = function() {return this.m_uniforms.length;};
+
+ /**
+ * @return {number}
+ */
+ es3fUniformApiTests.UniformCollection.prototype.getNumStructTypes = function() {return this.m_structTypes.length;};
+
+ /**
+ * @param {number} ndx
+ * @return {es3fUniformApiTests.Uniform}
+ */
+ es3fUniformApiTests.UniformCollection.prototype.getUniform = function(ndx) {return this.m_uniforms[ndx];};
+
+ /**
+ * @param {number} ndx
+ * @return {gluVarType.StructType}
+ */
+ es3fUniformApiTests.UniformCollection.prototype.getStructType = function(ndx) {return this.m_structTypes[ndx];};
+
+ /**
+ * @param {es3fUniformApiTests.Uniform} uniform
+ */
+ es3fUniformApiTests.UniformCollection.prototype.addUniform = function(uniform) {this.m_uniforms.push(uniform);};
+
+ /**
+ * @param {gluVarType.StructType} type
+ */
+ es3fUniformApiTests.UniformCollection.prototype.addStructType = function(type) {this.m_structTypes.push(type);};
+
+ // Add the contents of m_uniforms and m_structTypes to receiver, and remove them from this one.
+ // \note receiver takes ownership of the struct types.
+ /**
+ * @param {es3fUniformApiTests.UniformCollection} receiver
+ */
+ es3fUniformApiTests.UniformCollection.prototype.moveContents = function(receiver) {
+ for (var i = 0; i < this.m_uniforms.length; i++)
+ receiver.addUniform(this.m_uniforms[i]);
+ this.m_uniforms.length = 0;
+
+ for (var i = 0; i < this.m_structTypes.length; i++)
+ receiver.addStructType(this.m_structTypes[i]);
+ this.m_structTypes.length = 0;
+ };
+
+ /**
+ * @param {es3fUniformApiTests.dataTypePredicate} predicate
+ * @return {boolean}
+ */
+ es3fUniformApiTests.UniformCollection.prototype.containsMatchingBasicType = function(predicate) {
+ for (var i = 0; i < this.m_uniforms.length; i++)
+ if (es3fUniformApiTests.typeContainsMatchingBasicType(this.m_uniforms[i].type, predicate))
+ return true;
+ return false;
+ };
+
+ /**
+ * @return {Array<gluShaderUtil.DataType>}
+ */
+ es3fUniformApiTests.UniformCollection.prototype.getSamplerTypes = function() {
+ /** @type {Array<gluShaderUtil.DataType>} */ var samplerTypes = [];
+ for (var i = 0; i < this.m_uniforms.length; i++)
+ es3fUniformApiTests.getDistinctSamplerTypes(samplerTypes, this.m_uniforms[i].type);
+ return samplerTypes;
+ };
+
+ /**
+ * @return {boolean}
+ */
+ es3fUniformApiTests.UniformCollection.prototype.containsSeveralSamplerTypes = function() {
+ return this.getSamplerTypes().length > 1;
+ };
+
+ /**
+ * @return {number}
+ */
+ es3fUniformApiTests.UniformCollection.prototype.getNumSamplers = function() {
+ var sum = 0;
+ for (var i = 0; i < this.m_uniforms.length; i++)
+ sum += es3fUniformApiTests.getNumSamplersInType(this.m_uniforms[i].type);
+ return sum;
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} type
+ * @param {string=} nameSuffix
+ * @return {es3fUniformApiTests.UniformCollection}
+ */
+ es3fUniformApiTests.UniformCollection.basic = function(type, nameSuffix) {
+ if (nameSuffix === undefined) nameSuffix = '';
+ /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
+ /** @type {gluShaderUtil.precision} */ var prec;
+ if (!gluShaderUtil.isDataTypeBoolOrBVec(type))
+ prec = gluShaderUtil.precision.PRECISION_MEDIUMP;
+ res.m_uniforms.push(new es3fUniformApiTests.Uniform('u_var' + nameSuffix, gluVarType.newTypeBasic(type, prec)));
+ return res;
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} type
+ * @param {string=} nameSuffix
+ * @return {es3fUniformApiTests.UniformCollection}
+ */
+ es3fUniformApiTests.UniformCollection.basicArray = function(type, nameSuffix) {
+ if (nameSuffix === undefined) nameSuffix = '';
+ /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
+ /** @type {gluShaderUtil.precision} */ var prec;
+ if (!gluShaderUtil.isDataTypeBoolOrBVec(type))
+ prec = gluShaderUtil.precision.PRECISION_MEDIUMP;
+ res.m_uniforms.push(new es3fUniformApiTests.Uniform('u_var' + nameSuffix, gluVarType.newTypeArray(gluVarType.newTypeBasic(type, prec), 3)));
+ return res;
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} type0
+ * @param {gluShaderUtil.DataType} type1
+ * @param {boolean} containsArrays
+ * @param {string=} nameSuffix
+ * @return {es3fUniformApiTests.UniformCollection}
+ */
+ es3fUniformApiTests.UniformCollection.basicStruct = function(type0, type1, containsArrays, nameSuffix) {
+ if (nameSuffix === undefined) nameSuffix = '';
+ /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
+ /** @type {gluShaderUtil.precision} */ var prec0;
+ if (!gluShaderUtil.isDataTypeBoolOrBVec(type0))
+ prec0 = gluShaderUtil.precision.PRECISION_MEDIUMP;
+ /** @type {gluShaderUtil.precision} */ var prec1;
+ if (!gluShaderUtil.isDataTypeBoolOrBVec(type1))
+ prec1 = gluShaderUtil.precision.PRECISION_MEDIUMP;
+
+ /** @type {gluVarType.StructType} */ var structType = gluVarType.newStructType('structType' + nameSuffix);
+ structType.addMember('m0', gluVarType.newTypeBasic(type0, prec0));
+ structType.addMember('m1', gluVarType.newTypeBasic(type1, prec1));
+ if (containsArrays) {
+ structType.addMember('m2', gluVarType.newTypeArray(gluVarType.newTypeBasic(type0, prec0), 3));
+ structType.addMember('m3', gluVarType.newTypeArray(gluVarType.newTypeBasic(type1, prec1), 3));
+ }
+
+ res.addStructType(structType);
+ res.addUniform(new es3fUniformApiTests.Uniform('u_var' + nameSuffix, gluVarType.newTypeStruct(structType)));
+
+ return res;
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} type0
+ * @param {gluShaderUtil.DataType} type1
+ * @param {boolean} containsArrays
+ * @param {string=} nameSuffix
+ * @return {es3fUniformApiTests.UniformCollection}
+ */
+ es3fUniformApiTests.UniformCollection.structInArray = function(type0, type1, containsArrays, nameSuffix) {
+ if (nameSuffix === undefined) nameSuffix = '';
+ /** @type {es3fUniformApiTests.UniformCollection} */ var res = es3fUniformApiTests.UniformCollection.basicStruct(type0, type1, containsArrays, nameSuffix);
+ res.getUniform(0).type = gluVarType.newTypeArray(res.getUniform(0).type, 3);
+ return res;
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} type0
+ * @param {gluShaderUtil.DataType} type1
+ * @param {string=} nameSuffix
+ * @return {es3fUniformApiTests.UniformCollection}
+ */
+ es3fUniformApiTests.UniformCollection.nestedArraysStructs = function(type0, type1, nameSuffix) {
+ if (nameSuffix === undefined) nameSuffix = '';
+ /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
+ /** @type {gluShaderUtil.precision} */ var prec0;
+ if (!gluShaderUtil.isDataTypeBoolOrBVec(type0))
+ prec0 = gluShaderUtil.precision.PRECISION_MEDIUMP;
+ /** @type {gluShaderUtil.precision} */ var prec1;
+ if (!gluShaderUtil.isDataTypeBoolOrBVec(type1))
+ prec1 = gluShaderUtil.precision.PRECISION_MEDIUMP;
+ /** @type {gluVarType.StructType} */ var structType = gluVarType.newStructType('structType' + nameSuffix);
+ /** @type {gluVarType.StructType} */ var subStructType = gluVarType.newStructType('subStructType' + nameSuffix);
+ /** @type {gluVarType.StructType} */ var subSubStructType = gluVarType.newStructType('subSubStructType' + nameSuffix);
+
+ subSubStructType.addMember('mss0', gluVarType.newTypeBasic(type0, prec0));
+ subSubStructType.addMember('mss1', gluVarType.newTypeBasic(type1, prec1));
+
+ subStructType.addMember('ms0', gluVarType.newTypeBasic(type1, prec1));
+ subStructType.addMember('ms1', gluVarType.newTypeArray(gluVarType.newTypeBasic(type0, prec0), 2));
+ subStructType.addMember('ms2', gluVarType.newTypeArray(gluVarType.newTypeStruct(subSubStructType), 2));
+
+ structType.addMember('m0', gluVarType.newTypeBasic(type0, prec0));
+ structType.addMember('m1', gluVarType.newTypeStruct(subStructType));
+ structType.addMember('m2', gluVarType.newTypeBasic(type1, prec1));
+
+ res.addStructType(subSubStructType);
+ res.addStructType(subStructType);
+ res.addStructType(structType);
+
+ res.addUniform(new es3fUniformApiTests.Uniform('u_var' + nameSuffix, gluVarType.newTypeStruct(structType)));
+
+ return res;
+ };
+
+ /**
+ * @param {string=} nameSuffix
+ * @return {es3fUniformApiTests.UniformCollection}
+ */
+ es3fUniformApiTests.UniformCollection.multipleBasic = function(nameSuffix) {
+ if (nameSuffix === undefined) nameSuffix = '';
+ /** @type {Array<gluShaderUtil.DataType>} */ var types = [gluShaderUtil.DataType.FLOAT, gluShaderUtil.DataType.INT_VEC3, gluShaderUtil.DataType.UINT_VEC4, gluShaderUtil.DataType.FLOAT_MAT3, gluShaderUtil.DataType.BOOL_VEC2];
+ /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
+
+ for (var i = 0; i < types.length; i++) {
+ /** @type {es3fUniformApiTests.UniformCollection} */ var sub = es3fUniformApiTests.UniformCollection.basic(types[i], '_' + i + nameSuffix);
+ sub.moveContents(res);
+ }
+
+ return res;
+ };
+
+ /**
+ * @param {string=} nameSuffix
+ * @return {es3fUniformApiTests.UniformCollection}
+ */
+ es3fUniformApiTests.UniformCollection.multipleBasicArray = function(nameSuffix) {
+ if (nameSuffix === undefined) nameSuffix = '';
+ /** @type {Array<gluShaderUtil.DataType>} */ var types = [gluShaderUtil.DataType.FLOAT, gluShaderUtil.DataType.INT_VEC3, gluShaderUtil.DataType.BOOL_VEC2];
+ /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
+
+ for (var i = 0; i < types.length; i++) {
+ /** @type {es3fUniformApiTests.UniformCollection} */ var sub = es3fUniformApiTests.UniformCollection.basicArray(types[i], '_' + i + nameSuffix);
+ sub.moveContents(res);
+ }
+
+ return res;
+ };
+
+ /**
+ * @param {string=} nameSuffix
+ * @return {es3fUniformApiTests.UniformCollection}
+ */
+ es3fUniformApiTests.UniformCollection.multipleNestedArraysStructs = function(nameSuffix) {
+ if (nameSuffix === undefined) nameSuffix = '';
+ /** @type {Array<gluShaderUtil.DataType>} */ var types0 = [gluShaderUtil.DataType.FLOAT, gluShaderUtil.DataType.INT, gluShaderUtil.DataType.BOOL_VEC4];
+ /** @type {Array<gluShaderUtil.DataType>} */ var types1 = [gluShaderUtil.DataType.FLOAT_VEC4, gluShaderUtil.DataType.INT_VEC4, gluShaderUtil.DataType.BOOL];
+ /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
+
+ assertMsgOptions(types0.length == types1.length, 'es3fUniformApiTests.UniformCollection.multipleNestedArraysStructs - lengths are not the same', false, true);
+
+ for (var i = 0; i < types0.length; i++) {
+ /** @type {es3fUniformApiTests.UniformCollection} */ var sub = es3fUniformApiTests.UniformCollection.nestedArraysStructs(types0[i], types1[i], '_' + i + nameSuffix);
+ sub.moveContents(res);
+ }
+
+ return res;
+ };
+
+ /**
+ * @param {number} seed
+ * @return {es3fUniformApiTests.UniformCollection}
+ */
+ es3fUniformApiTests.UniformCollection.random = function(seed) {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(seed);
+ /** @type {number} */ var numUniforms = rnd.getInt(1, 5);
+ /** @type {number} */ var structIdx = 0;
+ /** @type {es3fUniformApiTests.UniformCollection} */ var res = new es3fUniformApiTests.UniformCollection();
+
+ for (var i = 0; i < numUniforms; i++) {
+ /** @type {Array<gluVarType.StructType>} */ var structTypes = [];
+ /** @type {es3fUniformApiTests.Uniform} */ var uniform = new es3fUniformApiTests.Uniform('u_var' + i, new gluVarType.VarType());
+
+ // \note Discard uniforms that would cause number of samplers to exceed es3fUniformApiTests.MAX_NUM_SAMPLER_UNIFORMS.
+ do {
+ var temp = es3fUniformApiTests.generateRandomType(3, structIdx, structTypes, rnd);
+ structIdx = temp.ndx;
+ uniform.type = temp.type;
+ } while (res.getNumSamplers() + es3fUniformApiTests.getNumSamplersInType(uniform.type) > es3fUniformApiTests.MAX_NUM_SAMPLER_UNIFORMS);
+
+ res.addUniform(uniform);
+ for (var j = 0; j < structTypes.length; j++)
+ res.addStructType(structTypes[j]);
+ }
+
+ return res;
+ };
+
+ /**
+ * @param {es3fUniformApiTests.VarValue} sampler
+ * @return {es3fUniformApiTests.VarValue}
+ */
+ es3fUniformApiTests.getSamplerFillValue = function(sampler) {
+ assertMsgOptions(gluShaderUtil.isDataTypeSampler(sampler.type), 'es3fUniformApiTests.getSamplerFillValue - not a sampler type', false, true);
+
+ /** @type {es3fUniformApiTests.VarValue} */ var result = new es3fUniformApiTests.VarValue();
+ result.type = es3fUniformApiTests.getSamplerLookupReturnType(sampler.type);
+
+ switch (result.type) {
+ case gluShaderUtil.DataType.FLOAT_VEC4:
+ for (var i = 0; i < 4; i++)
+ result.val[i] = sampler.val.samplerV.fillColor[i];
+ break;
+ case gluShaderUtil.DataType.UINT_VEC4:
+ for (var i = 0; i < 4; i++)
+ result.val[i] = sampler.val.samplerV.fillColor[i];
+ break;
+ case gluShaderUtil.DataType.INT_VEC4:
+ for (var i = 0; i < 4; i++)
+ result.val[i] = sampler.val.samplerV.fillColor[i];
+ break;
+ case gluShaderUtil.DataType.FLOAT:
+ result.val[0] = sampler.val.samplerV.fillColor[0];
+ break;
+ default:
+ throw new Error('es3fUniformApiTests.getSamplerFillValue - Invalid type');
+ }
+
+ return result;
+ };
+
+ /**
+ * @param {es3fUniformApiTests.VarValue} sampler
+ * @return {es3fUniformApiTests.VarValue}
+ */
+ es3fUniformApiTests.getSamplerUnitValue = function(sampler) {
+ assertMsgOptions(gluShaderUtil.isDataTypeSampler(sampler.type), 'es3fUniformApiTests.getSamplerUnitValue - not a sampler type', false, true);
+
+ /** @type {es3fUniformApiTests.VarValue} */ var result = new es3fUniformApiTests.VarValue();
+ result.type = gluShaderUtil.DataType.INT;
+ result.val[0] = sampler.val.samplerV.unit;
+
+ return result;
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} original
+ * @return {gluShaderUtil.DataType}
+ */
+ es3fUniformApiTests.getDataTypeTransposedMatrix = function(original) {
+ return gluShaderUtil.getDataTypeMatrix(gluShaderUtil.getDataTypeMatrixNumRows(original), gluShaderUtil.getDataTypeMatrixNumColumns(original));
+ };
+
+ /**
+ * @param {es3fUniformApiTests.VarValue} original
+ * @return {es3fUniformApiTests.VarValue}
+ */
+ es3fUniformApiTests.getTransposeMatrix = function(original) {
+ assertMsgOptions(gluShaderUtil.isDataTypeMatrix(original.type), 'es3fUniformApiTests.getTransposeMatrix - not a matrix', false, true);
+
+ /** @type {number} */ var rows = gluShaderUtil.getDataTypeMatrixNumRows(original.type);
+ /** @type {number} */ var cols = gluShaderUtil.getDataTypeMatrixNumColumns(original.type);
+ /** @type {es3fUniformApiTests.VarValue} */ var result = new es3fUniformApiTests.VarValue();
+ result.type = es3fUniformApiTests.getDataTypeTransposedMatrix(original.type);
+
+ for (var i = 0; i < rows; i++)
+ for (var j = 0; j < cols; j++)
+ result.val[i * cols + j] = original.val[j * rows + i];
+
+ return result;
+ };
+
+ /**
+ * @param {es3fUniformApiTests.VarValue} value
+ * @return {string}
+ */
+ es3fUniformApiTests.shaderVarValueStr = function(value) {
+ /** @type {number} */ var numElems = gluShaderUtil.getDataTypeScalarSize(value.type);
+ /** @type {string} */ var result = '';
+
+ if (numElems > 1)
+ result += gluShaderUtil.getDataTypeName(value.type) + '(';
+
+ for (var i = 0; i < numElems; i++) {
+ if (i > 0)
+ result += ', ';
+
+ if (gluShaderUtil.isDataTypeFloatOrVec(value.type) || gluShaderUtil.isDataTypeMatrix(value.type))
+ result += value.val[i].toFixed(2);
+ else if (gluShaderUtil.isDataTypeIntOrIVec((value.type)))
+ result += value.val[i];
+ else if (gluShaderUtil.isDataTypeUintOrUVec((value.type)))
+ result += value.val[i] + 'u';
+ else if (gluShaderUtil.isDataTypeBoolOrBVec((value.type)))
+ result += value.val[i] ? 'true' : 'false';
+ else if (gluShaderUtil.isDataTypeSampler((value.type)))
+ result += es3fUniformApiTests.shaderVarValueStr(es3fUniformApiTests.getSamplerFillValue(value));
+ else
+ throw new Error('es3fUniformApiTests.shaderVarValueStr - invalid type');
+ }
+
+ if (numElems > 1)
+ result += ')';
+
+ return result;
+ };
+
+ /**
+ * @param {es3fUniformApiTests.VarValue} value
+ * @return {string}
+ */
+ es3fUniformApiTests.apiVarValueStr = function(value) {
+ /** @type {number} */ var numElems = gluShaderUtil.getDataTypeScalarSize(value.type);
+ /** @type {string} */ var result = '';
+
+ if (numElems > 1)
+ result += '(';
+
+ for (var i = 0; i < numElems; i++) {
+ if (i > 0)
+ result += ', ';
+
+ if (gluShaderUtil.isDataTypeFloatOrVec(value.type) || gluShaderUtil.isDataTypeMatrix(value.type))
+ result += value.val[i].toFixed(2);
+ else if (gluShaderUtil.isDataTypeIntOrIVec(value.type) ||
+ gluShaderUtil.isDataTypeUintOrUVec(value.type))
+ result += value.val[i];
+ else if (gluShaderUtil.isDataTypeBoolOrBVec(value.type))
+ result += value.val[i] ? 'true' : 'false';
+ else if (gluShaderUtil.isDataTypeSampler(value.type))
+ result += value.val.samplerV.unit;
+ else
+ throw new Error('es3fUniformApiTests.apiVarValueStr - Invalid type');
+ }
+
+ if (numElems > 1)
+ result += ')';
+
+ return result;
+ };
+
+ // samplerUnit used if type is a sampler type. \note Samplers' unit numbers are not randomized.
+ /**
+ * @param {gluShaderUtil.DataType} type
+ * @param {deRandom.Random} rnd
+ * @param {number=} samplerUnit
+ * @return {es3fUniformApiTests.VarValue}
+ */
+ es3fUniformApiTests.generateRandomVarValue = function(type, rnd, samplerUnit) {
+ if (samplerUnit === undefined) samplerUnit = -1;
+ /** @type {number} */ var numElems = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {es3fUniformApiTests.VarValue} */ var result = new es3fUniformApiTests.VarValue();
+ result.type = type;
+
+ assertMsgOptions(
+ (samplerUnit >= 0) == (gluShaderUtil.isDataTypeSampler(type)),
+ 'es3fUniformApiTests.generateRandomVarValue - sampler units do not match type', false, true
+ );
+
+ if (gluShaderUtil.isDataTypeFloatOrVec(type) || gluShaderUtil.isDataTypeMatrix(type)) {
+ for (var i = 0; i < numElems; i++)
+ result.val[i] = rnd.getFloat(-10.0, 10.0);
+ } else if (gluShaderUtil.isDataTypeIntOrIVec(type)) {
+ for (var i = 0; i < numElems; i++)
+ result.val[i] = rnd.getInt(-10, 10);
+ } else if (gluShaderUtil.isDataTypeUintOrUVec(type)) {
+ for (var i = 0; i < numElems; i++)
+ result.val[i] = rnd.getInt(0, 10);
+ } else if (gluShaderUtil.isDataTypeBoolOrBVec(type)) {
+ for (var i = 0; i < numElems; i++)
+ result.val[i] = rnd.getBool();
+ } else if (gluShaderUtil.isDataTypeSampler(type)) {
+ /** @type {gluShaderUtil.DataType} */ var texResultType = es3fUniformApiTests.getSamplerLookupReturnType(type);
+ /** @type {gluShaderUtil.DataType} */ var texResultScalarType = gluShaderUtil.getDataTypeScalarTypeAsDataType(texResultType);
+ /** @type {number} */ var texResultNumDims = gluShaderUtil.getDataTypeScalarSize(texResultType);
+
+ result.val = new es3fUniformApiTests.SamplerV();
+ result.val.samplerV.unit = samplerUnit;
+
+ for (var i = 0; i < texResultNumDims; i++) {
+ switch (texResultScalarType) {
+ case gluShaderUtil.DataType.FLOAT: result.val.samplerV.fillColor[i] = rnd.getFloat(0.0, 1.0); break;
+ case gluShaderUtil.DataType.INT: result.val.samplerV.fillColor[i] = rnd.getInt(-10, 10); break;
+ case gluShaderUtil.DataType.UINT: result.val.samplerV.fillColor[i] = rnd.getInt(0, 10); break;
+ default:
+ throw new Error('es3fUniformApiTests.generateRandomVarValue - Invalid scalar type');
+ }
+ }
+ } else
+ throw new Error('es3fUniformApiTests.generateRandomVarValue - Invalid type');
+
+ return result;
+ };
+
+ /**
+ * @param {gluShaderUtil.DataType} type
+ * @return {es3fUniformApiTests.VarValue}
+ */
+ es3fUniformApiTests.generateZeroVarValue = function(type) {
+ /** @type {number} */ var numElems = gluShaderUtil.getDataTypeScalarSize(type);
+ /** @type {es3fUniformApiTests.VarValue} */ var result = new es3fUniformApiTests.VarValue();
+ result.type = type;
+
+ if (gluShaderUtil.isDataTypeFloatOrVec(type) || gluShaderUtil.isDataTypeMatrix(type)) {
+ for (var i = 0; i < numElems; i++)
+ result.val[i] = 0.0;
+ } else if (gluShaderUtil.isDataTypeIntOrIVec(type)) {
+ for (var i = 0; i < numElems; i++)
+ result.val[i] = 0;
+ } else if (gluShaderUtil.isDataTypeUintOrUVec(type)) {
+ for (var i = 0; i < numElems; i++)
+ result.val[i] = 0;
+ } else if (gluShaderUtil.isDataTypeBoolOrBVec(type)) {
+ for (var i = 0; i < numElems; i++)
+ result.val[i] = false;
+ } else if (gluShaderUtil.isDataTypeSampler(type)) {
+ /** @type {gluShaderUtil.DataType} */ var texResultType = es3fUniformApiTests.getSamplerLookupReturnType(type);
+ /** @type {gluShaderUtil.DataType} */ var texResultScalarType = gluShaderUtil.getDataTypeScalarTypeAsDataType(texResultType);
+ /** @type {number} */ var texResultNumDims = gluShaderUtil.getDataTypeScalarSize(texResultType);
+
+ result.val = new es3fUniformApiTests.SamplerV();
+ result.val.samplerV.unit = 0;
+
+ for (var i = 0; i < texResultNumDims; i++) {
+ switch (texResultScalarType) {
+ case gluShaderUtil.DataType.FLOAT: result.val.samplerV.fillColor[i] = 0.12 * i; break;
+ case gluShaderUtil.DataType.INT: result.val.samplerV.fillColor[i] = -2 + i; break;
+ case gluShaderUtil.DataType.UINT: result.val.samplerV.fillColor[i] = 4 + i; break;
+ default:
+ throw new Error('es3fUniformApiTests.generateZeroVarValue - Invalid scalar type');
+ }
+ }
+ } else
+ throw new Error('es3fUniformApiTests.generateZeroVarValue - Invalid type');
+
+ return result;
+ };
+
+ /**
+ * @param {es3fUniformApiTests.VarValue} a
+ * @param {es3fUniformApiTests.VarValue} b
+ * @return {boolean}
+ */
+ es3fUniformApiTests.apiVarValueEquals = function(a, b) {
+ /** @type {number} */ var size = gluShaderUtil.getDataTypeScalarSize(a.type);
+ /** @type {number} */ var floatThreshold = 0.05;
+
+ assertMsgOptions(a.type == b.type, 'es3fUniformApiTests.apiVarValueEquals - types are different', false, true);
+
+ if (gluShaderUtil.isDataTypeFloatOrVec(a.type) || gluShaderUtil.isDataTypeMatrix(a.type)) {
+ for (var i = 0; i < size; i++)
+ if (Math.abs(a.val[i] - b.val[i]) >= floatThreshold)
+ return false;
+ } else if (gluShaderUtil.isDataTypeIntOrIVec(a.type)) {
+ for (var i = 0; i < size; i++)
+ if (a.val[i] != b.val[i])
+ return false;
+ } else if (gluShaderUtil.isDataTypeUintOrUVec(a.type)) {
+ for (var i = 0; i < size; i++)
+ if (a.val[i] != b.val[i])
+ return false;
+ } else if (gluShaderUtil.isDataTypeBoolOrBVec(a.type)) {
+ for (var i = 0; i < size; i++)
+ if (a.val[i] != b.val[i])
+ return false;
+ } else if (gluShaderUtil.isDataTypeSampler(a.type)) {
+ if (a.val.samplerV.unit != b.val.samplerV.unit)
+ return false;
+ } else
+ throw new Error('es3fUniformApiTests.apiVarValueEquals - Invalid type');
+
+ return true;
+ };
+
+ /**
+ * @param {es3fUniformApiTests.VarValue} boolValue
+ * @param {gluShaderUtil.DataType} targetScalarType
+ * @param {deRandom.Random} rnd
+ * @return {es3fUniformApiTests.VarValue}
+ */
+ es3fUniformApiTests.getRandomBoolRepresentation = function(boolValue, targetScalarType, rnd) {
+ assertMsgOptions(
+ gluShaderUtil.isDataTypeBoolOrBVec(boolValue.type),
+ 'es3fUniformApiTests.getRandomBoolRepresentation - Data type not boolean or boolean vector',
+ false,
+ true
+ );
+
+ /** @type {number} */ var size = gluShaderUtil.getDataTypeScalarSize(boolValue.type);
+ /** @type {gluShaderUtil.DataType} */ var targetType = size == 1 ? targetScalarType : gluShaderUtil.getDataTypeVector(targetScalarType, size);
+ /** @type {es3fUniformApiTests.VarValue} */ var result = new es3fUniformApiTests.VarValue();
+ result.type = targetType;
+
+ switch (targetScalarType) {
+ case gluShaderUtil.DataType.INT:
+ for (var i = 0; i < size; i++) {
+ if (boolValue.val[i]) {
+ result.val[i] = rnd.getInt(-10, 10);
+ if (result.val[i] == 0)
+ result.val[i] = 1;
+ } else
+ result.val[i] = 0;
+ }
+ break;
+
+ case gluShaderUtil.DataType.UINT:
+ for (var i = 0; i < size; i++) {
+ if (boolValue.val[i])
+ result.val[i] = rnd.getInt(1, 10);
+ else
+ result.val[i] = 0;
+ }
+ break;
+
+ case gluShaderUtil.DataType.FLOAT:
+ for (var i = 0; i < size; i++) {
+ if (boolValue.val[i]) {
+ result.val[i] = rnd.getFloat(-10.0, 10.0);
+ if (result.val[i] == 0.0)
+ result.val[i] = 1.0;
+ } else
+ result.val[i] = 0;
+ }
+ break;
+
+ default:
+ throw new Error('es3fUniformApiTests.getRandomBoolRepresentation - Invalid type');
+ }
+
+ return result;
+ };
+
+ /**
+ * @param {es3fUniformApiTests.CaseShaderType} type
+ * @return {?string}
+ */
+ es3fUniformApiTests.getCaseShaderTypeName = function(type) {
+ switch (type) {
+ case es3fUniformApiTests.CaseShaderType.VERTEX: return 'vertex';
+ case es3fUniformApiTests.CaseShaderType.FRAGMENT: return 'fragment';
+ case es3fUniformApiTests.CaseShaderType.BOTH: return 'both';
+ default:
+ throw new Error('es3fUniformApiTests.getCaseShaderTypeName - Invalid shader type');
+ }
+ };
+
+ /**
+ * @param {number} seed
+ * @return {number}
+ */
+ es3fUniformApiTests.randomCaseShaderType = function(seed) {
+ return (new deRandom.Random(seed)).getInt(0, Object.keys(es3fUniformApiTests.CaseShaderType).length - 1);
+ };
+
+ //es3fUniformApiTests.UniformCase definitions
+
+ /**
+ * es3fUniformApiTests.Feature - Implemented as a function to create an object without unwanted properties.
+ * @constructor
+ */
+ es3fUniformApiTests.Feature = function() {
+ // ARRAYUSAGE_ONLY_MIDDLE_INDEX: only middle index of each array is used in shader. If not given, use all indices.
+ this.ARRAYUSAGE_ONLY_MIDDLE_INDEX = false;
+
+ // UNIFORMFUNC_VALUE: use pass-by-value versions of uniform assignment funcs, e.g. glUniform1f(), where possible. If not given, use pass-by-pointer versions.
+ this.UNIFORMFUNC_VALUE = false;
+
+ // MATRIXMODE_ROWMAJOR: pass matrices to GL in row major form. If not given, use column major.
+ this.MATRIXMODE_ROWMAJOR = false;
+
+ // ARRAYASSIGN: how basic-type arrays are assigned with glUniform*(). If none given, assign each element of an array separately.
+ this.ARRAYASSIGN_FULL = false; //!< Assign all elements of an array with one glUniform*().
+ this.ARRAYASSIGN_BLOCKS_OF_TWO = false; //!< Assign two elements per one glUniform*().
+
+ // UNIFORMUSAGE_EVERY_OTHER: use about half of the uniforms. If not given, use all uniforms (except that some array indices may be omitted according to ARRAYUSAGE).
+ this.UNIFORMUSAGE_EVERY_OTHER = false;
+
+ // BOOLEANAPITYPE: type used to pass booleans to and from GL api. If none given, use float.
+ this.BOOLEANAPITYPE_INT = false;
+ this.BOOLEANAPITYPE_UINT = false;
+
+ // UNIFORMVALUE_ZERO: use zero-valued uniforms. If not given, use random uniform values.
+ this.UNIFORMVALUE_ZERO = false;
+
+ // ARRAY_FIRST_ELEM_NAME_NO_INDEX: in certain API functions, when referring to the first element of an array, use just the array name without [0] at the end.
+ this.ARRAY_FIRST_ELEM_NAME_NO_INDEX = false;
+ };
+
+ // A basic uniform is a uniform (possibly struct or array member) whose type is a basic type (e.g. float, ivec4, sampler2d).
+ /**
+ * @constructor
+ * @param {string} name_
+ * @param {gluShaderUtil.DataType} type_
+ * @param {boolean} isUsedInShader_
+ * @param {es3fUniformApiTests.VarValue} finalValue_
+ * @param {string=} rootName_
+ * @param {number=} elemNdx_
+ * @param {number=} rootSize_
+ */
+ es3fUniformApiTests.BasicUniform = function(name_, type_, isUsedInShader_, finalValue_, rootName_, elemNdx_, rootSize_) {
+ /** @type {string} */ this.name = name_;
+ /** @type {gluShaderUtil.DataType} */ this.type = type_;
+ /** @type {boolean} */ this.isUsedInShader = isUsedInShader_;
+ /** @type {es3fUniformApiTests.VarValue} */ this.finalValue = finalValue_; //!< The value we ultimately want to set for this uniform.
+
+ /** @type {string} */ this.rootName = rootName_ === undefined ? name_ : rootName_; //!< If this is a member of a basic-typed array, rootName is the name of that array with "[0]" appended. Otherwise it equals name.
+ /** @type {number} */ this.elemNdx = elemNdx_ === undefined ? -1 : elemNdx_; //!< If this is a member of a basic-typed array, elemNdx is the index in that array. Otherwise -1.
+ /** @type {number} */ this.rootSize = rootSize_ === undefined ? 1 : rootSize_; //!< If this is a member of a basic-typed array, rootSize is the size of that array. Otherwise 1.
+ };
+
+ /**
+ * @param {Array<es3fUniformApiTests.BasicUniform>} vec
+ * @param {string} name
+ * @return {es3fUniformApiTests.BasicUniform}
+ */
+ es3fUniformApiTests.BasicUniform.findWithName = function(vec, name) {
+ for (var i = 0; i < vec.length; i++) {
+ if (vec[i].name == name)
+ return vec[i];
+ }
+ return null;
+ };
+
+ // Reference values for info that is expected to be reported by glGetActiveUniform() or glGetActiveUniforms().
+ /**
+ * @constructor
+ * @param {string} name_
+ * @param {gluShaderUtil.DataType} type_
+ * @param {boolean} used
+ */
+ es3fUniformApiTests.BasicUniformReportRef = function(name_, type_, used) {
+ /** @type {string} */ this.name = name_;
+ // \note minSize and maxSize are for arrays and can be distinct since implementations are allowed, but not required, to trim the inactive end indices of arrays.
+ /** @type {number} */ this.minSize = 1;
+ /** @type {number} */ this.maxSize = 1;
+ /** @type {gluShaderUtil.DataType} */ this.type = type_;
+ /** @type {boolean} */ this.isUsedInShader = used;
+ };
+
+ /**
+ * To be used after constructor
+ * @param {number} minS
+ * @param {number} maxS
+ * @return {es3fUniformApiTests.BasicUniformReportRef}
+ */
+ es3fUniformApiTests.BasicUniformReportRef.prototype.constructor_A = function(minS, maxS) {
+ this.minSize = minS;
+ this.maxSize = maxS;
+
+ assertMsgOptions(
+ this.minSize <= this.maxSize,
+ 'es3fUniformApiTests.BasicUniformReportRef.prototype.constructor_A - min size not smaller or equal than max size',
+ false,
+ true
+ );
+
+ return this;
+ };
+
+ // Info that is actually reported by glGetActiveUniform() or glGetActiveUniforms().
+ /**
+ * @constructor
+ * @param {string} name_
+ * @param {number} nameLength_
+ * @param {number} size_
+ * @param {gluShaderUtil.DataType} type_
+ * @param {number} index_
+ */
+ es3fUniformApiTests.BasicUniformReportGL = function(name_, nameLength_, size_, type_, index_) {
+ this.name = name_;
+ this.nameLength = nameLength_;
+ this.size = size_;
+ this.type = type_;
+ this.index = index_;
+ };
+
+ /**
+ * @param {Array<es3fUniformApiTests.BasicUniformReportGL>} vec
+ * @param {string} name
+ * @return {es3fUniformApiTests.BasicUniformReportGL}
+ */
+ es3fUniformApiTests.BasicUniformReportGL.findWithName = function(vec, name) {
+ for (var i = 0; i < vec.length; i++) {
+ if (vec[i].name == name)
+ return vec[i];
+ }
+ return null;
+ };
+
+ /**
+ * es3fUniformApiTests.UniformCase class, inherits from TestCase class
+ * @constructor
+ * @param {string} name
+ * @param {string} description
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fUniformApiTests.UniformCase = function(name, description) { // \note Randomizes caseType, uniformCollection and features.
+ tcuTestCase.DeqpTest.call(this, name, description);
+
+ /** @type {es3fUniformApiTests.Feature} */ this.m_features;
+ /** @type {es3fUniformApiTests.UniformCollection} (SharedPtr) */ this.m_uniformCollection;
+
+ /** @type {number} */ this.m_caseShaderType = 0;
+
+ /** @type {Array<gluTexture.Texture2D>} */ this.m_textures2d = [];
+ /** @type {Array<gluTexture.TextureCube>} */ this.m_texturesCube = [];
+ /** @type {Array<number>} */ this.m_filledTextureUnits = [];
+ };
+
+ es3fUniformApiTests.UniformCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ /** es3fUniformApiTests.UniformCase prototype restore */
+ es3fUniformApiTests.UniformCase.prototype.constructor = es3fUniformApiTests.UniformCase;
+
+ /**
+ * es3fUniformApiTests.UniformCase newC. Creates a es3fUniformApiTests.UniformCase. Use after constructor.
+ * @param {number} seed
+ * @return {es3fUniformApiTests.UniformCase}
+ */
+ es3fUniformApiTests.UniformCase.prototype.newC = function(seed) {
+ this.m_features = this.randomFeatures(seed);
+ this.m_uniformCollection = es3fUniformApiTests.UniformCollection.random(seed);
+ this.m_caseShaderType = es3fUniformApiTests.randomCaseShaderType(seed);
+
+ return this;
+ };
+
+ /**
+ * es3fUniformApiTests.UniformCase new_B (static). Creates a es3fUniformApiTests.UniformCase
+ * @param {string} name
+ * @param {string} description
+ * @param {number} seed
+ * @return {es3fUniformApiTests.UniformCase}
+ */
+ es3fUniformApiTests.UniformCase.new_C = function(name, description, seed) {
+ var uniformCase = new es3fUniformApiTests.UniformCase(name, description).newC(seed);
+
+ return uniformCase;
+ };
+
+ /**
+ * es3fUniformApiTests.UniformCase new_B. Creates a es3fUniformApiTests.UniformCase. Use after constructor.
+ * @param {es3fUniformApiTests.CaseShaderType} caseShaderType
+ * @param {es3fUniformApiTests.UniformCollection} uniformCollection (SharedPtr)
+ * @param {es3fUniformApiTests.Feature} features
+ * @return {es3fUniformApiTests.UniformCase}
+ */
+ es3fUniformApiTests.UniformCase.prototype.newB = function(caseShaderType, uniformCollection, features) {
+ this.m_caseShaderType = caseShaderType;
+ this.m_uniformCollection = uniformCollection;
+ this.m_features = features;
+
+ return this;
+ };
+
+ /**
+ * es3fUniformApiTests.UniformCase new_B (static). Creates a es3fUniformApiTests.UniformCase
+ * @param {string} name
+ * @param {string} description
+ * @param {es3fUniformApiTests.CaseShaderType} caseShaderType
+ * @param {es3fUniformApiTests.UniformCollection} uniformCollection (SharedPtr)
+ * @param {es3fUniformApiTests.Feature} features
+ * @return {es3fUniformApiTests.UniformCase}
+ */
+ es3fUniformApiTests.UniformCase.new_B = function(name, description, caseShaderType, uniformCollection, features) {
+ var uniformCase = new es3fUniformApiTests.UniformCase(name, description).newB(caseShaderType, uniformCollection, features);
+
+ return uniformCase;
+ };
+
+ /**
+ * es3fUniformApiTests.UniformCase new_A. Creates a es3fUniformApiTests.UniformCase. Use after constructor.
+ * @param {es3fUniformApiTests.CaseShaderType} caseShaderType
+ * @param {es3fUniformApiTests.UniformCollection} uniformCollection (SharedPtr)
+ * @return {es3fUniformApiTests.UniformCase}
+ */
+ es3fUniformApiTests.UniformCase.prototype.newA = function(caseShaderType, uniformCollection) {
+ this.m_caseShaderType = caseShaderType;
+ this.m_uniformCollection = uniformCollection;
+ this.m_features = null;
+
+ return this;
+ };
+
+ /**
+ * es3fUniformApiTests.UniformCase new_A (static). Creates a es3fUniformApiTests.UniformCase
+ * @param {string} name
+ * @param {string} description
+ * @param {es3fUniformApiTests.CaseShaderType} caseShaderType
+ * @param {es3fUniformApiTests.UniformCollection} uniformCollection (SharedPtr)
+ * @return {es3fUniformApiTests.UniformCase}
+ */
+ es3fUniformApiTests.UniformCase.new_A = function(name, description, caseShaderType, uniformCollection) {
+ var uniformCase = new es3fUniformApiTests.UniformCase(name, description).newA(caseShaderType, uniformCollection);
+
+ return uniformCase;
+ };
+
+ /**
+ * @param {number} seed
+ * @return {es3fUniformApiTests.Feature}
+ */
+ es3fUniformApiTests.UniformCase.prototype.randomFeatures = function(seed) {
+ /** @type {es3fUniformApiTests.Feature} */ var result = new es3fUniformApiTests.Feature();
+
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(seed);
+
+ result.ARRAYUSAGE_ONLY_MIDDLE_INDEX = rnd.getBool();
+ result.UNIFORMFUNC_VALUE = rnd.getBool();
+ result.MATRIXMODE_ROWMAJOR = rnd.getBool();
+ result.ARRAYASSIGN_FULL = rnd.getBool();
+ result.ARRAYASSIGN_BLOCKS_OF_TWO = !result.ARRAYASSIGN_FULL;
+ result.UNIFORMUSAGE_EVERY_OTHER = rnd.getBool();
+ result.BOOLEANAPITYPE_INT = rnd.getBool();
+ result.BOOLEANAPITYPE_UINT = !result.BOOLEANAPITYPE_INT;
+ result.UNIFORMVALUE_ZERO = rnd.getBool();
+
+ return result;
+ };
+
+ /**
+ * Initialize the es3fUniformApiTests.UniformCase
+ */
+ es3fUniformApiTests.UniformCase.prototype.init = function() {
+ /** @type {number} */ var numSamplerUniforms = this.m_uniformCollection.getNumSamplers();
+ /** @type {number} */ var vertexTexUnitsRequired = this.m_caseShaderType != es3fUniformApiTests.CaseShaderType.FRAGMENT ? numSamplerUniforms : 0;
+ /** @type {number} */ var fragmentTexUnitsRequired = this.m_caseShaderType != es3fUniformApiTests.CaseShaderType.VERTEX ? numSamplerUniforms : 0;
+ /** @type {number} */ var combinedTexUnitsRequired = vertexTexUnitsRequired + fragmentTexUnitsRequired;
+ var vertexTexUnitsSupported = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS));
+ var fragmentTexUnitsSupported = /** @type {number} */ (gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS));
+ var combinedTexUnitsSupported = /** @type {number} */ (gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS));
+
+ assertMsgOptions(
+ numSamplerUniforms <= es3fUniformApiTests.MAX_NUM_SAMPLER_UNIFORMS,
+ 'es3fUniformApiTests.UniformCase.prototype.init - sampler uniforms exceed MAX_NUM_SAMPLER_UNIFORMS',
+ false,
+ true
+ );
+
+ if (vertexTexUnitsRequired > vertexTexUnitsSupported)
+ testFailedOptions('' + vertexTexUnitsRequired + ' vertex texture units required, ' + vertexTexUnitsSupported + ' supported', true);
+ if (fragmentTexUnitsRequired > fragmentTexUnitsSupported)
+ testFailedOptions('' + fragmentTexUnitsRequired + ' fragment texture units required, ' + fragmentTexUnitsSupported + ' supported', true);
+ if (combinedTexUnitsRequired > combinedTexUnitsSupported)
+ testFailedOptions('' + combinedTexUnitsRequired + ' combined texture units required, ' + combinedTexUnitsSupported + ' supported', true);
+ };
+
+ /**
+ * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniformsDst
+ * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsDst
+ * @param {gluVarType.VarType} varType
+ * @param {string} varName
+ * @param {boolean} isParentActive
+ * @param {number} samplerUnitCounter
+ * @param {deRandom.Random} rnd
+ * @return {number} Used to be output parameter. Sampler unit count
+ */
+ es3fUniformApiTests.UniformCase.prototype.generateBasicUniforms = function(basicUniformsDst, basicUniformReportsDst, varType, varName, isParentActive, samplerUnitCounter, rnd) {
+ /** @type {es3fUniformApiTests.VarValue} */ var value;
+
+ if (varType.isBasicType()) {
+ /** @type {boolean} */ var isActive = isParentActive && (this.m_features.UNIFORMUSAGE_EVERY_OTHER ? basicUniformsDst.length % 2 == 0 : true);
+ /** @type {gluShaderUtil.DataType} */ var type = varType.getBasicType();
+ value = this.m_features.UNIFORMVALUE_ZERO ? es3fUniformApiTests.generateZeroVarValue(type) :
+ gluShaderUtil.isDataTypeSampler(type) ? es3fUniformApiTests.generateRandomVarValue(type, rnd, samplerUnitCounter++) :
+ es3fUniformApiTests.generateRandomVarValue(varType.getBasicType(), rnd);
+
+ basicUniformsDst.push(new es3fUniformApiTests.BasicUniform(varName, varType.getBasicType(), isActive, value));
+ basicUniformReportsDst.push(new es3fUniformApiTests.BasicUniformReportRef(varName, varType.getBasicType(), isActive));
+ } else if (varType.isArrayType()) {
+ /** @type {number} */ var size = varType.getArraySize();
+ /** @type {string} */ var arrayRootName = '' + varName + '[0]';
+ /** @type {Array<boolean>} */ var isElemActive = [];
+
+ for (var elemNdx = 0; elemNdx < varType.getArraySize(); elemNdx++) {
+ /** @type {string} */ var indexedName = '' + varName + '[' + elemNdx + ']';
+ /** @type {boolean} */ var isCurElemActive = isParentActive &&
+ (this.m_features.UNIFORMUSAGE_EVERY_OTHER ? basicUniformsDst.length % 2 == 0 : true) &&
+ (this.m_features.ARRAYUSAGE_ONLY_MIDDLE_INDEX ? elemNdx == Math.floor(size / 2) : true);
+
+ isElemActive.push(isCurElemActive);
+
+ if (varType.getElementType().isBasicType()) {
+ // \note We don't want separate entries in basicUniformReportsDst for elements of basic-type arrays.
+ /** @type {gluShaderUtil.DataType} */ var elemBasicType = varType.getElementType().getBasicType();
+ value = this.m_features.UNIFORMVALUE_ZERO ? es3fUniformApiTests.generateZeroVarValue(elemBasicType) :
+ gluShaderUtil.isDataTypeSampler(elemBasicType) ? es3fUniformApiTests.generateRandomVarValue(elemBasicType, rnd, samplerUnitCounter++) :
+ es3fUniformApiTests.generateRandomVarValue(elemBasicType, rnd);
+
+ basicUniformsDst.push(new es3fUniformApiTests.BasicUniform(indexedName, elemBasicType, isCurElemActive, value, arrayRootName, elemNdx, size));
+ } else
+ samplerUnitCounter = this.generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, varType.getElementType(), indexedName, isCurElemActive, samplerUnitCounter, rnd);
+ }
+
+ if (varType.getElementType().isBasicType()) {
+ /** @type {number} */ var minSize;
+ for (minSize = varType.getArraySize(); minSize > 0 && !isElemActive[minSize - 1]; minSize--) {}
+
+ basicUniformReportsDst.push(new es3fUniformApiTests.BasicUniformReportRef(arrayRootName, varType.getElementType().getBasicType(), isParentActive && minSize > 0).constructor_A(minSize, size));
+ }
+ } else {
+ assertMsgOptions(
+ varType.isStructType(),
+ 'es3fUniformApiTests.UniformCase.prototype.generateBasicUniforms - not a struct type',
+ false,
+ true
+ );
+
+ /** @type {gluVarType.StructType} */ var structType = varType.getStruct();
+
+ for (var i = 0; i < structType.getSize(); i++) {
+ /** @type {gluVarType.StructMember} */ var member = structType.getMember(i);
+ /** @type {string} */ var memberFullName = '' + varName + '.' + member.getName();
+
+ samplerUnitCounter = this.generateBasicUniforms(basicUniformsDst, basicUniformReportsDst, member.getType(), memberFullName, isParentActive, samplerUnitCounter, rnd);
+ }
+ }
+
+ return samplerUnitCounter;
+ };
+
+ /**
+ * @param {string} dst
+ * @return {string}
+ */
+ es3fUniformApiTests.UniformCase.prototype.writeUniformDefinitions = function(dst) {
+ for (var i = 0; i < this.m_uniformCollection.getNumStructTypes(); i++)
+ dst += gluVarType.declareStructType(this.m_uniformCollection.getStructType(i), 0) + ';\n';
+
+ for (var i = 0; i < this.m_uniformCollection.getNumUniforms(); i++)
+ dst += 'uniform ' + gluVarType.declareVariable(this.m_uniformCollection.getUniform(i).type, this.m_uniformCollection.getUniform(i).name, 0) + ';\n';
+
+ dst += '\n';
+
+ var compareFuncs = [{
+ requiringTypes: [gluShaderUtil.isDataTypeFloatOrVec, gluShaderUtil.isDataTypeMatrix],
+ definition: 'mediump float compare_float (mediump float a, mediump float b) { return abs(a - b) < 0.05 ? 1.0 : 0.0; }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_VEC2, t);},
+ function(t) {return es3fUniformApiTests.dataTypeIsMatrixWithNRows(2, t);}
+ ],
+ definition: 'mediump float compare_vec2 (mediump vec2 a, mediump vec2 b) { return compare_float(a.x, b.x)*compare_float(a.y, b.y); }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_VEC3, t);},
+ function(t) {return es3fUniformApiTests.dataTypeIsMatrixWithNRows(3, t);}
+ ],
+ definition: 'mediump float compare_vec3 (mediump vec3 a, mediump vec3 b) { return compare_float(a.x, b.x)*compare_float(a.y, b.y)*compare_float(a.z, b.z); }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_VEC4, t);},
+ function(t) {return es3fUniformApiTests.dataTypeIsMatrixWithNRows(4, t);}],
+ definition: 'mediump float compare_vec4 (mediump vec4 a, mediump vec4 b) { return compare_float(a.x, b.x)*compare_float(a.y, b.y)*compare_float(a.z, b.z)*compare_float(a.w, b.w); }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT2, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_mat2 (mediump mat2 a, mediump mat2 b) { return compare_vec2(a[0], b[0])*compare_vec2(a[1], b[1]); }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT2X3, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_mat2x3 (mediump mat2x3 a, mediump mat2x3 b) { return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1]); }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT2X4, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_mat2x4 (mediump mat2x4 a, mediump mat2x4 b) { return compare_vec4(a[0], b[0])*compare_vec4(a[1], b[1]); }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT3X2, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_mat3x2 (mediump mat3x2 a, mediump mat3x2 b) { return compare_vec2(a[0], b[0])*compare_vec2(a[1], b[1])*compare_vec2(a[2], b[2]); }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT3, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_mat3 (mediump mat3 a, mediump mat3 b) { return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1])*compare_vec3(a[2], b[2]); }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT3X4, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_mat3x4 (mediump mat3x4 a, mediump mat3x4 b) { return compare_vec4(a[0], b[0])*compare_vec4(a[1], b[1])*compare_vec4(a[2], b[2]); }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT4X2, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_mat4x2 (mediump mat4x2 a, mediump mat4x2 b) { return compare_vec2(a[0], b[0])*compare_vec2(a[1], b[1])*compare_vec2(a[2], b[2])*compare_vec2(a[3], b[3]); }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT4X3, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_mat4x3 (mediump mat4x3 a, mediump mat4x3 b) { return compare_vec3(a[0], b[0])*compare_vec3(a[1], b[1])*compare_vec3(a[2], b[2])*compare_vec3(a[3], b[3]); }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.FLOAT_MAT4, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_mat4 (mediump mat4 a, mediump mat4 b) { return compare_vec4(a[0], b[0])*compare_vec4(a[1], b[1])*compare_vec4(a[2], b[2])*compare_vec4(a[3], b[3]); }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INT, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_int (mediump int a, mediump int b) { return a == b ? 1.0 : 0.0; }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INT_VEC2, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_ivec2 (mediump ivec2 a, mediump ivec2 b) { return a == b ? 1.0 : 0.0; }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INT_VEC3, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_ivec3 (mediump ivec3 a, mediump ivec3 b) { return a == b ? 1.0 : 0.0; }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INT_VEC4, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_ivec4 (mediump ivec4 a, mediump ivec4 b) { return a == b ? 1.0 : 0.0; }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.UINT, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_uint (mediump uint a, mediump uint b) { return a == b ? 1.0 : 0.0; }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.UINT_VEC2, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_uvec2 (mediump uvec2 a, mediump uvec2 b) { return a == b ? 1.0 : 0.0; }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.UINT_VEC3, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_uvec3 (mediump uvec3 a, mediump uvec3 b) { return a == b ? 1.0 : 0.0; }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.UINT_VEC4, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_uvec4 (mediump uvec4 a, mediump uvec4 b) { return a == b ? 1.0 : 0.0; }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.BOOL, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_bool (bool a, bool b) { return a == b ? 1.0 : 0.0; }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.BOOL_VEC2, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_bvec2 (bvec2 a, bvec2 b) { return a == b ? 1.0 : 0.0; }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.BOOL_VEC3, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_bvec3 (bvec3 a, bvec3 b) { return a == b ? 1.0 : 0.0; }'
+ },{
+ requiringTypes: [
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.BOOL_VEC4, t);},
+ function(t) {return es3fUniformApiTests.dataTypeEquals(gluShaderUtil.DataType.INVALID, t);}
+ ],
+ definition: 'mediump float compare_bvec4 (bvec4 a, bvec4 b) { return a == b ? 1.0 : 0.0; }'
+ }
+ ];
+
+ /** @type {Array<gluShaderUtil.DataType>} */ var samplerTypes = this.m_uniformCollection.getSamplerTypes();
+
+ for (var compFuncNdx = 0; compFuncNdx < compareFuncs.length; compFuncNdx++) {
+ /** @type {Array<es3fUniformApiTests.dataTypePredicate>} */ var typeReq = compareFuncs[compFuncNdx].requiringTypes;
+ /** @type {boolean} */ var containsTypeSampler = false;
+
+ for (var i = 0; i < samplerTypes.length; i++) {
+ if (gluShaderUtil.isDataTypeSampler(samplerTypes[i])) {
+ /** @type {gluShaderUtil.DataType} */ var retType = es3fUniformApiTests.getSamplerLookupReturnType(samplerTypes[i]);
+ if (typeReq[0](retType) || typeReq[1](retType)) {
+ containsTypeSampler = true;
+ break;
+ }
+ }
+ }
+
+ if (containsTypeSampler || this.m_uniformCollection.containsMatchingBasicType(typeReq[0]) || this.m_uniformCollection.containsMatchingBasicType(typeReq[1]))
+ dst += compareFuncs[compFuncNdx].definition + '\n';
+ }
+
+ return dst;
+ };
+
+ /**
+ * @param {string} dst
+ * @param {es3fUniformApiTests.BasicUniform} uniform
+ * @return {string} Used to write the string in the output parameter
+ */
+ es3fUniformApiTests.UniformCase.prototype.writeUniformCompareExpr = function(dst, uniform) {
+ if (gluShaderUtil.isDataTypeSampler(uniform.type))
+ dst += 'compare_' + gluShaderUtil.getDataTypeName(es3fUniformApiTests.getSamplerLookupReturnType(uniform.type)) + '(texture(' + uniform.name + ', vec' + es3fUniformApiTests.getSamplerNumLookupDimensions(uniform.type) + '(0.0))'; //WebGL2.0
+ else
+ dst += 'compare_' + gluShaderUtil.getDataTypeName(uniform.type) + '(' + uniform.name;
+
+ dst += ', ' + es3fUniformApiTests.shaderVarValueStr(uniform.finalValue) + ')';
+
+ return dst;
+ };
+
+ /**
+ * @param {string} dst
+ * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
+ * @param {string} variableName
+ * @return {string} Used to write the string in the output parameter
+ */
+ es3fUniformApiTests.UniformCase.prototype.writeUniformComparisons = function(dst, basicUniforms, variableName) {
+ for (var i = 0; i < basicUniforms.length; i++) {
+ /** @type {es3fUniformApiTests.BasicUniform} */ var unif = basicUniforms[i];
+
+ if (unif.isUsedInShader) {
+ dst += '\t' + variableName + ' *= ';
+ dst = this.writeUniformCompareExpr(dst, basicUniforms[i]);
+ dst += ';\n';
+ } else
+ dst += '\t// UNUSED: ' + basicUniforms[i].name + '\n';
+ }
+
+ return dst;
+ };
+
+ /**
+ * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
+ * @return {string}
+ */
+ es3fUniformApiTests.UniformCase.prototype.generateVertexSource = function(basicUniforms) {
+ /** @type {boolean} */ var isVertexCase = this.m_caseShaderType == es3fUniformApiTests.CaseShaderType.VERTEX || this.m_caseShaderType == es3fUniformApiTests.CaseShaderType.BOTH;
+ /** @type {string} */ var result = '';
+
+ result += '#version 300 es\n' +
+ 'in highp vec4 a_position;\n' +
+ 'out mediump float v_vtxOut;\n' +
+ '\n';
+
+ if (isVertexCase)
+ result = this.writeUniformDefinitions(result);
+
+ result += '\n' +
+ 'void main (void)\n' +
+ ' {\n' +
+ ' gl_Position = a_position;\n' +
+ ' v_vtxOut = 1.0;\n';
+
+ if (isVertexCase)
+ result = this.writeUniformComparisons(result, basicUniforms, 'v_vtxOut');
+
+ result += '}\n';
+
+ return result;
+ };
+
+ /**
+ * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
+ * @return {string}
+ */
+ es3fUniformApiTests.UniformCase.prototype.generateFragmentSource = function(basicUniforms) {
+ /**@type {boolean} */ var isFragmentCase = this.m_caseShaderType == es3fUniformApiTests.CaseShaderType.FRAGMENT || this.m_caseShaderType == es3fUniformApiTests.CaseShaderType.BOTH;
+ /**@type {string} */ var result = '';
+
+ result += '#version 300 es\n' +
+ 'in mediump float v_vtxOut;\n' +
+ '\n';
+
+ if (isFragmentCase)
+ result = this.writeUniformDefinitions(result);
+
+ result += '\n' +
+ 'layout(location = 0) out mediump vec4 dEQP_FragColor;\n' +
+ '\n' +
+ 'void main (void)\n' +
+ ' {\n' +
+ ' mediump float result = v_vtxOut;\n';
+
+ if (isFragmentCase)
+ result = this.writeUniformComparisons(result, basicUniforms, 'result');
+
+ result += ' dEQP_FragColor = vec4(result, result, result, 1.0);\n' +
+ '}\n';
+
+ return result;
+ };
+
+ /**
+ * @param {es3fUniformApiTests.VarValue} value
+ */
+ es3fUniformApiTests.UniformCase.prototype.setupTexture = function(value) {
+ // \note No handling for samplers other than 2D or cube.
+
+ assertMsgOptions(
+ es3fUniformApiTests.getSamplerLookupReturnType(value.type) == gluShaderUtil.DataType.FLOAT_VEC4,
+ 'es3fUniformApiTests.UniformCase.prototype.setupTexture - sampler return type should be vec4f', false, true
+ );
+
+ /** @type {number} */ var width = 32;
+ /** @type {number} */ var height = 32;
+ /** @type {Array<number>} */ var color = value.val.samplerV.fillColor;
+ /** @type {tcuTexture.TextureCube} */ var refTexture;
+ /** @type {gluTexture.TextureCube} */ var texture;
+
+ if (value.type == gluShaderUtil.DataType.SAMPLER_2D) {
+ texture = gluTexture.texture2DFromFormat(gl, gl.RGBA, gl.UNSIGNED_BYTE, width, height);
+ refTexture = texture.getRefTexture();
+ this.m_textures2d.push(texture);
+
+ refTexture.allocLevel(0);
+ es3fUniformApiTests.fillWithColor(refTexture.getLevel(0), color);
+
+ gl.activeTexture(gl.TEXTURE0 + value.val.samplerV.unit);
+ this.m_filledTextureUnits.push(value.val.samplerV.unit);
+ texture.upload();
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ } else if (value.type == gluShaderUtil.DataType.SAMPLER_CUBE) {
+ assertMsgOptions(width == height, 'es3fUniformApiTests.UniformCase.prototype.setupTexture - non square texture', false, true);
+
+ texture = gluTexture.cubeFromFormat(gl, gl.RGBA, gl.UNSIGNED_BYTE, width);
+ refTexture = texture.getRefTexture();
+ this.m_texturesCube.push(texture);
+
+ for (var face in tcuTexture.CubeFace) {
+ refTexture.allocLevel(tcuTexture.CubeFace[face], 0);
+ es3fUniformApiTests.fillWithColor(refTexture.getLevelFace(0, tcuTexture.CubeFace[face]), color);
+ }
+
+ gl.activeTexture(gl.TEXTURE0 + value.val.samplerV.unit);
+ this.m_filledTextureUnits.push(value.val.samplerV.unit);
+ texture.upload();
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ } else
+ throw new Error('es3fUniformApiTests.UniformCase.prototype.setupTexture - Invalid sampler type');
+ };
+
+ /**
+ * @param {Array<es3fUniformApiTests.BasicUniformReportGL>} basicUniformReportsDst
+ * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsRef
+ * @param {WebGLProgram} programGL
+ * @return {boolean}
+ */
+ es3fUniformApiTests.UniformCase.prototype.getActiveUniformsOneByOne = function(basicUniformReportsDst, basicUniformReportsRef, programGL) {
+ /** @type {WebGLProgram} */ var numActiveUniforms;
+ /** @type {boolean} */ var success = true;
+
+ numActiveUniforms = /** @type {WebGLProgram} */ (gl.getProgramParameter(programGL, gl.ACTIVE_UNIFORMS));
+ bufferedLogToConsole('// Number of active uniforms reported: ' + numActiveUniforms);
+
+ for (var unifNdx = 0; unifNdx < numActiveUniforms; unifNdx++) {
+ /** @type {number} (GLint)*/ var reportedSize = -1;
+ /** @type {number} (GLenum)*/ var reportedTypeGL = gl.NONE;
+ /** @type {gluShaderUtil.DataType} */ var reportedType;
+ /** @type {string} */ var reportedNameStr;
+ /** @type {WebGLActiveInfo} */ var activeInfo;
+
+ activeInfo = gl.getActiveUniform(programGL, unifNdx);
+
+ reportedNameStr = activeInfo.name;
+ reportedTypeGL = activeInfo.type;
+ reportedSize = activeInfo.size;
+
+ reportedType = gluShaderUtil.getDataTypeFromGLType(reportedTypeGL);
+
+ checkMessage(reportedType !== undefined, 'Invalid uniform type');
+
+ bufferedLogToConsole('// Got name = ' + reportedNameStr + ', size = ' + reportedSize + ', type = ' + gluShaderUtil.getDataTypeName(reportedType));
+
+ // Ignore built-in uniforms.
+ if (reportedNameStr.indexOf('gl_') == -1) {
+ /** @type {number} */ var referenceNdx;
+ for (referenceNdx = 0; referenceNdx < basicUniformReportsRef.length; referenceNdx++) {
+ if (basicUniformReportsRef[referenceNdx].name == reportedNameStr)
+ break;
+ }
+
+ if (referenceNdx >= basicUniformReportsRef.length) {
+ bufferedLogToConsole('// FAILURE: invalid non-built-in uniform name reported');
+ success = false;
+ } else {
+ /** @type {es3fUniformApiTests.BasicUniformReportRef} */ var reference = basicUniformReportsRef[referenceNdx];
+
+ assertMsgOptions(
+ reference.type !== undefined,
+ 'es3fUniformApiTests.UniformCase.prototype.getActiveUniformsOneByOne - type is undefined',
+ false,
+ true
+ );
+ assertMsgOptions(
+ reference.minSize >= 1 || (reference.minSize == 0 && !reference.isUsedInShader),
+ 'es3fUniformApiTests.UniformCase.prototype.getActiveUniformsOneByOne - uniform min size does not match usage in shader',
+ false,
+ true
+ );
+ assertMsgOptions(
+ reference.minSize <= reference.maxSize,
+ 'es3fUniformApiTests.UniformCase.prototype.getActiveUniformsOneByOne - uniform min size bigger than max size',
+ false,
+ true
+ );
+
+ if (es3fUniformApiTests.BasicUniformReportGL.findWithName(basicUniformReportsDst, reportedNameStr) !== null) {
+ bufferedLogToConsole('// FAILURE: same uniform name reported twice');
+ success = false;
+ }
+
+ basicUniformReportsDst.push(new es3fUniformApiTests.BasicUniformReportGL(reportedNameStr, reportedNameStr.length, reportedSize, reportedType, unifNdx));
+
+ if (reportedType != reference.type) {
+ bufferedLogToConsole('// FAILURE: wrong type reported, should be ' + gluShaderUtil.getDataTypeName(reference.type));
+ success = false;
+ }
+ if (reportedSize < reference.minSize || reportedSize > reference.maxSize) {
+ bufferedLogToConsole('// FAILURE: wrong size reported, should be ' +
+ (reference.minSize == reference.maxSize ? reference.minSize : 'in the range [' + reference.minSize + ', ' + reference.maxSize + ']'));
+
+ success = false;
+ }
+ }
+ }
+ }
+
+ for (var i = 0; i < basicUniformReportsRef.length; i++) {
+ /** @type {es3fUniformApiTests.BasicUniformReportRef} */ var expected = basicUniformReportsRef[i];
+ if (expected.isUsedInShader && es3fUniformApiTests.BasicUniformReportGL.findWithName(basicUniformReportsDst, expected.name) === null) {
+ bufferedLogToConsole('// FAILURE: uniform with name ' + expected.name + ' was not reported by GL');
+ success = false;
+ }
+ }
+
+ return success;
+ };
+
+ /**
+ * @param {Array<es3fUniformApiTests.BasicUniformReportGL>} basicUniformReportsDst
+ * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsRef
+ * @param {WebGLProgram} programGL
+ * @return {boolean}
+ */
+ es3fUniformApiTests.UniformCase.prototype.getActiveUniforms = function(basicUniformReportsDst, basicUniformReportsRef, programGL) {
+ /** @type {Array<string>} */ var queryNames = new Array(basicUniformReportsRef.length);
+ /** @type {Array<string>} */ var queryNamesC = new Array(basicUniformReportsRef.length);
+ /** @type {Array<number>} (GLuint) */ var uniformIndices = new Array(basicUniformReportsRef.length);
+ /** @type {Array<number>} */ var validUniformIndices = []; // This shall have the same contents, and in same order, as uniformIndices, but with gl.INVALID_INDEX entries removed.
+ /** @type {boolean} */ var success = true;
+
+ for (var i = 0; i < basicUniformReportsRef.length; i++) {
+ /** @type {string} */ var name = basicUniformReportsRef[i].name;
+ queryNames[i] = this.m_features.ARRAY_FIRST_ELEM_NAME_NO_INDEX && name[name.length - 1] == ']' ? es3fUniformApiTests.beforeLast(name, '[') : name;
+ queryNamesC[i] = queryNames[i];
+ }
+
+ uniformIndices = gl.getUniformIndices(programGL, queryNamesC);
+
+ for (var i = 0; i < uniformIndices.length; i++) {
+ if (uniformIndices[i] != gl.INVALID_INDEX)
+ validUniformIndices.push(uniformIndices[i]);
+ else {
+ if (basicUniformReportsRef[i].isUsedInShader) {
+ bufferedLogToConsole('// FAILURE: uniform with name ' + basicUniformReportsRef[i].name + ' received gl.INVALID_INDEX');
+ success = false;
+ }
+ }
+ }
+
+ if (validUniformIndices.length > 0) {
+ /** @type {Array<string>} */ var uniformNameBuf = new Array(validUniformIndices.length);
+ /** @type {Array<number>} (GLint) */ var uniformSizeBuf = new Array(validUniformIndices.length);
+ /** @type {Array<number>} (GLint) */ var uniformTypeBuf = new Array(validUniformIndices.length);
+
+ uniformSizeBuf = gl.getActiveUniforms(programGL, validUniformIndices, gl.UNIFORM_SIZE);
+ uniformTypeBuf = gl.getActiveUniforms(programGL, validUniformIndices, gl.UNIFORM_TYPE);
+
+ /** @type {number} */ var validNdx = -1; // Keeps the corresponding index to validUniformIndices while unifNdx is the index to uniformIndices.
+ for (var unifNdx = 0; unifNdx < uniformIndices.length; unifNdx++) {
+ if (uniformIndices[unifNdx] == gl.INVALID_INDEX)
+ continue;
+
+ validNdx++;
+
+ /** @type {es3fUniformApiTests.BasicUniformReportRef} */ var reference = basicUniformReportsRef[unifNdx];
+ /** @type {number} */ var reportedIndex = validUniformIndices[validNdx];
+ /** @type {number} */ var reportedNameLength = reference.name.length;
+ /** @type {number} */ var reportedSize = uniformSizeBuf[validNdx];
+ /** @type {gluShaderUtil.DataType} */ var reportedType = gluShaderUtil.getDataTypeFromGLType(uniformTypeBuf[validNdx]);
+ /** @type {string} */ var reportedNameStr = reference.name;
+
+ bufferedLogToConsole('// Got name size = ' + reportedSize +
+ ', type = ' + gluShaderUtil.getDataTypeName(reportedType) +
+ ' for the uniform at index ' + reportedIndex + ' (' + reference.name + ')');
+
+ assertMsgOptions(
+ reference.type !== undefined,
+ 'es3fUniformApiTests.UniformCase.prototype.getActiveUniforms - type is undefined',
+ false,
+ true
+ );
+ assertMsgOptions(
+ reference.minSize >= 1 || (reference.minSize == 0 && !reference.isUsedInShader),
+ 'es3fUniformApiTests.UniformCase.prototype.getActiveUniforms - uniform min size does not match usage in shader',
+ false,
+ true
+ );
+ assertMsgOptions(
+ reference.minSize <= reference.maxSize,
+ 'es3fUniformApiTests.UniformCase.prototype.getActiveUniforms - uniform min size bigger than max size',
+ false,
+ true
+ );
+
+ if (es3fUniformApiTests.BasicUniformReportGL.findWithName(basicUniformReportsDst, reportedNameStr) !== null) {
+ bufferedLogToConsole('// FAILURE: same uniform name reported twice');
+ success = false;
+ }
+ basicUniformReportsDst.push(new es3fUniformApiTests.BasicUniformReportGL(reference.name, reportedNameLength, reportedSize, reportedType, reportedIndex));
+
+ if (reportedType != reference.type) {
+ bufferedLogToConsole('// FAILURE: wrong type reported, should be ' + gluShaderUtil.getDataTypeName(reference.type));
+ success = false;
+ }
+
+ if (reportedSize < reference.minSize || reportedSize > reference.maxSize) {
+ bufferedLogToConsole('// FAILURE: wrong size reported, should be ' +
+ (reference.minSize == reference.maxSize ? reference.minSize : 'in the range [' + reference.minSize + ', ' + reference.maxSize + ']'));
+
+ success = false;
+ }
+ }
+ }
+
+ return success;
+ };
+
+ /**
+ * @param {Array<es3fUniformApiTests.BasicUniformReportGL>} uniformResults
+ * @param {Array<es3fUniformApiTests.BasicUniformReportGL>} uniformsResults
+ * @return {boolean}
+ */
+ es3fUniformApiTests.UniformCase.prototype.uniformVsUniformsComparison = function(uniformResults, uniformsResults) {
+ /** @type {boolean} */ var success = true;
+ /** @type {es3fUniformApiTests.BasicUniformReportGL} */ var uniformsResult;
+
+ for (var uniformResultNdx = 0; uniformResultNdx < uniformResults.length; uniformResultNdx++) {
+ /** @type {es3fUniformApiTests.BasicUniformReportGL} */ var uniformResult = uniformResults[uniformResultNdx];
+ /** @type {string} */ var uniformName = uniformResult.name;
+ uniformsResult = es3fUniformApiTests.BasicUniformReportGL.findWithName(uniformsResults, uniformName);
+
+ if (uniformsResult !== null) {
+ bufferedLogToConsole('// Checking uniform ' + uniformName);
+
+ if (uniformResult.index != uniformsResult.index) {
+ bufferedLogToConsole('// FAILURE: glGetActiveUniform() and glGetUniformIndices() gave different indices for uniform ' + uniformName);
+ success = false;
+ }
+ if (uniformResult.nameLength != uniformsResult.nameLength) {
+ bufferedLogToConsole('// FAILURE: glGetActiveUniform() and glGetActiveUniforms() gave incompatible name lengths for uniform ' + uniformName);
+ success = false;
+ }
+ if (uniformResult.size != uniformsResult.size) {
+ bufferedLogToConsole('// FAILURE: glGetActiveUniform() and glGetActiveUniforms() gave different sizes for uniform ' + uniformName);
+ success = false;
+ }
+ if (uniformResult.type != uniformsResult.type) {
+ bufferedLogToConsole('// FAILURE: glGetActiveUniform() and glGetActiveUniforms() gave different types for uniform ' + uniformName);
+ success = false;
+ }
+ } else {
+ bufferedLogToConsole('// FAILURE: uniform ' + uniformName + ' was reported active by glGetActiveUniform() but not by glGetUniformIndices()');
+ success = false;
+ }
+ }
+
+ for (var uniformsResultNdx = 0; uniformsResultNdx < uniformsResults.length; uniformsResultNdx++) {
+ uniformsResult = uniformsResults[uniformsResultNdx];
+ /** @type {string} */ var uniformsName = uniformsResult.name;
+ /** @type {es3fUniformApiTests.BasicUniformReportGL} */ var uniformsResultIt = es3fUniformApiTests.BasicUniformReportGL.findWithName(uniformsResults, uniformsName);
+
+ if (uniformsResultIt === null) {
+ bufferedLogToConsole('// FAILURE: uniform ' + uniformsName + ' was reported active by glGetUniformIndices() but not by glGetActiveUniform()');
+ success = false;
+ }
+ }
+
+ return success;
+ };
+
+ /**
+ * @param {Array<es3fUniformApiTests.VarValue>} valuesDst
+ * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
+ * @param {WebGLProgram} programGL
+ * @return {boolean}
+ */
+ es3fUniformApiTests.UniformCase.prototype.getUniforms = function(valuesDst, basicUniforms, programGL) {
+ /** @type {boolean} */ var success = true;
+
+ for (var unifNdx = 0; unifNdx < basicUniforms.length; unifNdx++) {
+ /** @type {es3fUniformApiTests.BasicUniform} */ var uniform = basicUniforms[unifNdx];
+ /** @type {string} */ var queryName = this.m_features.ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? es3fUniformApiTests.beforeLast(uniform.name, '[') : uniform.name;
+ /** @type {WebGLUniformLocation} */ var location = gl.getUniformLocation(programGL, queryName);
+ /** @type {number} */ var size = gluShaderUtil.getDataTypeScalarSize(uniform.type);
+ /** @type {es3fUniformApiTests.VarValue} */ var value = new es3fUniformApiTests.VarValue();
+
+ if (!location) {
+ value.type = gluShaderUtil.DataType.INVALID;
+ valuesDst.push(value);
+ if (uniform.isUsedInShader) {
+ bufferedLogToConsole('// FAILURE: ' + uniform.name + ' was used in shader, but has location -1');
+ success = false;
+ }
+ continue;
+ }
+
+ value.type = uniform.type;
+
+ var result = /** @type {number} */ (gl.getUniform(programGL, location));
+
+ if (gluShaderUtil.isDataTypeSampler(uniform.type)) {
+ value.val = new es3fUniformApiTests.SamplerV();
+ value.val.samplerV.unit = result;
+ } else
+ value.val = /** @type {Array<number>} */ (result.length === undefined ? [result] : result);
+
+ valuesDst.push(value);
+
+ bufferedLogToConsole('// Got ' + uniform.name + ' value ' + es3fUniformApiTests.apiVarValueStr(value));
+ }
+
+ return success;
+ };
+
+ /**
+ * @param {Array<es3fUniformApiTests.VarValue>} values
+ * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
+ * @return {boolean}
+ */
+ es3fUniformApiTests.UniformCase.prototype.checkUniformDefaultValues = function(values, basicUniforms) {
+ /** @type {boolean} */ var success = true;
+
+ assertMsgOptions(
+ values.length == basicUniforms.length,
+ 'es3fUniformApiTests.UniformCase.prototype.checkUniformDefaultValues - lengths do not match',
+ false,
+ true
+ );
+
+ for (var unifNdx = 0; unifNdx < basicUniforms.length; unifNdx++) {
+ /** @type {es3fUniformApiTests.BasicUniform} */ var uniform = basicUniforms[unifNdx];
+ /** @type {es3fUniformApiTests.VarValue} */ var unifValue = values[unifNdx];
+ /** @type {number} */ var valSize = gluShaderUtil.getDataTypeScalarSize(uniform.type);
+
+ bufferedLogToConsole('// Checking uniform ' + uniform.name);
+
+ if (unifValue.type == gluShaderUtil.DataType.INVALID) // This happens when glGetUniformLocation() returned -1.
+ continue;
+
+ var CHECK_UNIFORM = function(ZERO) {
+ do {
+ for (var i = 0; i < valSize; i++) {
+ if (unifValue.val[i] != ZERO) {
+ bufferedLogToConsole('// FAILURE: uniform ' + uniform.name + ' has non-zero initial value');
+ success = false;
+ }
+ }
+ } while (false);
+ };
+
+ if (gluShaderUtil.isDataTypeFloatOrVec(uniform.type) || gluShaderUtil.isDataTypeMatrix(uniform.type))
+ CHECK_UNIFORM(0.0);
+ else if (gluShaderUtil.isDataTypeIntOrIVec(uniform.type))
+ CHECK_UNIFORM(0);
+ else if (gluShaderUtil.isDataTypeUintOrUVec(uniform.type))
+ CHECK_UNIFORM(0);
+ else if (gluShaderUtil.isDataTypeBoolOrBVec(uniform.type))
+ CHECK_UNIFORM(false);
+ else if (gluShaderUtil.isDataTypeSampler(uniform.type)) {
+ if (unifValue.val.samplerV.unit != 0) {
+ bufferedLogToConsole('// FAILURE: uniform ' + uniform.name + ' has non-zero initial value');
+ success = false;
+ }
+ } else
+ throw new Error('es3fUniformApiTests.UniformCase.prototype.checkUniformDefaultValues - invalid uniform type');
+ }
+
+ return success;
+ };
+
+ /**
+ * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
+ * @param {WebGLProgram} programGL
+ * @param {deRandom.Random} rnd
+ */
+ es3fUniformApiTests.UniformCase.prototype.assignUniforms = function(basicUniforms, programGL, rnd) {
+ /** @type {boolean} */ var transpose = false; //No support to transpose uniform matrices in WebGL, must always be false. (this.m_features.MATRIXMODE_ROWMAJOR) != 0;
+ /** @type {boolean} (GLboolean) */ var transposeGL = transpose;
+ /** @type {gluShaderUtil.DataType} */ var boolApiType = this.m_features.BOOLEANAPITYPE_INT ? gluShaderUtil.DataType.INT :
+ this.m_features.BOOLEANAPITYPE_UINT ? gluShaderUtil.DataType.UINT :
+ gluShaderUtil.DataType.FLOAT;
+
+ for (var unifNdx = 0; unifNdx < basicUniforms.length; unifNdx++) {
+ /** @type {es3fUniformApiTests.BasicUniform} */ var uniform = basicUniforms[unifNdx];
+ /** @type {boolean} */ var isArrayMember = uniform.elemNdx >= 0;
+ /** @type {string} */ var queryName = this.m_features.ARRAY_FIRST_ELEM_NAME_NO_INDEX && uniform.elemNdx == 0 ? es3fUniformApiTests.beforeLast(uniform.name, '[') : uniform.name;
+ /** @type {number} */ var numValuesToAssign = !isArrayMember ? 1 :
+ this.m_features.ARRAYASSIGN_FULL ? (uniform.elemNdx == 0 ? uniform.rootSize : 0) :
+ this.m_features.ARRAYASSIGN_BLOCKS_OF_TWO ? (uniform.elemNdx % 2 == 0 ? 2 : 0) :
+ /* Default: assign array elements separately */ 1;
+
+ assertMsgOptions(
+ numValuesToAssign >= 0,
+ 'es3fUniformApiTests.UniformCase.prototype.assignUniforms - number of values to assign not a positive integer',
+ false,
+ true
+ );
+ assertMsgOptions(
+ numValuesToAssign == 1 || isArrayMember,
+ 'es3fUniformApiTests.UniformCase.prototype.assignUniforms - not an array member and number of values to assign not 1',
+ false,
+ true
+ );
+
+ if (numValuesToAssign == 0) {
+ bufferedLogToConsole('// es3fUniformApiTests.Uniform ' + uniform.name + ' is covered by another glUniform*v() call to the same array');
+ continue;
+ }
+
+ /** @type {WebGLUniformLocation} */ var location = gl.getUniformLocation(programGL, queryName);
+ /** @type {number} */ var typeSize = gluShaderUtil.getDataTypeScalarSize(uniform.type);
+ /** @type {boolean} */ var assignByValue = this.m_features.UNIFORMFUNC_VALUE && !gluShaderUtil.isDataTypeMatrix(uniform.type) && numValuesToAssign == 1;
+ /** @type {Array<es3fUniformApiTests.VarValue>} */ var valuesToAssign = [];
+ /** @type {Array<number>} */ var buffer;
+
+ for (var i = 0; i < numValuesToAssign; i++) {
+ /** @type {string} */ var curName = isArrayMember ? es3fUniformApiTests.beforeLast(uniform.rootName, '[') + '[' + (uniform.elemNdx + i) + ']' : uniform.name;
+ /** @type {es3fUniformApiTests.VarValue} */ var unifValue = new es3fUniformApiTests.VarValue();
+
+ if (isArrayMember) {
+ /** @type {es3fUniformApiTests.BasicUniform} */ var elemUnif = es3fUniformApiTests.BasicUniform.findWithName(basicUniforms, curName);
+ if (elemUnif === null)
+ continue;
+ unifValue = elemUnif.finalValue;
+ } else
+ unifValue = uniform.finalValue;
+
+ /** @type {es3fUniformApiTests.VarValue} */ var apiValue = gluShaderUtil.isDataTypeBoolOrBVec(unifValue.type) ? es3fUniformApiTests.getRandomBoolRepresentation(unifValue, boolApiType, rnd) :
+ gluShaderUtil.isDataTypeSampler(unifValue.type) ? es3fUniformApiTests.getSamplerUnitValue(unifValue) :
+ unifValue;
+
+ valuesToAssign.push(gluShaderUtil.isDataTypeMatrix(apiValue.type) && transpose ? es3fUniformApiTests.getTransposeMatrix(apiValue) : apiValue);
+
+ if (gluShaderUtil.isDataTypeBoolOrBVec(uniform.type))
+ bufferedLogToConsole('// Using type ' + gluShaderUtil.getDataTypeName(boolApiType) + ' to set boolean value ' + es3fUniformApiTests.apiVarValueStr(unifValue) + ' for ' + curName);
+ else if (gluShaderUtil.isDataTypeSampler(uniform.type))
+ bufferedLogToConsole('// Texture for the sampler uniform ' + curName + ' will be filled with color ' + es3fUniformApiTests.apiVarValueStr(es3fUniformApiTests.getSamplerFillValue(uniform.finalValue)));
+ }
+
+ assertMsgOptions(
+ valuesToAssign.length > 0,
+ 'es3fUniformApiTests.UniformCase.prototype.assignUniforms - values quantity less than one',
+ false,
+ true
+ );
+
+ if (gluShaderUtil.isDataTypeFloatOrVec(valuesToAssign[0].type)) {
+ if (assignByValue) {
+ switch (typeSize) {
+ case 1: gl.uniform1f(location, valuesToAssign[0].val[0]); break;
+ case 2: gl.uniform2f(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1]); break;
+ case 3: gl.uniform3f(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1], valuesToAssign[0].val[2]); break;
+ case 4: gl.uniform4f(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1], valuesToAssign[0].val[2], valuesToAssign[0].val[3]); break;
+ default:
+ throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size');
+ }
+ } else {
+ buffer = new Array(valuesToAssign.length * typeSize);
+ for (var i = 0; i < buffer.length; i++)
+ buffer[i] = valuesToAssign[Math.floor(i / typeSize)].val[i % typeSize];
+
+ switch (typeSize) {
+ case 1: gl.uniform1fv(location, buffer); break;
+ case 2: gl.uniform2fv(location, buffer); break;
+ case 3: gl.uniform3fv(location, buffer); break;
+ case 4: gl.uniform4fv(location, buffer); break;
+ default:
+ throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size');
+ }
+ }
+ } else if (gluShaderUtil.isDataTypeMatrix(valuesToAssign[0].type)) {
+ assertMsgOptions(
+ !assignByValue,
+ 'es3fUniformApiTests.UniformCase.prototype.assignUniforms - assigning by value in matrix type',
+ false, true
+ );
+
+ buffer = new Array(valuesToAssign.length * typeSize);
+ for (var i = 0; i < buffer.length; i++)
+ buffer[i] = valuesToAssign[Math.floor(i / typeSize)].val[i % typeSize];
+
+ switch (uniform.type) {
+ case gluShaderUtil.DataType.FLOAT_MAT2: gl.uniformMatrix2fv(location, transposeGL, new Float32Array(buffer)); break;
+ case gluShaderUtil.DataType.FLOAT_MAT3: gl.uniformMatrix3fv(location, transposeGL, new Float32Array(buffer)); break;
+ case gluShaderUtil.DataType.FLOAT_MAT4: gl.uniformMatrix4fv(location, transposeGL, new Float32Array(buffer)); break;
+ case gluShaderUtil.DataType.FLOAT_MAT2X3: gl.uniformMatrix2x3fv(location, transposeGL, new Float32Array(buffer)); break;
+ case gluShaderUtil.DataType.FLOAT_MAT2X4: gl.uniformMatrix2x4fv(location, transposeGL, new Float32Array(buffer)); break;
+ case gluShaderUtil.DataType.FLOAT_MAT3X2: gl.uniformMatrix3x2fv(location, transposeGL, new Float32Array(buffer)); break;
+ case gluShaderUtil.DataType.FLOAT_MAT3X4: gl.uniformMatrix3x4fv(location, transposeGL, new Float32Array(buffer)); break;
+ case gluShaderUtil.DataType.FLOAT_MAT4X2: gl.uniformMatrix4x2fv(location, transposeGL, new Float32Array(buffer)); break;
+ case gluShaderUtil.DataType.FLOAT_MAT4X3: gl.uniformMatrix4x3fv(location, transposeGL, new Float32Array(buffer)); break;
+ default:
+ throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid uniform type');
+ }
+ } else if (gluShaderUtil.isDataTypeIntOrIVec(valuesToAssign[0].type)) {
+ if (assignByValue) {
+ switch (typeSize) {
+ case 1: gl.uniform1i(location, valuesToAssign[0].val[0]); break;
+ case 2: gl.uniform2i(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1]); break;
+ case 3: gl.uniform3i(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1], valuesToAssign[0].val[2]); break;
+ case 4: gl.uniform4i(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1], valuesToAssign[0].val[2], valuesToAssign[0].val[3]); break;
+ default:
+ throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size');
+ }
+ } else {
+ buffer = new Array(valuesToAssign.length * typeSize);
+ for (var i = 0; i < buffer.length; i++)
+ buffer[i] = valuesToAssign[Math.floor(i / typeSize)].val[i % typeSize];
+
+ switch (typeSize) {
+ case 1: gl.uniform1iv(location, buffer); break;
+ case 2: gl.uniform2iv(location, buffer); break;
+ case 3: gl.uniform3iv(location, buffer); break;
+ case 4: gl.uniform4iv(location, buffer); break;
+ default:
+ throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size');
+ }
+ }
+ } else if (gluShaderUtil.isDataTypeUintOrUVec(valuesToAssign[0].type)) {
+ if (assignByValue) {
+ switch (typeSize) {
+ case 1: gl.uniform1ui(location, valuesToAssign[0].val[0]); break;
+ case 2: gl.uniform2ui(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1]); break;
+ case 3: gl.uniform3ui(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1], valuesToAssign[0].val[2]); break;
+ case 4: gl.uniform4ui(location, valuesToAssign[0].val[0], valuesToAssign[0].val[1], valuesToAssign[0].val[2], valuesToAssign[0].val[3]); break;
+ default:
+ throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size');
+ }
+ } else {
+ buffer = new Array(valuesToAssign.length * typeSize);
+ for (var i = 0; i < buffer.length; i++)
+ buffer[i] = valuesToAssign[Math.floor(i / typeSize)].val[i % typeSize];
+
+ switch (typeSize) {
+ case 1: gl.uniform1uiv(location, buffer); break;
+ case 2: gl.uniform2uiv(location, buffer); break;
+ case 3: gl.uniform3uiv(location, buffer); break;
+ case 4: gl.uniform4uiv(location, buffer); break;
+ default:
+ throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid type size');
+ }
+ }
+ } else if (gluShaderUtil.isDataTypeSampler(valuesToAssign[0].type)) {
+ if (assignByValue)
+ gl.uniform1i(location, uniform.finalValue.val.samplerV.unit);
+ else {
+ var unit = /** @type {Array<number>} */ (uniform.finalValue.val);
+ gl.uniform1iv(location, unit);
+ }
+ } else
+ throw new Error('es3fUniformApiTests.UniformCase.prototype.assignUniforms - Invalid uniform type');
+ }
+ };
+
+ /**
+ * @param {Array<es3fUniformApiTests.VarValue>} values
+ * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
+ * @return {boolean}
+ */
+ es3fUniformApiTests.UniformCase.prototype.compareUniformValues = function(values, basicUniforms) {
+ /** @type {boolean} */ var success = true;
+
+ for (var unifNdx = 0; unifNdx < basicUniforms.length; unifNdx++) {
+ /** @type {es3fUniformApiTests.BasicUniform} */ var uniform = basicUniforms[unifNdx];
+ /** @type {es3fUniformApiTests.VarValue} */ var unifValue = values[unifNdx];
+
+ bufferedLogToConsole('// Checking uniform ' + uniform.name);
+
+ if (unifValue.type == gluShaderUtil.DataType.INVALID) // This happens when glGetUniformLocation() returned -1.
+ continue;
+
+ if (!es3fUniformApiTests.apiVarValueEquals(unifValue, uniform.finalValue)) {
+ bufferedLogToConsole('// FAILURE: value obtained with glGetUniform*() for uniform ' + uniform.name + ' differs from value set with glUniform*()');
+ success = false;
+ }
+ }
+
+ return success;
+ };
+
+ /** @const @type {number} */ es3fUniformApiTests.VIEWPORT_WIDTH = 128;
+ /** @const @type {number} */ es3fUniformApiTests.VIEWPORT_HEIGHT = 128;
+
+ /**
+ * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
+ * @param {gluShaderProgram.ShaderProgram} program
+ * @param {deRandom.Random} rnd
+ * @return {boolean}
+ */
+ es3fUniformApiTests.UniformCase.prototype.renderTest = function(basicUniforms, program, rnd) {
+ //const tcu::RenderTarget& renderTarget = m_context.getRenderTarget();
+ /** @const */ var viewportW = Math.min(gl.canvas.width, es3fUniformApiTests.VIEWPORT_WIDTH);
+ /** @const */ var viewportH = Math.min(gl.canvas.height, es3fUniformApiTests.VIEWPORT_HEIGHT);
+ /** @const */ var viewportX = rnd.getInt(0, gl.canvas.width - viewportW);
+ /** @const */ var viewportY = rnd.getInt(0, gl.canvas.height - viewportH);
+ /** @type {tcuSurface.Surface} */ var renderedImg = new tcuSurface.Surface(viewportW, viewportH);
+
+ // Assert that no two samplers of different types have the same texture unit - this is an error in GL.
+ for (var i = 0; i < basicUniforms.length; i++) {
+ if (gluShaderUtil.isDataTypeSampler(basicUniforms[i].type)) {
+ for (var j = 0; j < i; j++) {
+ if (gluShaderUtil.isDataTypeSampler(basicUniforms[j].type) && basicUniforms[i].type != basicUniforms[j].type)
+ assertMsgOptions(
+ basicUniforms[i].finalValue.val.samplerV.unit != basicUniforms[j].finalValue.val.samplerV.unit,
+ 'es3fUniformApiTests.UniformCase.prototype.renderTest - sampler units have the same texture unit',
+ false, true
+ );
+ }
+ }
+ }
+
+ for (var i = 0; i < basicUniforms.length; i++) {
+ if (gluShaderUtil.isDataTypeSampler(basicUniforms[i].type) && this.m_filledTextureUnits.indexOf(basicUniforms[i].finalValue.val) == -1) {
+ bufferedLogToConsole('// Filling texture at unit ' + es3fUniformApiTests.apiVarValueStr(basicUniforms[i].finalValue) + ' with color ' + es3fUniformApiTests.shaderVarValueStr(basicUniforms[i].finalValue));
+ this.setupTexture(basicUniforms[i].finalValue);
+ }
+ }
+
+ gl.viewport(viewportX, viewportY, viewportW, viewportH);
+
+ /** @type {Float32Array} */ var position = new Float32Array([
+ -1.0, -1.0, 0.0, 1.0,
+ -1.0, 1.0, 0.0, 1.0,
+ 1.0, -1.0, 0.0, 1.0,
+ 1.0, 1.0, 0.0, 1.0
+ ]);
+
+ /** @type {Uint16Array} */
+ var indices = new Uint16Array([0, 1, 2, 2, 1, 3]);
+
+ /** @type {number} */ var posLoc = gl.getAttribLocation(program.getProgram(), 'a_position');
+ gl.enableVertexAttribArray(posLoc);
+
+ var gl_position_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, gl_position_buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, position, gl.STATIC_DRAW);
+ gl.vertexAttribPointer(posLoc, 4, gl.FLOAT, false, 0, 0);
+
+ var gl_index_buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, gl_index_buffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
+
+ gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
+
+ renderedImg.readViewport(gl, [viewportX, viewportY, viewportW, viewportH]);
+
+ /** @type {number} */ var numFailedPixels = 0;
+ var whitePixel = new gluDrawUtil.Pixel([255.0, 255.0, 255.0, 255.0]);
+ for (var y = 0; y < renderedImg.getHeight(); y++) {
+ for (var x = 0; x < renderedImg.getWidth(); x++) {
+ var currentPixel = new gluDrawUtil.Pixel(renderedImg.getPixel(x, y));
+ if (!whitePixel.equals(currentPixel))
+ numFailedPixels += 1;
+ }
+ }
+
+ if (numFailedPixels > 0) {
+ //TODO: log << TestLog::Image("RenderedImage", "Rendered image", renderedImg);
+ bufferedLogToConsole('FAILURE: image comparison failed, got ' + numFailedPixels + ' non-white pixels');
+ return false;
+ } else {
+ bufferedLogToConsole('Success: got all-white pixels (all uniforms have correct values)');
+ return true;
+ }
+ };
+
+ /**
+ * @return {tcuTestCase.IterateResult}
+ */
+ es3fUniformApiTests.UniformCase.prototype.iterate = function() {
+ /** @type {deRandom.Random} */ var rnd = new deRandom.Random(deString.deStringHash(this.name) ^ deRandom.getBaseSeed());
+ /** @type {Array<es3fUniformApiTests.BasicUniform>} */ var basicUniforms = [];
+ /** @type {Array<es3fUniformApiTests.BasicUniformReportRef>} */ var basicUniformReportsRef = [];
+
+ /** @type {number} */ var samplerUnitCounter = 0;
+ for (var i = 0; i < this.m_uniformCollection.getNumUniforms(); i++)
+ samplerUnitCounter = this.generateBasicUniforms(basicUniforms, basicUniformReportsRef, this.m_uniformCollection.getUniform(i).type, this.m_uniformCollection.getUniform(i).name, true, samplerUnitCounter, rnd);
+
+ /** @type {string} */ var vertexSource = this.generateVertexSource(basicUniforms);
+ /** @type {string} */ var fragmentSource = this.generateFragmentSource(basicUniforms);
+ /** @type {gluShaderProgram.ShaderProgram} */ var program = new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vertexSource, fragmentSource));
+
+ bufferedLogToConsole(program.getProgramInfo().infoLog);
+
+ if (!program.isOk()) {
+ testFailedOptions('Compile failed', false);
+ return tcuTestCase.IterateResult.STOP;
+ }
+
+ gl.useProgram(program.getProgram());
+
+ /** @type {boolean} */ var success = this.test(basicUniforms, basicUniformReportsRef, program, rnd);
+ assertMsgOptions(success, '', true, false);
+
+ return tcuTestCase.IterateResult.STOP;
+ };
+
+ /**
+ * @enum {number}
+ */
+ es3fUniformApiTests.CaseType = {
+ UNIFORM: 0, //!< Check info returned by glGetActiveUniform().
+ INDICES_UNIFORMSIV: 1, //!< Check info returned by glGetUniformIndices() + glGetActiveUniforms(). TODO: Check 'IV' part
+ CONSISTENCY: 2 //!< Query info with both above methods, and check consistency.
+ };
+
+ /**
+ * es3fUniformApiTests.UniformInfoQueryCase class
+ * @constructor
+ * @param {string} name
+ * @param {string} description
+ * @param {es3fUniformApiTests.CaseShaderType} shaderType
+ * @param {es3fUniformApiTests.UniformCollection} uniformCollection
+ * @param {es3fUniformApiTests.CaseType} caseType
+ * @param {es3fUniformApiTests.Feature} additionalFeatures
+ * @extends {es3fUniformApiTests.UniformCase}
+ */
+ es3fUniformApiTests.UniformInfoQueryCase = function(name, description, shaderType, uniformCollection, caseType, additionalFeatures) {
+ es3fUniformApiTests.UniformCase.call(this, name, description);
+ this.newB(shaderType, uniformCollection, additionalFeatures);
+ /** @type {es3fUniformApiTests.CaseType} */ this.m_caseType = caseType;
+ };
+
+ es3fUniformApiTests.UniformInfoQueryCase.prototype = Object.create(es3fUniformApiTests.UniformCase.prototype);
+ /** Constructor restore */
+ es3fUniformApiTests.UniformInfoQueryCase.prototype.constructor = es3fUniformApiTests.UniformInfoQueryCase;
+
+ /**
+ * @param {es3fUniformApiTests.CaseType} caseType
+ * @return {?string}
+ */
+ es3fUniformApiTests.UniformInfoQueryCase.getCaseTypeName = function(caseType) {
+ switch (caseType) {
+ case es3fUniformApiTests.CaseType.UNIFORM: return 'active_uniform';
+ case es3fUniformApiTests.CaseType.INDICES_UNIFORMSIV: return 'indices_active_uniformsiv';
+ case es3fUniformApiTests.CaseType.CONSISTENCY: return 'consistency';
+ default:
+ throw new Error('Invalid type');
+ }
+ };
+
+ /**
+ * @param {es3fUniformApiTests.CaseType} caseType
+ * @return {?string}
+ */
+ es3fUniformApiTests.UniformInfoQueryCase.getCaseTypeDescription = function(caseType) {
+ switch (caseType) {
+ case es3fUniformApiTests.CaseType.UNIFORM: return 'Test glGetActiveUniform()';
+ case es3fUniformApiTests.CaseType.INDICES_UNIFORMSIV: return 'Test glGetUniformIndices() along with glGetActiveUniforms()';
+ case es3fUniformApiTests.CaseType.CONSISTENCY: return 'Check consistency between results from glGetActiveUniform() and glGetUniformIndices() + glGetActiveUniforms()';
+ default:
+ throw new Error('Invalid type');
+ }
+ };
+
+ // \note Although this is only used in UniformApiTest::es3fUniformApiTests.init, it needs to be defined here as it's used as a template argument.
+ /**
+ * @constructor
+ * @param {?string} name
+ * @param {es3fUniformApiTests.UniformCollection} uniformCollection_
+ */
+ es3fUniformApiTests.UniformCollectionCase = function(name, uniformCollection_) {
+ /** @type {string} */ this.namePrefix = name ? name + '_' : '';
+ /** @type {es3fUniformApiTests.UniformCollection} (SharedPtr) */ this.uniformCollection = uniformCollection_;
+ };
+
+ /**
+ * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
+ * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsRef
+ * @param {gluShaderProgram.ShaderProgram} program
+ * @param {deRandom.Random} rnd
+ * @return {boolean}
+ */
+ es3fUniformApiTests.UniformInfoQueryCase.prototype.test = function(basicUniforms, basicUniformReportsRef, program, rnd) {
+ /** @type {WebGLProgram} */ var programGL = program.getProgram();
+ /** @type {Array<es3fUniformApiTests.BasicUniformReportGL>} */ var basicUniformReportsUniform = [];
+ /** @type {Array<es3fUniformApiTests.BasicUniformReportGL>} */ var basicUniformReportsUniforms = [];
+ /** @type {boolean} */ var success;
+
+ if (this.m_caseType == es3fUniformApiTests.CaseType.UNIFORM || this.m_caseType == es3fUniformApiTests.CaseType.CONSISTENCY) {
+ success = false;
+
+ //TODO:: const ScopedLogSection section(log, "InfoGetActiveUniform", "es3fUniformApiTests.Uniform information queries with glGetActiveUniform()");
+ success = this.getActiveUniformsOneByOne(basicUniformReportsUniform, basicUniformReportsRef, programGL);
+
+ if (!success) {
+ if (this.m_caseType == es3fUniformApiTests.CaseType.UNIFORM)
+ return false;
+ else {
+ assertMsgOptions(
+ this.m_caseType == es3fUniformApiTests.CaseType.CONSISTENCY,
+ 'es3fUniformApiTests.UniformInfoQueryCase.prototype.test - case type is not consistency',
+ false,
+ true
+ );
+ bufferedLogToConsole('// Note: this is a consistency case, so ignoring above failure(s)');
+ }
+ }
+ }
+
+ if (this.m_caseType == es3fUniformApiTests.CaseType.INDICES_UNIFORMSIV || this.m_caseType == es3fUniformApiTests.CaseType.CONSISTENCY) {
+ success = false;
+
+ //TODO: const ScopedLogSection section(log, "InfoGetActiveUniforms", "es3fUniformApiTests.Uniform information queries with glGetUniformIndices() and glGetActiveUniforms()");
+ success = this.getActiveUniforms(basicUniformReportsUniforms, basicUniformReportsRef, programGL);
+
+ if (!success) {
+ if (this.m_caseType == es3fUniformApiTests.CaseType.INDICES_UNIFORMSIV)
+ return false;
+ else {
+ assertMsgOptions(
+ this.m_caseType == es3fUniformApiTests.CaseType.CONSISTENCY,
+ 'es3fUniformApiTests.UniformInfoQueryCase.prototype.test - case type is not consistency',
+ false,
+ true
+ );
+ bufferedLogToConsole('// Note: this is a consistency case, so ignoring above failure(s)');
+ }
+ }
+ }
+
+ if (this.m_caseType == es3fUniformApiTests.CaseType.CONSISTENCY) {
+ success = false;
+
+ //TODO: const ScopedLogSection section(log, "CompareUniformVsUniforms", "Comparison of results from glGetActiveUniform() and glGetActiveUniforms()");
+ success = this.uniformVsUniformsComparison(basicUniformReportsUniform, basicUniformReportsUniforms);
+
+ if (!success)
+ return false;
+ }
+
+ return true;
+ };
+
+ /**
+ * @enum {number}
+ */
+ es3fUniformApiTests.ValueToCheck = {
+ INITIAL: 0, //!< Verify the initial values of the uniforms (i.e. check that they're zero).
+ ASSIGNED: 1 //!< Assign values to uniforms with glUniform*(), and check those.
+ };
+
+ /**
+ * @enum {number}
+ */
+ es3fUniformApiTests.CheckMethod = {
+ GET_UNIFORM: 0, //!< Check values with glGetUniform*().
+ RENDER: 1 //!< Check values by rendering with the value-checking shader.
+ };
+
+ /**
+ * @enum {number}
+ */
+ es3fUniformApiTests.AssignMethod = {
+ POINTER: 0,
+ VALUE: 1
+ };
+
+ /**
+ * es3fUniformApiTests.UniformValueCase test class
+ * @constructor
+ * @param {string} name
+ * @param {string} description
+ * @param {es3fUniformApiTests.CaseShaderType} shaderType
+ * @param {es3fUniformApiTests.UniformCollection} uniformCollection (SharedPtr)
+ * @param {es3fUniformApiTests.ValueToCheck} valueToCheck
+ * @param {es3fUniformApiTests.CheckMethod} checkMethod
+ * @param {?es3fUniformApiTests.AssignMethod} assignMethod
+ * @param {es3fUniformApiTests.Feature} additionalFeatures
+ * @extends {es3fUniformApiTests.UniformCase}
+ */
+ es3fUniformApiTests.UniformValueCase = function(name, description, shaderType, uniformCollection, valueToCheck, checkMethod, assignMethod, additionalFeatures) {
+ es3fUniformApiTests.UniformCase.call(this, name, description);
+
+ additionalFeatures.UNIFORMVALUE_ZERO |= valueToCheck == es3fUniformApiTests.ValueToCheck.INITIAL;
+ additionalFeatures.UNIFORMFUNC_VALUE |= assignMethod == es3fUniformApiTests.AssignMethod.VALUE;
+ this.newB(shaderType, uniformCollection, additionalFeatures);
+
+ this.m_valueToCheck = valueToCheck;
+ this.m_checkMethod = checkMethod;
+
+ assertMsgOptions(
+ !(assignMethod === undefined && valueToCheck == es3fUniformApiTests.ValueToCheck.ASSIGNED),
+ 'es3fUniformApiTests.UniformValueCase - assign method is undefined when value to check requires it',
+ false,
+ true
+ );
+ };
+
+ es3fUniformApiTests.UniformValueCase.prototype = Object.create(es3fUniformApiTests.UniformCase.prototype);
+ /** Constructor restore */
+ es3fUniformApiTests.UniformValueCase.prototype.constructor = es3fUniformApiTests.UniformValueCase;
+
+ /**
+ * @param {es3fUniformApiTests.ValueToCheck} valueToCheck
+ * @return {?string}
+ */
+ es3fUniformApiTests.UniformValueCase.getValueToCheckName = function(valueToCheck) {
+ switch (valueToCheck) {
+ case es3fUniformApiTests.ValueToCheck.INITIAL: return 'initial';
+ case es3fUniformApiTests.ValueToCheck.ASSIGNED: return 'assigned';
+ default: throw new Error('es3fUniformApiTests.UniformValueCase.getValueToCheckName - Invalid value to check option');
+ }
+ };
+
+ /**
+ * @param {es3fUniformApiTests.ValueToCheck} valueToCheck
+ * @return {?string}
+ */
+ es3fUniformApiTests.UniformValueCase.getValueToCheckDescription = function(valueToCheck) {
+ switch (valueToCheck) {
+ case es3fUniformApiTests.ValueToCheck.INITIAL: return 'Check initial uniform values (zeros)';
+ case es3fUniformApiTests.ValueToCheck.ASSIGNED: return 'Check assigned uniform values';
+ default: throw new Error('es3fUniformApiTests.UniformValueCase.getValueToCheckDescription - Invalid value to check option');
+ }
+ };
+
+ /**
+ * @param {es3fUniformApiTests.CheckMethod} checkMethod
+ * @return {?string}
+ */
+ es3fUniformApiTests.UniformValueCase.getCheckMethodName = function(checkMethod) {
+ switch (checkMethod) {
+ case es3fUniformApiTests.CheckMethod.GET_UNIFORM: return 'get_uniform';
+ case es3fUniformApiTests.CheckMethod.RENDER: return 'render';
+ default: throw new Error('es3fUniformApiTests.UniformValueCase.getCheckMethodName - Invalid check method');
+ }
+ };
+
+ /**
+ * @param {es3fUniformApiTests.CheckMethod} checkMethod
+ * @return {?string}
+ */
+ es3fUniformApiTests.UniformValueCase.getCheckMethodDescription = function(checkMethod) {
+ switch (checkMethod) {
+ case es3fUniformApiTests.CheckMethod.GET_UNIFORM: return 'Verify values with glGetUniform*()';
+ case es3fUniformApiTests.CheckMethod.RENDER: return 'Verify values by rendering';
+ default: throw new Error('es3fUniformApiTests.UniformValueCase.getCheckMethodDescription - Invalid check method');
+ }
+ };
+
+ /**
+ * @param {es3fUniformApiTests.AssignMethod} assignMethod
+ * @return {?string}
+ */
+ es3fUniformApiTests.UniformValueCase.getAssignMethodName = function(assignMethod) {
+ switch (assignMethod) {
+ case es3fUniformApiTests.AssignMethod.POINTER: return 'by_pointer';
+ case es3fUniformApiTests.AssignMethod.VALUE: return 'by_value';
+ default: throw new Error('es3fUniformApiTests.UniformValueCase.getAssignMethodName - Invalid assign method');
+ }
+ };
+
+ /**
+ * @param {es3fUniformApiTests.AssignMethod} assignMethod
+ * @return {?string}
+ */
+ es3fUniformApiTests.UniformValueCase.getAssignMethodDescription = function(assignMethod) {
+ switch (assignMethod) {
+ case es3fUniformApiTests.AssignMethod.POINTER: return 'Assign values by-pointer';
+ case es3fUniformApiTests.AssignMethod.VALUE: return 'Assign values by-value';
+ default: throw new Error('es3fUniformApiTests.UniformValueCase.getAssignMethodDescription - Invalid assign method');
+ }
+ };
+
+ /**
+ * es3fUniformApiTests.UniformValueCase test function
+ * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
+ * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsRef
+ * @param {gluShaderProgram.ShaderProgram} program
+ * @param {deRandom.Random} rnd
+ * @return {boolean}
+ */
+ es3fUniformApiTests.UniformValueCase.prototype.test = function(basicUniforms, basicUniformReportsRef, program, rnd) {
+ /** @type {WebGLProgram} */ var programGL = program.getProgram();
+
+ if (this.m_valueToCheck == es3fUniformApiTests.ValueToCheck.ASSIGNED) {
+ //TODO: const ScopedLogSection section(log, "UniformAssign", "es3fUniformApiTests.Uniform value assignments");
+ this.assignUniforms(basicUniforms, programGL, rnd);
+ } else
+ assertMsgOptions(
+ this.m_valueToCheck == es3fUniformApiTests.ValueToCheck.INITIAL,
+ 'es3fUniformApiTests.UniformValueCase.prototype.test - value to check not initial',
+ false, true
+ );
+
+ /** @type {boolean}*/ var success;
+
+ if (this.m_checkMethod == es3fUniformApiTests.CheckMethod.GET_UNIFORM) {
+ /** @type {Array<es3fUniformApiTests.VarValue>} */ var values = [];
+
+ //TODO: const ScopedLogSection section(log, "GetUniforms", "es3fUniformApiTests.Uniform value query");
+ success = this.getUniforms(values, basicUniforms, program.getProgram());
+
+ if (!success)
+ return false;
+
+ if (this.m_valueToCheck == es3fUniformApiTests.ValueToCheck.ASSIGNED) {
+ //TODO: const ScopedLogSection section(log, "ValueCheck", "Verify that the reported values match the assigned values");
+ success = this.compareUniformValues(values, basicUniforms);
+
+ if (!success)
+ return false;
+ } else {
+ assertMsgOptions(
+ this.m_valueToCheck == es3fUniformApiTests.ValueToCheck.INITIAL,
+ 'es3fUniformApiTests.UniformValueCase.prototype.test - value to check not initial',
+ false, true
+ );
+
+ //TODO: const ScopedLogSection section(log, "ValueCheck", "Verify that the uniforms have correct initial values (zeros)");
+ success = this.checkUniformDefaultValues(values, basicUniforms);
+
+ if (!success)
+ return false;
+ }
+ } else {
+ assertMsgOptions(
+ this.m_checkMethod == es3fUniformApiTests.CheckMethod.RENDER,
+ 'es3fUniformApiTests.UniformValueCase.prototype.test - check method different than RENDER',
+ false, true
+ );
+
+ //TODO: const ScopedLogSection section(log, "RenderTest", "Render test");
+ success = this.renderTest(basicUniforms, program, rnd);
+
+ if (!success)
+ return false;
+ }
+
+ return true;
+ };
+
+ /**
+ * es3fUniformApiTests.RandomUniformCase test class
+ * @constructor
+ * @param {string} name
+ * @param {string} description
+ * @param {number} seed
+ * @extends {es3fUniformApiTests.UniformCase}
+ */
+ es3fUniformApiTests.RandomUniformCase = function(name, description, seed) {
+ es3fUniformApiTests.UniformCase.call(this, name, description);
+ this.newC(seed ^ deRandom.getBaseSeed());
+ };
+
+ es3fUniformApiTests.RandomUniformCase.prototype = Object.create(es3fUniformApiTests.UniformCase.prototype);
+ /** Constructor restore */
+ es3fUniformApiTests.RandomUniformCase.prototype.constructor = es3fUniformApiTests.RandomUniformCase;
+
+ /**
+ * @param {Array<es3fUniformApiTests.BasicUniform>} basicUniforms
+ * @param {Array<es3fUniformApiTests.BasicUniformReportRef>} basicUniformReportsRef
+ * @param {gluShaderProgram.ShaderProgram} program
+ * @param {deRandom.Random} rnd
+ * @return {boolean}
+ */
+ es3fUniformApiTests.RandomUniformCase.prototype.test = function(basicUniforms, basicUniformReportsRef, program, rnd) {
+ // \note Different sampler types may not be bound to same unit when rendering.
+ /** @type {boolean}*/ var renderingPossible = !this.m_features.UNIFORMVALUE_ZERO || !this.m_uniformCollection.containsSeveralSamplerTypes();
+
+ /** @type {boolean} */ var performGetActiveUniforms = rnd.getBool();
+ /** @type {boolean} */ var performGetActiveUniformsiv = rnd.getBool();
+ /** @type {boolean} */ var performUniformVsUniformsivComparison = performGetActiveUniforms && performGetActiveUniformsiv && rnd.getBool();
+ /** @type {boolean} */ var performGetUniforms = rnd.getBool();
+ /** @type {boolean} */ var performCheckUniformDefaultValues = performGetUniforms && rnd.getBool();
+ /** @type {boolean} */ var performAssignUniforms = rnd.getBool();
+ /** @type {boolean} */ var performCompareUniformValues = performGetUniforms && performAssignUniforms && rnd.getBool();
+ /** @type {boolean} */ var performRenderTest = renderingPossible && performAssignUniforms && rnd.getBool();
+ /** @type {WebGLProgram} */ var programGL = program.getProgram();
+
+ if (!(performGetActiveUniforms || performGetActiveUniformsiv || performUniformVsUniformsivComparison || performGetUniforms || performCheckUniformDefaultValues || performAssignUniforms || performCompareUniformValues || performRenderTest))
+ performGetActiveUniforms = true; // Do something at least.
+
+ var PERFORM_AND_CHECK = function(CALL, SECTION_NAME, SECTION_DESCRIPTION) {
+ //TODO: const ScopedLogSection section(log, (SECTION_NAME), (SECTION_DESCRIPTION));
+ /** @type {boolean} */ var success = CALL();
+ if (!success)
+ return false;
+ };
+
+ /** @type {Array<es3fUniformApiTests.BasicUniformReportGL>} */ var reportsUniform = [];
+ /** @type {Array<es3fUniformApiTests.BasicUniformReportGL>} */ var reportsUniformsiv = [];
+
+ var current = this; //To use "this" in anonymous function.
+
+ if (performGetActiveUniforms)
+ PERFORM_AND_CHECK(function() {current.getActiveUniformsOneByOne(reportsUniform, basicUniformReportsRef, programGL);}, 'InfoGetActiveUniform', 'es3fUniformApiTests.Uniform information queries with glGetActiveUniform()');
+
+ if (performGetActiveUniformsiv)
+ PERFORM_AND_CHECK(function() {current.getActiveUniforms(reportsUniformsiv, basicUniformReportsRef, programGL);}, 'InfoGetActiveUniformsiv', 'es3fUniformApiTests.Uniform information queries with glGetIndices() and glGetActiveUniformsiv()');
+
+ if (performUniformVsUniformsivComparison)
+ PERFORM_AND_CHECK(function() {current.uniformVsUniformsComparison(reportsUniform, reportsUniformsiv);}, 'CompareUniformVsUniformsiv', 'Comparison of results from glGetActiveUniform() and glGetActiveUniformsiv()');
+
+ /** @type {Array<es3fUniformApiTests.VarValue>} */ var uniformDefaultValues = [];
+
+ if (performGetUniforms)
+ PERFORM_AND_CHECK(function() {current.getUniforms(uniformDefaultValues, basicUniforms, programGL);}, 'GetUniformDefaults', 'es3fUniformApiTests.Uniform default value query');
+
+ if (performCheckUniformDefaultValues)
+ PERFORM_AND_CHECK(function() {current.checkUniformDefaultValues(uniformDefaultValues, basicUniforms);}, 'DefaultValueCheck', 'Verify that the uniforms have correct initial values (zeros)');
+
+ /** @type {Array<es3fUniformApiTests.VarValue>} */ var uniformValues = [];
+
+ if (performAssignUniforms) {
+ //TODO: const ScopedLogSection section(log, "UniformAssign", "es3fUniformApiTests.Uniform value assignments");
+ this.assignUniforms(basicUniforms, programGL, rnd);
+ }
+
+ if (performCompareUniformValues) {
+ PERFORM_AND_CHECK(function() {current.getUniforms(uniformValues, basicUniforms, programGL);}, 'GetUniforms', 'es3fUniformApiTests.Uniform value query');
+ PERFORM_AND_CHECK(function() {current.compareUniformValues(uniformValues, basicUniforms);}, 'ValueCheck', 'Verify that the reported values match the assigned values');
+ }
+
+ if (performRenderTest)
+ PERFORM_AND_CHECK(function() {current.renderTest(basicUniforms, program, rnd);}, 'RenderTest', 'Render test');
+
+ return true;
+ };
+
+ /**
+ * Initializes the tests to be performed.
+ */
+ es3fUniformApiTests.init = function() {
+ var state = tcuTestCase.runner;
+ var testGroup = state.testCases;
+
+ // Generate sets of UniformCollections that are used by several cases.
+ /**
+ * @enum
+ */
+ var UniformCollections = {
+ BASIC: 0,
+ BASIC_ARRAY: 1,
+ BASIC_STRUCT: 2,
+ STRUCT_IN_ARRAY: 3,
+ ARRAY_IN_STRUCT: 4,
+ NESTED_STRUCTS_ARRAYS: 5,
+ MULTIPLE_BASIC: 6,
+ MULTIPLE_BASIC_ARRAY: 7,
+ MULTIPLE_NESTED_STRUCTS_ARRAYS: 8
+ };
+
+ /**
+ * @constructor
+ */
+ var UniformCollectionGroup = function() {
+ /** @type {string} */ this.name = '';
+ /** @type {Array<es3fUniformApiTests.UniformCollectionCase>} */ this.cases = [];
+ };
+
+ /** @type {Array<UniformCollectionGroup>} */ var defaultUniformCollections = new Array(Object.keys(UniformCollections).length);
+
+ /** @type {string} */ var name;
+
+ //Initialize
+ for (var i = 0; i < defaultUniformCollections.length; i++) defaultUniformCollections[i] = new UniformCollectionGroup();
+
+ defaultUniformCollections[UniformCollections.BASIC].name = 'basic';
+ defaultUniformCollections[UniformCollections.BASIC_ARRAY].name = 'basic_array';
+ defaultUniformCollections[UniformCollections.BASIC_STRUCT].name = 'basic_struct';
+ defaultUniformCollections[UniformCollections.STRUCT_IN_ARRAY].name = 'struct_in_array';
+ defaultUniformCollections[UniformCollections.ARRAY_IN_STRUCT].name = 'array_in_struct';
+ defaultUniformCollections[UniformCollections.NESTED_STRUCTS_ARRAYS].name = 'nested_structs_arrays';
+ defaultUniformCollections[UniformCollections.MULTIPLE_BASIC].name = 'multiple_basic';
+ defaultUniformCollections[UniformCollections.MULTIPLE_BASIC_ARRAY].name = 'multiple_basic_array';
+ defaultUniformCollections[UniformCollections.MULTIPLE_NESTED_STRUCTS_ARRAYS].name = 'multiple_nested_structs_arrays';
+
+ for (var dataTypeNdx = 0; dataTypeNdx < es3fUniformApiTests.s_testDataTypes.length; dataTypeNdx++) {
+ /** @type {gluShaderUtil.DataType} */ var dataType = es3fUniformApiTests.s_testDataTypes[dataTypeNdx];
+ /** @type {string} */ var typeName = gluShaderUtil.getDataTypeName(dataType);
+
+ defaultUniformCollections[UniformCollections.BASIC].cases.push(new es3fUniformApiTests.UniformCollectionCase(typeName, es3fUniformApiTests.UniformCollection.basic(dataType)));
+
+ if (gluShaderUtil.isDataTypeScalar(dataType) ||
+ (gluShaderUtil.isDataTypeVector(dataType) && gluShaderUtil.getDataTypeScalarSize(dataType) == 4) ||
+ dataType == gluShaderUtil.DataType.FLOAT_MAT4 ||
+ dataType == gluShaderUtil.DataType.SAMPLER_2D)
+ defaultUniformCollections[UniformCollections.BASIC_ARRAY].cases.push(new es3fUniformApiTests.UniformCollectionCase(typeName, es3fUniformApiTests.UniformCollection.basicArray(dataType)));
+
+ if (gluShaderUtil.isDataTypeScalar(dataType) ||
+ dataType == gluShaderUtil.DataType.FLOAT_MAT4 ||
+ dataType == gluShaderUtil.DataType.SAMPLER_2D) {
+ /** @type {gluShaderUtil.DataType} */ var secondDataType;
+ if (gluShaderUtil.isDataTypeScalar(dataType))
+ secondDataType = gluShaderUtil.getDataTypeVector(dataType, 4);
+ else if (dataType == gluShaderUtil.DataType.FLOAT_MAT4)
+ secondDataType = gluShaderUtil.DataType.FLOAT_MAT2;
+ else if (dataType == gluShaderUtil.DataType.SAMPLER_2D)
+ secondDataType = gluShaderUtil.DataType.SAMPLER_CUBE;
+
+ assertMsgOptions(
+ secondDataType !== undefined,
+ 'es3fUniformApiTests.init - second data type undefined',
+ false, true
+ );
+
+ /** @type {string} */ var secondTypeName = gluShaderUtil.getDataTypeName(secondDataType);
+ name = typeName + '_' + secondTypeName;
+
+ defaultUniformCollections[UniformCollections.BASIC_STRUCT].cases.push(new es3fUniformApiTests.UniformCollectionCase(name, es3fUniformApiTests.UniformCollection.basicStruct(dataType, secondDataType, false)));
+ defaultUniformCollections[UniformCollections.ARRAY_IN_STRUCT].cases.push(new es3fUniformApiTests.UniformCollectionCase(name, es3fUniformApiTests.UniformCollection.basicStruct(dataType, secondDataType, true)));
+ defaultUniformCollections[UniformCollections.STRUCT_IN_ARRAY].cases.push(new es3fUniformApiTests.UniformCollectionCase(name, es3fUniformApiTests.UniformCollection.structInArray(dataType, secondDataType, false)));
+ defaultUniformCollections[UniformCollections.NESTED_STRUCTS_ARRAYS].cases.push(new es3fUniformApiTests.UniformCollectionCase(name, es3fUniformApiTests.UniformCollection.nestedArraysStructs(dataType, secondDataType)));
+ }
+ }
+ defaultUniformCollections[UniformCollections.MULTIPLE_BASIC].cases.push(new es3fUniformApiTests.UniformCollectionCase(null, es3fUniformApiTests.UniformCollection.multipleBasic()));
+ defaultUniformCollections[UniformCollections.MULTIPLE_BASIC_ARRAY].cases.push(new es3fUniformApiTests.UniformCollectionCase(null, es3fUniformApiTests.UniformCollection.multipleBasicArray()));
+ defaultUniformCollections[UniformCollections.MULTIPLE_NESTED_STRUCTS_ARRAYS].cases.push(new es3fUniformApiTests.UniformCollectionCase(null, es3fUniformApiTests.UniformCollection.multipleNestedArraysStructs()));
+
+ // Info-query cases (check info returned by e.g. glGetActiveUniforms()).
+
+ // info_query
+ /** @type {tcuTestCase.DeqpTest} */
+ var infoQueryGroup = tcuTestCase.newTest('info_query', 'Test uniform info querying functions');
+ testGroup.addChild(infoQueryGroup);
+
+ /** @type {UniformCollectionGroup} */ var collectionGroup;
+ /** @type {es3fUniformApiTests.UniformCollectionCase} */ var collectionCase;
+ /** @type {es3fUniformApiTests.UniformCollection} (SharedPtr) */ var uniformCollection;
+ /** @type {es3fUniformApiTests.Feature} */ var features;
+ /** @type {tcuTestCase.DeqpTest} */ var collectionTestGroup;
+ /** @type {string} */ var collName;
+ /** @type {es3fUniformApiTests.CheckMethod} */ var checkMethod;
+ /** @type {tcuTestCase.DeqpTest} */ var checkMethodGroup;
+ /** @type {string} */ var collectionGroupName;
+ /** @type {boolean} */ var containsBooleans;
+ /** @type {boolean} */ var varyBoolApiType;
+ /** @type {number} */ var numBoolVariations;
+ /** @type {es3fUniformApiTests.Feature} */ var booleanTypeFeat;
+ /** @type {string} */ var booleanTypeName;
+ /** @type {tcuTestCase.DeqpTest} */ var unusedUniformsGroup;
+
+ /** @type {Array<string>} */ var shaderTypes = Object.keys(es3fUniformApiTests.CaseShaderType);
+
+ for (var caseTypeI in es3fUniformApiTests.CaseType) {
+ /** @type {es3fUniformApiTests.CaseType} */ var caseType = es3fUniformApiTests.CaseType[caseTypeI];
+ /** @type {tcuTestCase.DeqpTest} */
+ var caseTypeGroup = tcuTestCase.newTest(es3fUniformApiTests.UniformInfoQueryCase.getCaseTypeName(caseType), es3fUniformApiTests.UniformInfoQueryCase.getCaseTypeDescription(caseType));
+ infoQueryGroup.addChild(caseTypeGroup);
+
+ for (var collectionGroupNdx = 0; collectionGroupNdx < Object.keys(UniformCollections).length; collectionGroupNdx++) {
+ var numArrayFirstElemNameCases = caseType == es3fUniformApiTests.CaseType.INDICES_UNIFORMSIV && collectionGroupNdx == UniformCollections.BASIC_ARRAY ? 2 : 1;
+
+ for (var referToFirstArrayElemWithoutIndexI = 0; referToFirstArrayElemWithoutIndexI < numArrayFirstElemNameCases; referToFirstArrayElemWithoutIndexI++) {
+ collectionGroup = defaultUniformCollections[collectionGroupNdx];
+ collectionGroupName = collectionGroup.name + (referToFirstArrayElemWithoutIndexI == 0 ? '' : '_first_elem_without_brackets');
+ collectionTestGroup = tcuTestCase.newTest(collectionGroupName, '');
+ caseTypeGroup.addChild(collectionTestGroup);
+
+ for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) {
+ collectionCase = collectionGroup.cases[collectionNdx];
+
+ for (var i = 0; i < shaderTypes.length; i++) {
+ name = collectionCase.namePrefix + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]);
+ uniformCollection = collectionCase.uniformCollection;
+
+ features = new es3fUniformApiTests.Feature();
+ features.ARRAY_FIRST_ELEM_NAME_NO_INDEX = referToFirstArrayElemWithoutIndexI != 0;
+
+ collectionTestGroup.addChild(new es3fUniformApiTests.UniformInfoQueryCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection, caseType, features));
+ }
+ }
+ }
+ }
+
+ // Info-querying cases when unused uniforms are present.
+
+ unusedUniformsGroup = tcuTestCase.newTest('unused_uniforms', 'Test with unused uniforms');
+ caseTypeGroup.addChild(unusedUniformsGroup);
+
+ collectionGroup = defaultUniformCollections[UniformCollections.ARRAY_IN_STRUCT];
+
+ for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) {
+ collectionCase = collectionGroup.cases[collectionNdx];
+ collName = collectionCase.namePrefix;
+ uniformCollection = collectionCase.uniformCollection;
+
+ for (var i = 0; i < shaderTypes.length; i++) {
+ name = collName + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]);
+
+ features = new es3fUniformApiTests.Feature();
+ features.UNIFORMUSAGE_EVERY_OTHER = true;
+ features.ARRAYUSAGE_ONLY_MIDDLE_INDEX = true;
+
+ unusedUniformsGroup.addChild(new es3fUniformApiTests.UniformInfoQueryCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection, caseType, features));
+ }
+ }
+ }
+
+ // Cases testing uniform values.
+
+ // Cases checking uniforms' initial values (all must be zeros), with glGetUniform*() or by rendering.
+
+ /** @type {tcuTestCase.DeqpTest} */ var initialValuesGroup = tcuTestCase.newTest(
+ 'value.' + es3fUniformApiTests.UniformValueCase.getValueToCheckName(es3fUniformApiTests.ValueToCheck.INITIAL),
+ es3fUniformApiTests.UniformValueCase.getValueToCheckDescription(es3fUniformApiTests.ValueToCheck.INITIAL));
+ testGroup.addChild(initialValuesGroup);
+
+ for (var checkMethodI in es3fUniformApiTests.CheckMethod) {
+ checkMethod = es3fUniformApiTests.CheckMethod[checkMethodI];
+ checkMethodGroup = tcuTestCase.newTest(es3fUniformApiTests.UniformValueCase.getCheckMethodName(checkMethod), es3fUniformApiTests.UniformValueCase.getCheckMethodDescription(checkMethod));
+ initialValuesGroup.addChild(checkMethodGroup);
+
+ for (var collectionGroupNdx = 0; collectionGroupNdx < Object.keys(UniformCollections).length; collectionGroupNdx++) {
+ collectionGroup = defaultUniformCollections[collectionGroupNdx];
+ collectionTestGroup = tcuTestCase.newTest(collectionGroup.name, '');
+ checkMethodGroup.addChild(collectionTestGroup);
+
+ for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) {
+ collectionCase = collectionGroup.cases[collectionNdx];
+ collName = collectionCase.namePrefix;
+ uniformCollection = collectionCase.uniformCollection;
+ containsBooleans = uniformCollection.containsMatchingBasicType(gluShaderUtil.isDataTypeBoolOrBVec);
+ varyBoolApiType = checkMethod == es3fUniformApiTests.CheckMethod.GET_UNIFORM && containsBooleans &&
+ (collectionGroupNdx == UniformCollections.BASIC || collectionGroupNdx == UniformCollections.BASIC_ARRAY);
+ numBoolVariations = varyBoolApiType ? 3 : 1;
+
+ if (checkMethod == es3fUniformApiTests.CheckMethod.RENDER && uniformCollection.containsSeveralSamplerTypes())
+ continue; // \note Samplers' initial API values (i.e. their texture units) are 0, and no two samplers of different types shall have same unit when rendering.
+
+ for (var booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++) {
+ booleanTypeFeat = new es3fUniformApiTests.Feature();
+ booleanTypeFeat.BOOLEANAPITYPE_INT = booleanTypeI == 1;
+ booleanTypeFeat.BOOLEANAPITYPE_UINT = booleanTypeI == 2;
+
+ booleanTypeName = booleanTypeI == 1 ? 'int' :
+ booleanTypeI == 2 ? 'uint' :
+ 'float';
+ /** @type {string} */ var nameWithApiType = varyBoolApiType ? collName + 'api_' + booleanTypeName + '_' : collName;
+
+ for (var i = 0; i < shaderTypes.length; i++) {
+ name = nameWithApiType + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]);
+ collectionTestGroup.addChild(new es3fUniformApiTests.UniformValueCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection,
+ es3fUniformApiTests.ValueToCheck.INITIAL, checkMethod, null, booleanTypeFeat));
+ }
+ }
+ }
+ }
+ }
+
+ // Cases that first assign values to each uniform, then check the values with glGetUniform*() or by rendering.
+
+ /** @type {tcuTestCase.DeqpTest} */ var assignedValuesGroup = tcuTestCase.newTest(
+ 'value.' + es3fUniformApiTests.UniformValueCase.getValueToCheckName(es3fUniformApiTests.ValueToCheck.ASSIGNED),
+ es3fUniformApiTests.UniformValueCase.getValueToCheckDescription(es3fUniformApiTests.ValueToCheck.ASSIGNED));
+ testGroup.addChild(assignedValuesGroup);
+
+ for (var assignMethodI in es3fUniformApiTests.AssignMethod) {
+ /** @type {es3fUniformApiTests.AssignMethod} */ var assignMethod = es3fUniformApiTests.AssignMethod[assignMethodI];
+ /** @type {tcuTestCase.DeqpTest} */ var assignMethodGroup = tcuTestCase.newTest(es3fUniformApiTests.UniformValueCase.getAssignMethodName(assignMethod), es3fUniformApiTests.UniformValueCase.getAssignMethodDescription(assignMethod));
+ assignedValuesGroup.addChild(assignMethodGroup);
+
+ for (var checkMethodI in es3fUniformApiTests.CheckMethod) {
+ checkMethod = es3fUniformApiTests.CheckMethod[checkMethodI];
+ checkMethodGroup = tcuTestCase.newTest(es3fUniformApiTests.UniformValueCase.getCheckMethodName(checkMethod), es3fUniformApiTests.UniformValueCase.getCheckMethodDescription(checkMethod));
+ assignMethodGroup.addChild(checkMethodGroup);
+
+ for (var collectionGroupNdx = 0; collectionGroupNdx < Object.keys(UniformCollections).length; collectionGroupNdx++) {
+ /** @type {number} */ var numArrayFirstElemNameCases = checkMethod == es3fUniformApiTests.CheckMethod.GET_UNIFORM && collectionGroupNdx == UniformCollections.BASIC_ARRAY ? 2 : 1;
+
+ for (var referToFirstArrayElemWithoutIndexI = 0; referToFirstArrayElemWithoutIndexI < numArrayFirstElemNameCases; referToFirstArrayElemWithoutIndexI++) {
+ collectionGroup = defaultUniformCollections[collectionGroupNdx];
+ collectionGroupName = collectionGroup.name + (referToFirstArrayElemWithoutIndexI == 0 ? '' : '_first_elem_without_brackets');
+ collectionTestGroup = tcuTestCase.newTest(collectionGroupName, '');
+ checkMethodGroup.addChild(collectionTestGroup);
+
+ for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) {
+ collectionCase = collectionGroup.cases[collectionNdx];
+ collName = collectionCase.namePrefix;
+ uniformCollection = collectionCase.uniformCollection;
+ containsBooleans = uniformCollection.containsMatchingBasicType(gluShaderUtil.isDataTypeBoolOrBVec);
+ varyBoolApiType = checkMethod == es3fUniformApiTests.CheckMethod.GET_UNIFORM && containsBooleans &&
+ (collectionGroupNdx == UniformCollections.BASIC || collectionGroupNdx == UniformCollections.BASIC_ARRAY);
+ numBoolVariations = varyBoolApiType ? 3 : 1;
+ /** @type {boolean} */ var containsMatrices = uniformCollection.containsMatchingBasicType(gluShaderUtil.isDataTypeMatrix);
+ /** @type {boolean} */ var varyMatrixMode = containsMatrices &&
+ (collectionGroupNdx == UniformCollections.BASIC || collectionGroupNdx == UniformCollections.BASIC_ARRAY);
+ /** @type {number} */ var numMatVariations = varyMatrixMode ? 2 : 1;
+
+ if (containsMatrices && assignMethod != es3fUniformApiTests.AssignMethod.POINTER)
+ continue;
+
+ for (var booleanTypeI = 0; booleanTypeI < numBoolVariations; booleanTypeI++) {
+ booleanTypeFeat = new es3fUniformApiTests.Feature();
+ booleanTypeFeat.BOOLEANAPITYPE_INT = booleanTypeI == 1;
+ booleanTypeFeat.BOOLEANAPITYPE_UINT = booleanTypeI == 2;
+
+ booleanTypeName = booleanTypeI == 1 ? 'int' :
+ booleanTypeI == 2 ? 'uint' :
+ 'float';
+ /** @type {string} */ var nameWithBoolType = varyBoolApiType ? collName + 'api_' + booleanTypeName + '_' : collName;
+
+ for (var matrixTypeI = 0; matrixTypeI < numMatVariations; matrixTypeI++) {
+ /** @type {string} */ var nameWithMatrixType = nameWithBoolType + (matrixTypeI == 1 ? 'row_major_' : '');
+
+ for (var i = 0; i < shaderTypes.length; i++) {
+ name = nameWithMatrixType + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]);
+
+ booleanTypeFeat.ARRAY_FIRST_ELEM_NAME_NO_INDEX = referToFirstArrayElemWithoutIndexI != 0;
+ booleanTypeFeat.MATRIXMODE_ROWMAJOR = matrixTypeI == 1;
+
+ collectionTestGroup.addChild(new es3fUniformApiTests.UniformValueCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection,
+ es3fUniformApiTests.ValueToCheck.ASSIGNED, checkMethod, assignMethod, booleanTypeFeat));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Cases assign multiple basic-array elements with one glUniform*v() (i.e. the count parameter is bigger than 1).
+
+ /** @type {es3fUniformApiTests.Feature} */ var arrayAssignFullMode = new es3fUniformApiTests.Feature();
+ arrayAssignFullMode.ARRAYASSIGN_FULL = true;
+
+ /** @type {es3fUniformApiTests.Feature} */ var arrayAssignBlocksOfTwo = new es3fUniformApiTests.Feature();
+ arrayAssignFullMode.ARRAYASSIGN_BLOCKS_OF_TWO = true;
+
+ var arrayAssignGroups =
+ [{arrayAssignMode: arrayAssignFullMode, name: 'basic_array_assign_full', description: 'Assign entire basic-type arrays per glUniform*v() call'}, {arrayAssignMode: arrayAssignBlocksOfTwo, name: 'basic_array_assign_partial', description: 'Assign two elements of a basic-type array per glUniform*v() call'}
+ ];
+
+ for (var arrayAssignGroupNdx = 0; arrayAssignGroupNdx < arrayAssignGroups.length; arrayAssignGroupNdx++) {
+ /** @type {es3fUniformApiTests.Feature} */ var arrayAssignMode = arrayAssignGroups[arrayAssignGroupNdx].arrayAssignMode;
+ /** @type {string} */ var groupName = arrayAssignGroups[arrayAssignGroupNdx].name;
+ /** @type {string} */ var groupDesc = arrayAssignGroups[arrayAssignGroupNdx].description;
+
+ /** @type {tcuTestCase.DeqpTest} */ var curArrayAssignGroup = tcuTestCase.newTest(groupName, groupDesc);
+ assignedValuesGroup.addChild(curArrayAssignGroup);
+
+ /** @type {Array<number>} */ var basicArrayCollectionGroups = [UniformCollections.BASIC_ARRAY, UniformCollections.ARRAY_IN_STRUCT, UniformCollections.MULTIPLE_BASIC_ARRAY];
+
+ for (var collectionGroupNdx = 0; collectionGroupNdx < basicArrayCollectionGroups.length; collectionGroupNdx++) {
+ collectionGroup = defaultUniformCollections[basicArrayCollectionGroups[collectionGroupNdx]];
+ collectionTestGroup = tcuTestCase.newTest(collectionGroup.name, '');
+ curArrayAssignGroup.addChild(collectionTestGroup);
+
+ for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) {
+ collectionCase = collectionGroup.cases[collectionNdx];
+ collName = collectionCase.namePrefix;
+ uniformCollection = collectionCase.uniformCollection;
+
+ for (var i = 0; i < shaderTypes.length; i++) {
+ name = collName + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]);
+ collectionTestGroup.addChild(new es3fUniformApiTests.UniformValueCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection,
+ es3fUniformApiTests.ValueToCheck.ASSIGNED, es3fUniformApiTests.CheckMethod.GET_UNIFORM, es3fUniformApiTests.AssignMethod.POINTER,
+ arrayAssignMode));
+ }
+ }
+ }
+ }
+
+ // Value checking cases when unused uniforms are present.
+
+ unusedUniformsGroup = tcuTestCase.newTest('unused_uniforms', 'Test with unused uniforms');
+ assignedValuesGroup.addChild(unusedUniformsGroup);
+
+ collectionGroup = defaultUniformCollections[UniformCollections.ARRAY_IN_STRUCT];
+
+ for (var collectionNdx = 0; collectionNdx < collectionGroup.cases.length; collectionNdx++) {
+ collectionCase = collectionGroup.cases[collectionNdx];
+ collName = collectionCase.namePrefix;
+ uniformCollection = collectionCase.uniformCollection;
+
+ for (var i = 0; i < shaderTypes.length; i++) {
+ name = collName + es3fUniformApiTests.getCaseShaderTypeName(es3fUniformApiTests.CaseShaderType[shaderTypes[i]]);
+
+ features = new es3fUniformApiTests.Feature();
+ features.ARRAYUSAGE_ONLY_MIDDLE_INDEX = true;
+ features.UNIFORMUSAGE_EVERY_OTHER = true;
+
+ unusedUniformsGroup.addChild(new es3fUniformApiTests.UniformValueCase(name, '', es3fUniformApiTests.CaseShaderType[shaderTypes[i]], uniformCollection,
+ es3fUniformApiTests.ValueToCheck.ASSIGNED, es3fUniformApiTests.CheckMethod.GET_UNIFORM, es3fUniformApiTests.AssignMethod.POINTER,
+ features));
+ }
+ }
+
+ // Random cases.
+
+ /** @type {number} */ var numRandomCases = 100;
+ /** @type {tcuTestCase.DeqpTest} */ var randomGroup = tcuTestCase.newTest('random', 'Random cases');
+ testGroup.addChild(randomGroup);
+
+ for (var ndx = 0; ndx < numRandomCases; ndx++)
+ randomGroup.addChild(new es3fUniformApiTests.RandomUniformCase('' + ndx, '', ndx));
+ };
+
+ /**
+ * Create and execute the test cases
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fUniformApiTests.run = function(context, range) {
+ gl = context;
+ //Set up Test Root parameters
+ var testName = 'uniform_api';
+ var testDescription = 'es3fUniformApiTests.Uniform API Tests';
+ var state = tcuTestCase.runner;
+
+ state.testName = testName;
+ state.testCases = tcuTestCase.newTest(testName, testDescription, null);
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ es3fUniformApiTests.init();
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fUniformApiTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fUniformBlockTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fUniformBlockTests.js
new file mode 100644
index 0000000000..91a90fdc64
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fUniformBlockTests.js
@@ -0,0 +1,748 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fUniformBlockTests');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('modules.shared.glsRandomUniformBlockCase');
+goog.require('modules.shared.glsUniformBlockCase');
+
+goog.scope(function() {
+
+ var es3fUniformBlockTests = functional.gles3.es3fUniformBlockTests;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var glsUniformBlockCase = modules.shared.glsUniformBlockCase;
+ var glsRandomUniformBlockCase = modules.shared.glsRandomUniformBlockCase;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var deMath = framework.delibs.debase.deMath;
+ var deRandom = framework.delibs.debase.deRandom;
+
+ /**
+ * es3fUniformBlockTests.createRandomCaseGroup
+ * @param {tcuTestCase.DeqpTest} parentGroup
+ * @param {string} groupName
+ * @param {string} description
+ * @param {glsUniformBlockCase.BufferMode} bufferMode
+ * @param {number} features
+ * @param {number} numCases
+ * @param {number} baseSeed
+ */
+ es3fUniformBlockTests.createRandomCaseGroup = function(parentGroup, groupName, description, bufferMode, features, numCases, baseSeed) {
+ /** @type {tcuTestCase.DeqpTest} */
+ var group = tcuTestCase.newTest(groupName, description);
+ parentGroup.addChild(group);
+
+ baseSeed += deRandom.getBaseSeed();
+
+ for (var ndx = 0; ndx < numCases; ndx++)
+ group.addChild(new glsRandomUniformBlockCase.RandomUniformBlockCase('' + ndx, '', bufferMode, features, ndx + baseSeed));
+ };
+
+ /**
+ * es3fUniformBlockTests.BlockBasicTypeCase constructor
+ * @param {string} name The name of the test
+ * @param {string} description The description of the test
+ * @param {glsUniformBlockCase.VarType} type The type of the block
+ * @param {number} layoutFlags
+ * @param {number} numInstances
+ * @constructor
+ * @extends {glsUniformBlockCase.UniformBlockCase}
+ */
+ es3fUniformBlockTests.BlockBasicTypeCase = function(name, description, type, layoutFlags, numInstances) {
+ glsUniformBlockCase.UniformBlockCase.call(this, name, description, glsUniformBlockCase.BufferMode.BUFFERMODE_PER_BLOCK);
+ /** @type {glsUniformBlockCase.UniformBlock}*/ var block = this.m_interface.allocBlock('Block');
+ block.addUniform(new glsUniformBlockCase.Uniform('var', type, 0));
+ block.setFlags(layoutFlags);
+
+ if (numInstances > 0) {
+ block.setArraySize(numInstances);
+ block.setInstanceName('block');
+ }
+ };
+
+ es3fUniformBlockTests.BlockBasicTypeCase.prototype = Object.create(glsUniformBlockCase.UniformBlockCase.prototype);
+ es3fUniformBlockTests.BlockBasicTypeCase.prototype.constructor = es3fUniformBlockTests.BlockBasicTypeCase;
+
+ /**
+ * es3fUniformBlockTests.createBlockBasicTypeCases
+ * @param {tcuTestCase.DeqpTest} group
+ * @param {string} name
+ * @param {glsUniformBlockCase.VarType} type
+ * @param {number} layoutFlags
+ * @param {number=} numInstances
+ */
+ es3fUniformBlockTests.createBlockBasicTypeCases = function(group, name, type, layoutFlags, numInstances) {
+ numInstances = (numInstances === undefined) ? 0 : numInstances;
+ group.addChild(new es3fUniformBlockTests.BlockBasicTypeCase(name + '_vertex', '', type, layoutFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX, numInstances));
+ group.addChild(new es3fUniformBlockTests.BlockBasicTypeCase(name + '_fragment', '', type, layoutFlags | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, numInstances));
+
+ //alert(group.spec[0].m_instance);
+ if (!(layoutFlags & glsUniformBlockCase.UniformFlags.LAYOUT_PACKED))
+ group.addChild(new es3fUniformBlockTests.BlockBasicTypeCase(name + '_both', '', type, layoutFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, numInstances));
+ };
+
+ /**
+ * es3fUniformBlockTests.BlockSingleStructCase constructor
+ * @param {string} name The name of the test
+ * @param {string} description The description of the test
+ * @param {number} layoutFlags
+ * @param {glsUniformBlockCase.BufferMode} bufferMode
+ * @param {number} numInstances
+ * @constructor
+ * @extends {glsUniformBlockCase.UniformBlockCase}
+ */
+ es3fUniformBlockTests.BlockSingleStructCase = function(name, description, layoutFlags, bufferMode, numInstances) {
+ glsUniformBlockCase.UniformBlockCase.call(this, name, description, bufferMode);
+ this.m_layoutFlags = layoutFlags;
+ this.m_numInstances = numInstances;
+ };
+
+ es3fUniformBlockTests.BlockSingleStructCase.prototype = Object.create(glsUniformBlockCase.UniformBlockCase.prototype);
+ es3fUniformBlockTests.BlockSingleStructCase.prototype.constructor = es3fUniformBlockTests.BlockSingleStructCase;
+
+ es3fUniformBlockTests.BlockSingleStructCase.prototype.init = function() {
+ /**@type {glsUniformBlockCase.StructType}*/ var typeS = this.m_interface.allocStruct('S');
+ typeS.addMember('a', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.INT_VEC3, glsUniformBlockCase.UniformFlags.PRECISION_HIGH), glsUniformBlockCase.UniformFlags.UNUSED_BOTH); // First member is unused.
+ typeS.addMember('b', glsUniformBlockCase.newVarTypeArray(glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_MAT3, glsUniformBlockCase.UniformFlags.PRECISION_MEDIUM), 4));
+ typeS.addMember('c', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_VEC4, glsUniformBlockCase.UniformFlags.PRECISION_HIGH));
+
+ /** @type {glsUniformBlockCase.UniformBlock} */ var block = this.m_interface.allocBlock('Block');
+ block.addUniform(new glsUniformBlockCase.Uniform('s', glsUniformBlockCase.newVarTypeStruct(typeS), 0));
+ block.setFlags(this.m_layoutFlags);
+
+ if (this.m_numInstances > 0) {
+ block.setInstanceName('block');
+ block.setArraySize(this.m_numInstances);
+ }
+ };
+
+ /**
+ * es3fUniformBlockTests.BlockSingleStructArrayCase constructor
+ * @param {string} name The name of the test
+ * @param {string} description The description of the test
+ * @param {number} layoutFlags
+ * @param {glsUniformBlockCase.BufferMode} bufferMode
+ * @param {number} numInstances
+ * @constructor
+ * @extends {glsUniformBlockCase.UniformBlockCase}
+ */
+ es3fUniformBlockTests.BlockSingleStructArrayCase = function(name, description, layoutFlags, bufferMode, numInstances) {
+ glsUniformBlockCase.UniformBlockCase.call(this, name, description, bufferMode);
+ this.m_layoutFlags = layoutFlags;
+ this.m_numInstances = numInstances;
+ };
+
+ es3fUniformBlockTests.BlockSingleStructArrayCase.prototype = Object.create(glsUniformBlockCase.UniformBlockCase.prototype);
+ es3fUniformBlockTests.BlockSingleStructArrayCase.prototype.constructor = es3fUniformBlockTests.BlockSingleStructArrayCase;
+
+ es3fUniformBlockTests.BlockSingleStructArrayCase.prototype.init = function() {
+ /**@type {glsUniformBlockCase.StructType}*/ var typeS = this.m_interface.allocStruct('S');
+ typeS.addMember('a', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.INT_VEC3, glsUniformBlockCase.UniformFlags.PRECISION_HIGH), glsUniformBlockCase.UniformFlags.UNUSED_BOTH); // First member is unused.
+ typeS.addMember('b', glsUniformBlockCase.newVarTypeArray(glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_MAT3, glsUniformBlockCase.UniformFlags.PRECISION_MEDIUM), 4));
+ typeS.addMember('c', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_VEC4, glsUniformBlockCase.UniformFlags.PRECISION_HIGH));
+
+ /** @type {glsUniformBlockCase.UniformBlock} */ var block = this.m_interface.allocBlock('Block');
+ block.addUniform(new glsUniformBlockCase.Uniform('u', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.UINT, glsUniformBlockCase.UniformFlags.PRECISION_LOW)));
+ block.addUniform(new glsUniformBlockCase.Uniform('s', glsUniformBlockCase.newVarTypeArray(glsUniformBlockCase.newVarTypeStruct(typeS), 3)));
+ block.addUniform(new glsUniformBlockCase.Uniform('v', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_VEC4, glsUniformBlockCase.UniformFlags.PRECISION_MEDIUM)));
+ block.setFlags(this.m_layoutFlags);
+
+ if (this.m_numInstances > 0) {
+ block.setInstanceName('block');
+ block.setArraySize(this.m_numInstances);
+ }
+ };
+
+ /**
+ * es3fUniformBlockTests.BlockSingleNestedStructCase constructor
+ * @param {string} name The name of the test
+ * @param {string} description The description of the test
+ * @param {number} layoutFlags
+ * @param {glsUniformBlockCase.BufferMode} bufferMode
+ * @param {number} numInstances
+ * @constructor
+ * @extends {glsUniformBlockCase.UniformBlockCase}
+ */
+ es3fUniformBlockTests.BlockSingleNestedStructCase = function(name, description, layoutFlags, bufferMode, numInstances) {
+ glsUniformBlockCase.UniformBlockCase.call(this, name, description, bufferMode);
+ this.m_layoutFlags = layoutFlags;
+ this.m_numInstances = numInstances;
+ };
+
+ es3fUniformBlockTests.BlockSingleNestedStructCase.prototype = Object.create(glsUniformBlockCase.UniformBlockCase.prototype);
+ es3fUniformBlockTests.BlockSingleNestedStructCase.prototype.constructor = es3fUniformBlockTests.BlockSingleNestedStructCase;
+
+ es3fUniformBlockTests.BlockSingleNestedStructCase.prototype.init = function() {
+ /**@type {glsUniformBlockCase.StructType}*/ var typeS = this.m_interface.allocStruct('S');
+ typeS.addMember('a', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.INT_VEC3, glsUniformBlockCase.UniformFlags.PRECISION_HIGH));
+ typeS.addMember('b', glsUniformBlockCase.newVarTypeArray(glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_MAT3, glsUniformBlockCase.UniformFlags.PRECISION_MEDIUM), 4));
+ typeS.addMember('c', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_VEC4, glsUniformBlockCase.UniformFlags.PRECISION_HIGH), glsUniformBlockCase.UniformFlags.UNUSED_BOTH);
+
+ /**@type {glsUniformBlockCase.StructType}*/ var typeT = this.m_interface.allocStruct('T');
+ typeT.addMember('a', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_MAT3, glsUniformBlockCase.UniformFlags.PRECISION_MEDIUM));
+ typeT.addMember('b', glsUniformBlockCase.newVarTypeStruct(typeS));
+
+ /** @type {glsUniformBlockCase.UniformBlock} */ var block = this.m_interface.allocBlock('Block');
+ block.addUniform(new glsUniformBlockCase.Uniform('s', glsUniformBlockCase.newVarTypeStruct(typeS), 0));
+ block.addUniform(new glsUniformBlockCase.Uniform('v', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_VEC2, glsUniformBlockCase.UniformFlags.PRECISION_LOW), glsUniformBlockCase.UniformFlags.UNUSED_BOTH));
+ block.addUniform(new glsUniformBlockCase.Uniform('t', glsUniformBlockCase.newVarTypeStruct(typeT), 0));
+ block.addUniform(new glsUniformBlockCase.Uniform('u', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.UINT, glsUniformBlockCase.UniformFlags.PRECISION_HIGH), 0));
+ block.setFlags(this.m_layoutFlags);
+
+ if (this.m_numInstances > 0) {
+ block.setInstanceName('block');
+ block.setArraySize(this.m_numInstances);
+ }
+ };
+
+ /**
+ * es3fUniformBlockTests.BlockSingleNestedStructArrayCase constructor
+ * @param {string} name The name of the test
+ * @param {string} description The description of the test
+ * @param {number} layoutFlags
+ * @param {glsUniformBlockCase.BufferMode} bufferMode
+ * @param {number} numInstances
+ * @constructor
+ * @extends {glsUniformBlockCase.UniformBlockCase}
+ */
+ es3fUniformBlockTests.BlockSingleNestedStructArrayCase = function(name, description, layoutFlags, bufferMode, numInstances) {
+ glsUniformBlockCase.UniformBlockCase.call(this, name, description, bufferMode);
+ this.m_layoutFlags = layoutFlags;
+ this.m_numInstances = numInstances;
+ };
+
+ es3fUniformBlockTests.BlockSingleNestedStructArrayCase.prototype = Object.create(glsUniformBlockCase.UniformBlockCase.prototype);
+ es3fUniformBlockTests.BlockSingleNestedStructArrayCase.prototype.constructor = es3fUniformBlockTests.BlockSingleNestedStructArrayCase;
+
+ es3fUniformBlockTests.BlockSingleNestedStructArrayCase.prototype.init = function() {
+ /**@type {glsUniformBlockCase.StructType}*/ var typeS = this.m_interface.allocStruct('S');
+ typeS.addMember('a', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.INT_VEC3, glsUniformBlockCase.UniformFlags.PRECISION_HIGH));
+ typeS.addMember('b', glsUniformBlockCase.newVarTypeArray(glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.INT_VEC2, glsUniformBlockCase.UniformFlags.PRECISION_MEDIUM), 4));
+ typeS.addMember('c', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_VEC4, glsUniformBlockCase.UniformFlags.PRECISION_HIGH), glsUniformBlockCase.UniformFlags.UNUSED_BOTH);
+
+ /**@type {glsUniformBlockCase.StructType}*/ var typeT = this.m_interface.allocStruct('T');
+ typeT.addMember('a', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_MAT3, glsUniformBlockCase.UniformFlags.PRECISION_MEDIUM));
+ typeT.addMember('b', glsUniformBlockCase.newVarTypeArray(glsUniformBlockCase.newVarTypeStruct(typeS), 3));
+
+ /** @type {glsUniformBlockCase.UniformBlock} */ var block = this.m_interface.allocBlock('Block');
+ block.addUniform(new glsUniformBlockCase.Uniform('s', glsUniformBlockCase.newVarTypeStruct(typeS), 0));
+ block.addUniform(new glsUniformBlockCase.Uniform('v', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_VEC2, glsUniformBlockCase.UniformFlags.PRECISION_LOW), glsUniformBlockCase.UniformFlags.UNUSED_BOTH));
+ block.addUniform(new glsUniformBlockCase.Uniform('t', glsUniformBlockCase.newVarTypeArray(glsUniformBlockCase.newVarTypeStruct(typeT), 2), 0));
+ block.addUniform(new glsUniformBlockCase.Uniform('u', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.UINT, glsUniformBlockCase.UniformFlags.PRECISION_HIGH), 0));
+ block.setFlags(this.m_layoutFlags);
+
+ if (this.m_numInstances > 0) {
+ block.setInstanceName('block');
+ block.setArraySize(this.m_numInstances);
+ }
+ };
+
+ /**
+ * es3fUniformBlockTests.BlockMultiBasicTypesCase constructor
+ * @param {string} name The name of the test
+ * @param {string} description The description of the test
+ * @param {number} flagsA
+ * @param {number} flagsB
+ * @param {glsUniformBlockCase.BufferMode} bufferMode
+ * @param {number} numInstances
+ * @constructor
+ * @extends {glsUniformBlockCase.UniformBlockCase}
+ */
+ es3fUniformBlockTests.BlockMultiBasicTypesCase = function(name, description, flagsA, flagsB, bufferMode, numInstances) {
+ glsUniformBlockCase.UniformBlockCase.call(this, name, description, bufferMode);
+ this.m_flagsA = flagsA;
+ this.m_flagsB = flagsB;
+ this.m_numInstances = numInstances;
+ };
+
+ es3fUniformBlockTests.BlockMultiBasicTypesCase.prototype = Object.create(glsUniformBlockCase.UniformBlockCase.prototype);
+ es3fUniformBlockTests.BlockMultiBasicTypesCase.prototype.constructor = es3fUniformBlockTests.BlockMultiBasicTypesCase;
+
+ es3fUniformBlockTests.BlockMultiBasicTypesCase.prototype.init = function() {
+ /** @type {glsUniformBlockCase.UniformBlock} */ var blockA = this.m_interface.allocBlock('BlockA');
+ blockA.addUniform(new glsUniformBlockCase.Uniform('a', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT, glsUniformBlockCase.UniformFlags.PRECISION_HIGH)));
+ blockA.addUniform(new glsUniformBlockCase.Uniform('b', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.UINT_VEC3, glsUniformBlockCase.UniformFlags.PRECISION_LOW), glsUniformBlockCase.UniformFlags.UNUSED_BOTH));
+ blockA.addUniform(new glsUniformBlockCase.Uniform('c', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_MAT2, glsUniformBlockCase.UniformFlags.PRECISION_MEDIUM)));
+ blockA.setInstanceName('blockA');
+ blockA.setFlags(this.m_flagsA);
+
+ /** @type {glsUniformBlockCase.UniformBlock} */ var blockB = this.m_interface.allocBlock('BlockB');
+ blockB.addUniform(new glsUniformBlockCase.Uniform('a', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_MAT3, glsUniformBlockCase.UniformFlags.PRECISION_MEDIUM)));
+ blockB.addUniform(new glsUniformBlockCase.Uniform('b', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.INT_VEC2, glsUniformBlockCase.UniformFlags.PRECISION_LOW)));
+ blockB.addUniform(new glsUniformBlockCase.Uniform('c', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_VEC4, glsUniformBlockCase.UniformFlags.PRECISION_HIGH), glsUniformBlockCase.UniformFlags.UNUSED_BOTH));
+ blockB.addUniform(new glsUniformBlockCase.Uniform('d', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.BOOL, 0)));
+ blockB.setInstanceName('blockB');
+ blockB.setFlags(this.m_flagsB);
+
+ if (this.m_numInstances > 0) {
+ blockA.setArraySize(this.m_numInstances);
+ blockB.setArraySize(this.m_numInstances);
+ }
+ };
+
+ /**
+ * es3fUniformBlockTests.BlockMultiNestedStructCase constructor
+ * @param {string} name The name of the test
+ * @param {string} description The description of the test
+ * @param {number} flagsA
+ * @param {number} flagsB
+ * @param {glsUniformBlockCase.BufferMode} bufferMode
+ * @param {number} numInstances
+ * @constructor
+ * @extends {glsUniformBlockCase.UniformBlockCase}
+ */
+ es3fUniformBlockTests.BlockMultiNestedStructCase = function(name, description, flagsA, flagsB, bufferMode, numInstances) {
+ glsUniformBlockCase.UniformBlockCase.call(this, name, description, bufferMode);
+ this.m_flagsA = flagsA;
+ this.m_flagsB = flagsB;
+ this.m_numInstances = numInstances;
+ };
+
+ es3fUniformBlockTests.BlockMultiNestedStructCase.prototype = Object.create(glsUniformBlockCase.UniformBlockCase.prototype);
+ es3fUniformBlockTests.BlockMultiNestedStructCase.prototype.constructor = es3fUniformBlockTests.BlockMultiNestedStructCase;
+
+ es3fUniformBlockTests.BlockMultiNestedStructCase.prototype.init = function() {
+ /**@type {glsUniformBlockCase.StructType}*/ var typeS = this.m_interface.allocStruct('S');
+ typeS.addMember('a', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_MAT3, glsUniformBlockCase.UniformFlags.PRECISION_LOW));
+ typeS.addMember('b', glsUniformBlockCase.newVarTypeArray(glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.INT_VEC2, glsUniformBlockCase.UniformFlags.PRECISION_MEDIUM), 4));
+ typeS.addMember('c', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_VEC4, glsUniformBlockCase.UniformFlags.PRECISION_HIGH));
+
+ /**@type {glsUniformBlockCase.StructType}*/ var typeT = this.m_interface.allocStruct('T');
+ typeT.addMember('a', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.UINT, glsUniformBlockCase.UniformFlags.PRECISION_MEDIUM), glsUniformBlockCase.UniformFlags.UNUSED_BOTH);
+ typeT.addMember('b', glsUniformBlockCase.newVarTypeStruct(typeS));
+ typeT.addMember('c', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.BOOL_VEC4, 0));
+
+ /** @type {glsUniformBlockCase.UniformBlock} */ var blockA = this.m_interface.allocBlock('BlockA');
+ blockA.addUniform(new glsUniformBlockCase.Uniform('a', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT, glsUniformBlockCase.UniformFlags.PRECISION_HIGH)));
+ blockA.addUniform(new glsUniformBlockCase.Uniform('b', glsUniformBlockCase.newVarTypeStruct(typeS)));
+ blockA.addUniform(new glsUniformBlockCase.Uniform('c', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.UINT_VEC3, glsUniformBlockCase.UniformFlags.PRECISION_LOW), glsUniformBlockCase.UniformFlags.UNUSED_BOTH));
+ blockA.setInstanceName('blockA');
+ blockA.setFlags(this.m_flagsA);
+
+ /** @type {glsUniformBlockCase.UniformBlock} */ var blockB = this.m_interface.allocBlock('BlockB');
+ blockB.addUniform(new glsUniformBlockCase.Uniform('a', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.FLOAT_MAT2, glsUniformBlockCase.UniformFlags.PRECISION_MEDIUM)));
+ blockB.addUniform(new glsUniformBlockCase.Uniform('b', glsUniformBlockCase.newVarTypeStruct(typeT)));
+ blockB.addUniform(new glsUniformBlockCase.Uniform('c', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.BOOL_VEC4, 0), glsUniformBlockCase.UniformFlags.UNUSED_BOTH));
+ blockB.addUniform(new glsUniformBlockCase.Uniform('d', glsUniformBlockCase.newVarTypeBasic(gluShaderUtil.DataType.BOOL, 0)));
+ blockB.setInstanceName('blockB');
+ blockB.setFlags(this.m_flagsB);
+
+ if (this.m_numInstances > 0) {
+ blockA.setArraySize(this.m_numInstances);
+ blockB.setArraySize(this.m_numInstances);
+ }
+ };
+
+ /**
+ * Creates the test hierarchy to be executed.
+ **/
+ es3fUniformBlockTests.init = function() {
+ /** @const @type {tcuTestCase.DeqpTest} */ var testGroup = tcuTestCase.runner.testCases;
+
+ /** @type {Array<gluShaderUtil.DataType>} */
+ var basicTypes = [
+ gluShaderUtil.DataType.FLOAT,
+ gluShaderUtil.DataType.FLOAT_VEC2,
+ gluShaderUtil.DataType.FLOAT_VEC3,
+ gluShaderUtil.DataType.FLOAT_VEC4,
+ gluShaderUtil.DataType.INT,
+ gluShaderUtil.DataType.INT_VEC2,
+ gluShaderUtil.DataType.INT_VEC3,
+ gluShaderUtil.DataType.INT_VEC4,
+ gluShaderUtil.DataType.UINT,
+ gluShaderUtil.DataType.UINT_VEC2,
+ gluShaderUtil.DataType.UINT_VEC3,
+ gluShaderUtil.DataType.UINT_VEC4,
+ gluShaderUtil.DataType.BOOL,
+ gluShaderUtil.DataType.BOOL_VEC2,
+ gluShaderUtil.DataType.BOOL_VEC3,
+ gluShaderUtil.DataType.BOOL_VEC4,
+ gluShaderUtil.DataType.FLOAT_MAT2,
+ gluShaderUtil.DataType.FLOAT_MAT3,
+ gluShaderUtil.DataType.FLOAT_MAT4,
+ gluShaderUtil.DataType.FLOAT_MAT2X3,
+ gluShaderUtil.DataType.FLOAT_MAT2X4,
+ gluShaderUtil.DataType.FLOAT_MAT3X2,
+ gluShaderUtil.DataType.FLOAT_MAT3X4,
+ gluShaderUtil.DataType.FLOAT_MAT4X2,
+ gluShaderUtil.DataType.FLOAT_MAT4X3
+ ];
+
+ /** @type {Array<Object.<string, glsUniformBlockCase.UniformFlags>>} */
+ var precisionFlags = [{ name: 'lowp', flags: glsUniformBlockCase.UniformFlags.PRECISION_LOW }, { name: 'mediump', flags: glsUniformBlockCase.UniformFlags.PRECISION_MEDIUM }, { name: 'highp', flags: glsUniformBlockCase.UniformFlags.PRECISION_HIGH }
+ ];
+
+ /** @type {Array<Object.<string, glsUniformBlockCase.UniformFlags>>} */
+ var layoutFlags = [ /* { name: 'shared', flags: glsUniformBlockCase.UniformFlags.LAYOUT_SHARED }, */
+ /* { name: 'packed', flags: glsUniformBlockCase.UniformFlags.LAYOUT_PACKED }, */ { name: 'std140', flags: glsUniformBlockCase.UniformFlags.LAYOUT_STD140 }
+ ];
+
+ /** @type {Array<Object.<string, glsUniformBlockCase.UniformFlags>>} */
+ var matrixFlags = [{ name: 'row_major', flags: glsUniformBlockCase.UniformFlags.LAYOUT_ROW_MAJOR }, { name: 'column_major', flags: glsUniformBlockCase.UniformFlags.LAYOUT_COLUMN_MAJOR }
+ ];
+
+ /** @type {Array<Object.<string, glsUniformBlockCase.UniformFlags>>} */
+ var bufferModes = [{ name: 'per_block_buffer', mode: glsUniformBlockCase.BufferMode.BUFFERMODE_PER_BLOCK }, { name: 'single_buffer', mode: glsUniformBlockCase.BufferMode.BUFFERMODE_SINGLE }
+ ];
+
+ // ubo.single_basic_type
+ /** @type {tcuTestCase.DeqpTest} */
+ var singleBasicTypeGroup = tcuTestCase.newTest('single_basic_type', 'Single basic variable in single buffer');
+
+ testGroup.addChild(singleBasicTypeGroup);
+
+ /** @type {tcuTestCase.DeqpTest} */
+ var layoutGroup;
+ /** @type {gluShaderUtil.DataType} */
+ var type;
+ /** @type {string} */
+ var typeName;
+ /** @type {tcuTestCase.DeqpTest} */
+ var modeGroup;
+ /** @type {string} */
+ var baseName;
+ /** @type {number} */
+ var baseFlags;
+
+ for (var layoutFlagNdx = 0; layoutFlagNdx < layoutFlags.length; layoutFlagNdx++) {
+
+ layoutGroup = tcuTestCase.newTest(layoutFlags[layoutFlagNdx].name, '', null);
+ singleBasicTypeGroup.addChild(layoutGroup);
+
+ for (var basicTypeNdx = 0; basicTypeNdx < basicTypes.length; basicTypeNdx++) {
+ type = basicTypes[basicTypeNdx];
+ typeName = gluShaderUtil.getDataTypeName(type);
+
+ if (gluShaderUtil.isDataTypeBoolOrBVec(type))
+ es3fUniformBlockTests.createBlockBasicTypeCases(layoutGroup, typeName, glsUniformBlockCase.newVarTypeBasic(type, 0), layoutFlags[layoutFlagNdx].flags);
+ else {
+ for (var precNdx = 0; precNdx < precisionFlags.length; precNdx++)
+ es3fUniformBlockTests.createBlockBasicTypeCases(layoutGroup, precisionFlags[precNdx].name + '_' + typeName,
+ glsUniformBlockCase.newVarTypeBasic(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags);
+ }
+
+ if (gluShaderUtil.isDataTypeMatrix(type)) {
+ for (var matFlagNdx = 0; matFlagNdx < matrixFlags.length; matFlagNdx++) {
+ for (var precNdx = 0; precNdx < precisionFlags.length; precNdx++)
+ es3fUniformBlockTests.createBlockBasicTypeCases(layoutGroup, matrixFlags[matFlagNdx].name + '_' + precisionFlags[precNdx].name + '_' + typeName,
+ glsUniformBlockCase.newVarTypeBasic(type, precisionFlags[precNdx].flags), layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags);
+ }
+ }
+ }
+ }
+ bufferedLogToConsole('ubo.single_basic_type: Tests created');
+
+ // ubo.single_basic_array
+ /** @type {tcuTestCase.DeqpTest} */
+ var singleBasicArrayGroup = tcuTestCase.newTest('single_basic_array', 'Single basic array variable in single buffer');
+ testGroup.addChild(singleBasicArrayGroup);
+
+ for (var layoutFlagNdx = 0; layoutFlagNdx < layoutFlags.length; layoutFlagNdx++) {
+ layoutGroup = tcuTestCase.newTest(layoutFlags[layoutFlagNdx].name, '', null);
+ singleBasicArrayGroup.addChild(layoutGroup);
+
+ for (var basicTypeNdx = 0; basicTypeNdx < basicTypes.length; basicTypeNdx++) {
+ type = basicTypes[basicTypeNdx];
+ typeName = gluShaderUtil.getDataTypeName(type);
+ /** @type {number} */ var arraySize = 3;
+
+ es3fUniformBlockTests.createBlockBasicTypeCases(layoutGroup, typeName,
+ glsUniformBlockCase.newVarTypeArray(glsUniformBlockCase.newVarTypeBasic(type, gluShaderUtil.isDataTypeBoolOrBVec(type) ? 0 : glsUniformBlockCase.UniformFlags.PRECISION_HIGH), arraySize),
+ layoutFlags[layoutFlagNdx].flags);
+
+ if (gluShaderUtil.isDataTypeMatrix(type)) {
+ for (var matFlagNdx = 0; matFlagNdx < matrixFlags.length; matFlagNdx++)
+ es3fUniformBlockTests.createBlockBasicTypeCases(layoutGroup, matrixFlags[matFlagNdx].name + '_' + typeName,
+ glsUniformBlockCase.newVarTypeArray(glsUniformBlockCase.newVarTypeBasic(type, glsUniformBlockCase.UniformFlags.PRECISION_HIGH), arraySize),
+ layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags);
+ }
+ }
+ }
+ bufferedLogToConsole('ubo.single_basic_array: Tests created');
+
+ // ubo.single_struct
+ /** @type {tcuTestCase.DeqpTest} */
+ var singleStructGroup = tcuTestCase.newTest('single_struct', 'Single struct in uniform block');
+ testGroup.addChild(singleStructGroup);
+
+ for (var modeNdx = 0; modeNdx < bufferModes.length; modeNdx++) {
+ modeGroup = tcuTestCase.newTest(bufferModes[modeNdx].name, '');
+ singleStructGroup.addChild(modeGroup);
+
+ for (var layoutFlagNdx = 0; layoutFlagNdx < layoutFlags.length; layoutFlagNdx++) {
+ for (var isArray = 0; isArray < 2; isArray++) {
+ baseName = layoutFlags[layoutFlagNdx].name;
+ baseFlags = layoutFlags[layoutFlagNdx].flags;
+
+ if (bufferModes[modeNdx].mode == glsUniformBlockCase.BufferMode.BUFFERMODE_SINGLE && isArray == 0)
+ continue; // Doesn't make sense to add this variant.
+
+ if (isArray)
+ baseName += '_instance_array';
+
+ modeGroup.addChild(new es3fUniformBlockTests.BlockSingleStructCase(baseName + '_vertex', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+ modeGroup.addChild(new es3fUniformBlockTests.BlockSingleStructCase(baseName + '_fragment', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+
+ if (!(baseFlags & glsUniformBlockCase.UniformFlags.LAYOUT_PACKED))
+ modeGroup.addChild(new es3fUniformBlockTests.BlockSingleStructCase(baseName + '_both', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+ }
+ }
+ }
+ bufferedLogToConsole('ubo.single_struct: Tests created');
+
+ // ubo.single_struct_array
+ /** @type {tcuTestCase.DeqpTest} */
+ var singleStructArrayGroup = tcuTestCase.newTest('single_struct_array', 'Struct array in one uniform block');
+ testGroup.addChild(singleStructArrayGroup);
+
+ for (var modeNdx = 0; modeNdx < bufferModes.length; modeNdx++) {
+ modeGroup = tcuTestCase.newTest(bufferModes[modeNdx].name, '');
+ singleStructArrayGroup.addChild(modeGroup);
+
+ for (var layoutFlagNdx = 0; layoutFlagNdx < layoutFlags.length; layoutFlagNdx++) {
+ for (var isArray = 0; isArray < 2; isArray++) {
+ baseName = layoutFlags[layoutFlagNdx].name;
+ baseFlags = layoutFlags[layoutFlagNdx].flags;
+
+ if (bufferModes[modeNdx].mode == glsUniformBlockCase.BufferMode.BUFFERMODE_SINGLE && isArray == 0)
+ continue; // Doesn't make sense to add this variant.
+
+ if (isArray)
+ baseName += '_instance_array';
+
+ modeGroup.addChild(new es3fUniformBlockTests.BlockSingleStructArrayCase(baseName + '_vertex', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+ modeGroup.addChild(new es3fUniformBlockTests.BlockSingleStructArrayCase(baseName + '_fragment', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+
+ if (!(baseFlags & glsUniformBlockCase.UniformFlags.LAYOUT_PACKED))
+ modeGroup.addChild(new es3fUniformBlockTests.BlockSingleStructArrayCase(baseName + '_both', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+ }
+ }
+ }
+ bufferedLogToConsole('ubo.single_struct_array: Tests created');
+
+ // ubo.single_nested_struct
+ /** @type {tcuTestCase.DeqpTest} */
+ var singleNestedStructGroup = tcuTestCase.newTest('single_nested_struct', 'Nested struct in one uniform block');
+ testGroup.addChild(singleNestedStructGroup);
+
+ for (var modeNdx = 0; modeNdx < bufferModes.length; modeNdx++) {
+ modeGroup = tcuTestCase.newTest(bufferModes[modeNdx].name, '');
+ singleNestedStructGroup.addChild(modeGroup);
+
+ for (var layoutFlagNdx = 0; layoutFlagNdx < layoutFlags.length; layoutFlagNdx++) {
+ for (var isArray = 0; isArray < 2; isArray++) {
+ baseName = layoutFlags[layoutFlagNdx].name;
+ baseFlags = layoutFlags[layoutFlagNdx].flags;
+
+ if (bufferModes[modeNdx].mode == glsUniformBlockCase.BufferMode.BUFFERMODE_SINGLE && isArray == 0)
+ continue; // Doesn't make sense to add this variant.
+
+ if (isArray)
+ baseName += '_instance_array';
+
+ modeGroup.addChild(new es3fUniformBlockTests.BlockSingleNestedStructCase(baseName + '_vertex', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+ modeGroup.addChild(new es3fUniformBlockTests.BlockSingleNestedStructCase(baseName + '_fragment', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+
+ if (!(baseFlags & glsUniformBlockCase.UniformFlags.LAYOUT_PACKED))
+ modeGroup.addChild(new es3fUniformBlockTests.BlockSingleNestedStructCase(baseName + '_both', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+ }
+ }
+ }
+ bufferedLogToConsole('ubo.single_nested_struct: Tests created');
+
+ // ubo.single_nested_struct_array
+ /** @type {tcuTestCase.DeqpTest} */
+ var singleNestedStructArrayGroup = tcuTestCase.newTest('single_nested_struct_array', 'Nested struct array in one uniform block');
+ testGroup.addChild(singleNestedStructArrayGroup);
+
+ for (var modeNdx = 0; modeNdx < bufferModes.length; modeNdx++) {
+ modeGroup = tcuTestCase.newTest(bufferModes[modeNdx].name, '');
+ singleNestedStructArrayGroup.addChild(modeGroup);
+
+ for (var layoutFlagNdx = 0; layoutFlagNdx < layoutFlags.length; layoutFlagNdx++) {
+ for (var isArray = 0; isArray < 2; isArray++) {
+ baseName = layoutFlags[layoutFlagNdx].name;
+ baseFlags = layoutFlags[layoutFlagNdx].flags;
+
+ if (bufferModes[modeNdx].mode == glsUniformBlockCase.BufferMode.BUFFERMODE_SINGLE && isArray == 0)
+ continue; // Doesn't make sense to add this variant.
+
+ if (isArray)
+ baseName += '_instance_array';
+
+ modeGroup.addChild(new es3fUniformBlockTests.BlockSingleNestedStructArrayCase(baseName + '_vertex', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+ modeGroup.addChild(new es3fUniformBlockTests.BlockSingleNestedStructArrayCase(baseName + '_fragment', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+
+ if (!(baseFlags & glsUniformBlockCase.UniformFlags.LAYOUT_PACKED))
+ modeGroup.addChild(new es3fUniformBlockTests.BlockSingleNestedStructArrayCase(baseName + '_both', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+ }
+ }
+ }
+ bufferedLogToConsole('ubo.single_nested_struct_array: Tests created');
+
+ // ubo.instance_array_basic_type
+ /** @type {tcuTestCase.DeqpTest} */
+ var instanceArrayBasicTypeGroup = tcuTestCase.newTest('instance_array_basic_type', 'Single basic variable in instance array');
+ testGroup.addChild(instanceArrayBasicTypeGroup);
+
+ for (var layoutFlagNdx = 0; layoutFlagNdx < layoutFlags.length; layoutFlagNdx++) {
+ layoutGroup = tcuTestCase.newTest(layoutFlags[layoutFlagNdx].name, '');
+ instanceArrayBasicTypeGroup.addChild(layoutGroup);
+
+ for (var basicTypeNdx = 0; basicTypeNdx < basicTypes.length; basicTypeNdx++) {
+ type = basicTypes[basicTypeNdx];
+ typeName = gluShaderUtil.getDataTypeName(type);
+ /** @type {number} */ var numInstances = 3;
+
+ es3fUniformBlockTests.createBlockBasicTypeCases(layoutGroup, typeName,
+ glsUniformBlockCase.newVarTypeBasic(type, gluShaderUtil.isDataTypeBoolOrBVec(type) ? 0 : glsUniformBlockCase.UniformFlags.PRECISION_HIGH),
+ layoutFlags[layoutFlagNdx].flags, numInstances);
+
+ if (gluShaderUtil.isDataTypeMatrix(type)) {
+ for (var matFlagNdx = 0; matFlagNdx < matrixFlags.length; matFlagNdx++)
+ es3fUniformBlockTests.createBlockBasicTypeCases(layoutGroup, matrixFlags[matFlagNdx].name + '_' + typeName,
+ glsUniformBlockCase.newVarTypeBasic(type, glsUniformBlockCase.UniformFlags.PRECISION_HIGH), layoutFlags[layoutFlagNdx].flags | matrixFlags[matFlagNdx].flags,
+ numInstances);
+ }
+ }
+ }
+ bufferedLogToConsole('ubo.instance_array_basic_type: Tests created');
+
+ // ubo.multi_basic_types
+ /** @type {tcuTestCase.DeqpTest} */
+ var multiBasicTypesGroup = tcuTestCase.newTest('multi_basic_types', 'Multiple buffers with basic types');
+ testGroup.addChild(multiBasicTypesGroup);
+
+ for (var modeNdx = 0; modeNdx < bufferModes.length; modeNdx++) {
+ modeGroup = tcuTestCase.newTest(bufferModes[modeNdx].name, '');
+ multiBasicTypesGroup.addChild(modeGroup);
+
+ for (var layoutFlagNdx = 0; layoutFlagNdx < layoutFlags.length; layoutFlagNdx++) {
+ for (var isArray = 0; isArray < 2; isArray++) {
+ baseName = layoutFlags[layoutFlagNdx].name;
+ baseFlags = layoutFlags[layoutFlagNdx].flags;
+
+ if (isArray)
+ baseName += '_instance_array';
+
+ modeGroup.addChild(new es3fUniformBlockTests.BlockMultiBasicTypesCase(baseName + '_vertex', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX, baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+ modeGroup.addChild(new es3fUniformBlockTests.BlockMultiBasicTypesCase(baseName + '_fragment', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+
+ if (!(baseFlags & glsUniformBlockCase.UniformFlags.LAYOUT_PACKED))
+ modeGroup.addChild(new es3fUniformBlockTests.BlockMultiBasicTypesCase(baseName + '_both', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+
+ modeGroup.addChild(new es3fUniformBlockTests.BlockMultiBasicTypesCase(baseName + '_mixed', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX, baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+ }
+ }
+ }
+ bufferedLogToConsole('ubo.multi_basic_types: Tests created');
+
+ // ubo.multi_nested_struct
+ /** @type {tcuTestCase.DeqpTest} */
+ var multiNestedStructGroup = tcuTestCase.newTest('multi_nested_struct', 'Multiple buffers with basic types');
+ testGroup.addChild(multiNestedStructGroup);
+
+ for (var modeNdx = 0; modeNdx < bufferModes.length; modeNdx++) {
+ modeGroup = tcuTestCase.newTest(bufferModes[modeNdx].name, '');
+ multiNestedStructGroup.addChild(modeGroup);
+
+ for (var layoutFlagNdx = 0; layoutFlagNdx < layoutFlags.length; layoutFlagNdx++) {
+ for (var isArray = 0; isArray < 2; isArray++) {
+ baseName = layoutFlags[layoutFlagNdx].name;
+ baseFlags = layoutFlags[layoutFlagNdx].flags;
+
+ if (isArray)
+ baseName += '_instance_array';
+
+ modeGroup.addChild(new es3fUniformBlockTests.BlockMultiNestedStructCase(baseName + '_vertex', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX, baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+ modeGroup.addChild(new es3fUniformBlockTests.BlockMultiNestedStructCase(baseName + '_fragment', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+
+ if (!(baseFlags & glsUniformBlockCase.UniformFlags.LAYOUT_PACKED))
+ modeGroup.addChild(new es3fUniformBlockTests.BlockMultiNestedStructCase(baseName + '_both', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+
+ modeGroup.addChild(new es3fUniformBlockTests.BlockMultiNestedStructCase(baseName + '_mixed', '', baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_VERTEX, baseFlags | glsUniformBlockCase.UniformFlags.DECLARE_FRAGMENT, bufferModes[modeNdx].mode, isArray ? 3 : 0));
+ }
+ }
+ }
+ bufferedLogToConsole('ubo.multi_nested_struct: Tests created');
+
+ /* ubo.random */
+ /** @type {number} */ var allShaders = glsRandomUniformBlockCase.FeatureBits.FEATURE_VERTEX_BLOCKS | glsRandomUniformBlockCase.FeatureBits.FEATURE_FRAGMENT_BLOCKS | glsRandomUniformBlockCase.FeatureBits.FEATURE_SHARED_BLOCKS;
+ /** @type {number} */ var allLayouts = glsRandomUniformBlockCase.FeatureBits.FEATURE_STD140_LAYOUT;
+ /** @type {number} */ var allBasicTypes = glsRandomUniformBlockCase.FeatureBits.FEATURE_VECTORS | glsRandomUniformBlockCase.FeatureBits.FEATURE_MATRICES;
+ /** @type {number} */ var unused = glsRandomUniformBlockCase.FeatureBits.FEATURE_UNUSED_MEMBERS | glsRandomUniformBlockCase.FeatureBits.FEATURE_UNUSED_UNIFORMS;
+ /** @type {number} */ var matFlags = glsRandomUniformBlockCase.FeatureBits.FEATURE_MATRIX_LAYOUT;
+ /** @type {number} */ var allFeatures = (~glsRandomUniformBlockCase.FeatureBits.FEATURE_ARRAYS_OF_ARRAYS & 0xFFFF);
+
+ /** @type {tcuTestCase.DeqpTest} */
+ var randomGroup = tcuTestCase.newTest('random', 'Random Uniform Block cases');
+ testGroup.addChild(randomGroup);
+
+ // Basic types.
+ es3fUniformBlockTests.createRandomCaseGroup(randomGroup, 'scalar_types', 'Scalar types only, per-block buffers', glsUniformBlockCase.BufferMode.BUFFERMODE_PER_BLOCK, allShaders | allLayouts | unused, 25, 0);
+ es3fUniformBlockTests.createRandomCaseGroup(randomGroup, 'vector_types', 'Scalar and vector types only, per-block buffers', glsUniformBlockCase.BufferMode.BUFFERMODE_PER_BLOCK, allShaders | allLayouts | unused | glsRandomUniformBlockCase.FeatureBits.FEATURE_VECTORS, 25, 25);
+ es3fUniformBlockTests.createRandomCaseGroup(randomGroup, 'basic_types', 'All basic types, per-block buffers', glsUniformBlockCase.BufferMode.BUFFERMODE_PER_BLOCK, allShaders | allLayouts | unused | allBasicTypes | matFlags, 25, 50);
+ es3fUniformBlockTests.createRandomCaseGroup(randomGroup, 'basic_arrays', 'Arrays, per-block buffers', glsUniformBlockCase.BufferMode.BUFFERMODE_PER_BLOCK, allShaders | allLayouts | unused | allBasicTypes | matFlags | glsRandomUniformBlockCase.FeatureBits.FEATURE_ARRAYS, 25, 50);
+
+ es3fUniformBlockTests.createRandomCaseGroup(randomGroup, 'basic_instance_arrays', 'Basic instance arrays, per-block buffers', glsUniformBlockCase.BufferMode.BUFFERMODE_PER_BLOCK, allShaders | allLayouts | unused | allBasicTypes | matFlags | glsRandomUniformBlockCase.FeatureBits.FEATURE_INSTANCE_ARRAYS, 25, 75);
+ es3fUniformBlockTests.createRandomCaseGroup(randomGroup, 'nested_structs', 'Nested structs, per-block buffers', glsUniformBlockCase.BufferMode.BUFFERMODE_PER_BLOCK, allShaders | allLayouts | unused | allBasicTypes | matFlags | glsRandomUniformBlockCase.FeatureBits.FEATURE_STRUCTS, 25, 100);
+ es3fUniformBlockTests.createRandomCaseGroup(randomGroup, 'nested_structs_arrays', 'Nested structs, arrays, per-block buffers', glsUniformBlockCase.BufferMode.BUFFERMODE_PER_BLOCK, allShaders | allLayouts | unused | allBasicTypes | matFlags | glsRandomUniformBlockCase.FeatureBits.FEATURE_STRUCTS | glsRandomUniformBlockCase.FeatureBits.FEATURE_ARRAYS, 25, 150);
+ es3fUniformBlockTests.createRandomCaseGroup(randomGroup, 'nested_structs_instance_arrays', 'Nested structs, instance arrays, per-block buffers', glsUniformBlockCase.BufferMode.BUFFERMODE_PER_BLOCK, allShaders | allLayouts | unused | allBasicTypes | matFlags | glsRandomUniformBlockCase.FeatureBits.FEATURE_STRUCTS | glsRandomUniformBlockCase.FeatureBits.FEATURE_INSTANCE_ARRAYS, 25, 125);
+ es3fUniformBlockTests.createRandomCaseGroup(randomGroup, 'nested_structs_arrays_instance_arrays', 'Nested structs, instance arrays, per-block buffers', glsUniformBlockCase.BufferMode.BUFFERMODE_PER_BLOCK, allShaders | allLayouts | unused | allBasicTypes | matFlags | glsRandomUniformBlockCase.FeatureBits.FEATURE_STRUCTS | glsRandomUniformBlockCase.FeatureBits.FEATURE_ARRAYS | glsRandomUniformBlockCase.FeatureBits.FEATURE_INSTANCE_ARRAYS, 25, 175);
+
+ // Disabled: WebGL does not support shared or packed uniform buffers.
+ //es3fUniformBlockTests.createRandomCaseGroup(randomGroup, 'all_per_block_buffers', 'All random features, per-block buffers', glsUniformBlockCase.BufferMode.BUFFERMODE_PER_BLOCK, allFeatures, 50, 200);
+ //es3fUniformBlockTests.createRandomCaseGroup(randomGroup, 'all_shared_buffer', 'All random features, shared buffer', glsUniformBlockCase.BufferMode.BUFFERMODE_SINGLE, allFeatures, 50, 250);
+ bufferedLogToConsole('ubo.random: Tests created');
+ };
+
+ /**
+ * Create and execute the test cases
+ */
+ es3fUniformBlockTests.run = function(range) {
+ //Set up Test Root parameters
+ var testName = 'ubo';
+ var testDescription = 'Uniform Block Tests';
+ var state = tcuTestCase.runner;
+
+ state.setRoot(tcuTestCase.newTest(testName, testDescription, null));
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ //Create test cases
+ es3fUniformBlockTests.init();
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fUniformBlockTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fVertexArrayObjectTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fVertexArrayObjectTests.js
new file mode 100644
index 0000000000..6ee46995ca
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fVertexArrayObjectTests.js
@@ -0,0 +1,875 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the 'License');
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an 'AS IS' BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fVertexArrayObjectTests');
+goog.require('framework.common.tcuImageCompare');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.delibs.debase.deUtil');
+goog.require('framework.opengl.gluShaderProgram');
+
+goog.scope(function() {
+var es3fVertexArrayObjectTests = functional.gles3.es3fVertexArrayObjectTests;
+var tcuTestCase = framework.common.tcuTestCase;
+var deRandom = framework.delibs.debase.deRandom;
+var deString = framework.delibs.debase.deString;
+var gluShaderProgram = framework.opengl.gluShaderProgram;
+var tcuSurface = framework.common.tcuSurface;
+var tcuImageCompare = framework.common.tcuImageCompare;
+var deUtil = framework.delibs.debase.deUtil;
+
+/**
+ * @constructor
+ */
+es3fVertexArrayObjectTests.Attribute = function() {
+ this.enabled = false;
+ this.size = 1;
+ this.stride = 0;
+ this.type = gl.FLOAT;
+ this.integer = false;
+ this.divisor = 0;
+ this.offset = 0;
+ this.normalized = false;
+ this.bufferNdx = 0;
+};
+
+/**
+ * @constructor
+ * @struct
+ */
+es3fVertexArrayObjectTests.VertexArrayState = function() {
+ this.attributes = [];
+ this.elementArrayBuffer = 0;
+};
+
+/**
+ * @constructor
+ * @struct
+ */
+es3fVertexArrayObjectTests.BufferSpec = function(count, size, componentCount, stride, offset, type, intRangeMin, intRangeMax, floatRangeMin, floatRangeMax) {
+ this.count = count;
+ this.size = size;
+ this.componentCount = componentCount;
+ this.stride = stride;
+ this.offset = offset;
+
+ this.type = type;
+
+ this.intRangeMin = intRangeMin;
+ this.intRangeMax = intRangeMax;
+
+ this.floatRangeMin = floatRangeMin;
+ this.floatRangeMax = floatRangeMax;
+};
+
+/**
+ * @constructor
+ */
+es3fVertexArrayObjectTests.Spec = function() {
+ this.count = -1;
+ this.instances = -1;
+ this.useDrawElements = false;
+ this.indexType = gl.NONE;
+ this.indexOffset = -1;
+ this.indexRangeMin = -1;
+ this.indexRangeMax = -1;
+ this.indexCount = -1;
+ this.buffers = [];
+};
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {es3fVertexArrayObjectTests.Spec} spec
+ * @param {string} name
+ * @param {string} description
+ */
+es3fVertexArrayObjectTests.VertexArrayObjectTest = function(spec, name, description) {
+ tcuTestCase.DeqpTest.call(this, name, description);
+ this.m_spec = spec;
+ this.m_random = new deRandom.Random(deString.deStringHash(name));
+ /** @type Array<WebGLBuffer>} */ this.m_buffers = [];
+ // mapping 0 -> null object
+ this.m_buffers.push(null);
+};
+
+es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.constructor = es3fVertexArrayObjectTests.VertexArrayObjectTest;
+
+es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.init = function() {
+ this.m_vaoProgram = this.createProgram(this.m_spec.vao);
+ // m_log << tcu::TestLog::Message << "Program used with Vertex Array Object" << tcu::TestLog::EndMessage;
+ // m_log << *m_vaoProgram;
+ this.m_stateProgram = this.createProgram(this.m_spec.state);
+ // m_log << tcu::TestLog::Message << "Program used with Vertex Array State" << tcu::TestLog::EndMessage;
+ // m_log << *m_stateProgram;
+
+ if (!this.m_vaoProgram.isOk() || !this.m_stateProgram.isOk())
+ testFailedOptions('Failed to compile shaders', true);
+};
+
+/**
+ * @param {number} target GL target
+ * @param {number} index Index of the buffer to bind
+ */
+es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.bindBuffer = function(target, index) {
+ if (typeof this.m_buffers[index] === 'undefined') {
+ var data = this.createRandomBufferData(this.m_spec.buffers[index - 1]);
+ var buffer = gl.createBuffer();
+ this.m_buffers[index] = buffer;
+
+ gl.bindBuffer(target, buffer);
+ gl.bufferData(target, data, gl.DYNAMIC_DRAW);
+ gl.bindBuffer(target, null);
+ }
+
+ gl.bindBuffer(target, this.m_buffers[index]);
+};
+
+/**
+ * @param {es3fVertexArrayObjectTests.BufferSpec} buffer
+ */
+es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.createRandomBufferData = function(buffer) {
+ var typedArray;
+ switch (buffer.type) {
+ case gl.FLOAT: typedArray = Float32Array; break;
+ case gl.INT: typedArray = Int32Array; break;
+ case gl.UNSIGNED_INT: typedArray = Uint32Array; break;
+ case gl.SHORT: typedArray = Int16Array; break;
+ case gl.UNSIGNED_SHORT: typedArray = Uint16Array; break;
+ case gl.BYTE: typedArray = Int8Array; break;
+ case gl.UNSIGNED_BYTE: typedArray = Uint8Array; break;
+ default:
+ throw new Error('Invalid type: ' + buffer.type);
+ }
+
+ var raw = new ArrayBuffer(buffer.size);
+ var stride;
+
+ if (buffer.stride != 0) {
+ stride = buffer.stride;
+ } else {
+ switch (buffer.type) {
+ case gl.FLOAT: stride = buffer.componentCount * 4; break;
+ case gl.INT: stride = buffer.componentCount * 4; break;
+ case gl.UNSIGNED_INT: stride = buffer.componentCount * 4; break;
+ case gl.SHORT: stride = buffer.componentCount * 2; break;
+ case gl.UNSIGNED_SHORT: stride = buffer.componentCount * 2; break;
+ case gl.BYTE: stride = buffer.componentCount * 1; break;
+ case gl.UNSIGNED_BYTE: stride = buffer.componentCount * 1; break;
+ }
+ }
+
+ var offset = 0;
+
+ for (var pos = 0; pos < buffer.count; pos++) {
+ var data = new typedArray(raw, offset, buffer.componentCount);
+ for (var componentNdx = 0; componentNdx < buffer.componentCount; componentNdx++) {
+ switch (buffer.type) {
+ case gl.FLOAT: {
+ data[componentNdx] = this.m_random.getFloat(buffer.floatRangeMin, buffer.floatRangeMax);
+ break;
+ }
+ default: {
+ data[componentNdx] = this.m_random.getInt(buffer.intRangeMin, buffer.intRangeMax);
+ }
+ }
+ }
+
+ offset += stride;
+ }
+
+ return new typedArray(raw);
+};
+
+/**
+ * @param {es3fVertexArrayObjectTests.VertexArrayState} state
+ */
+es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.createProgram = function(state) {
+ var vtx = '';
+ var value = '';
+
+ vtx += '#version 300 es\n';
+
+ for (var attribNdx = 0; attribNdx < state.attributes.length; attribNdx++) {
+ if (state.attributes[attribNdx].integer)
+ vtx += 'layout(location = ' + attribNdx + ') in mediump ivec4 a_attrib' + attribNdx + ';\n';
+ else
+ vtx += 'layout(location = ' + attribNdx + ') in mediump vec4 a_attrib' + attribNdx + ';\n';
+
+ if (state.attributes[attribNdx].integer) {
+ var scale = 0.0;
+
+ // TODO: Should it be state.attributes[attribNdx].type?
+ switch (state.attributes[attribNdx].type) {
+ case gl.SHORT: scale = (1.0 / ((1 << 14) - 1)); break;
+ case gl.UNSIGNED_SHORT: scale = (1.0 / ((1 << 15) - 1)); break;
+ case gl.INT: scale = (1.0 / ((1 << 30) - 1)); break;
+ case gl.UNSIGNED_INT: scale = (1.0 / ((1 << 31) - 1)); break;
+ case gl.BYTE: scale = (1.0 / ((1 << 6) - 1)); break;
+ case gl.UNSIGNED_BYTE: scale = (1.0 / ((1 << 7) - 1)); break;
+
+ default:
+ throw new Error('Invalid type: ' + state.attributes[0].type);
+ }
+ value += (attribNdx != 0 ? ' + ' : '') + scale + ' * vec4(a_attrib' + attribNdx + ')';
+ } else if (state.attributes[attribNdx].type != gl.FLOAT && !state.attributes[attribNdx].normalized) {
+ var scale = 0.0;
+
+ switch (state.attributes[attribNdx].type) {
+ case gl.SHORT: scale = (0.5 / ((1 << 14) - 1)); break;
+ case gl.UNSIGNED_SHORT: scale = (0.5 / ((1 << 15) - 1)); break;
+ case gl.INT: scale = (0.5 / ((1 << 30) - 1)); break;
+ case gl.UNSIGNED_INT: scale = (0.5 / ((1 << 31) - 1)); break;
+ case gl.BYTE: scale = (0.5 / ((1 << 6) - 1)); break;
+ case gl.UNSIGNED_BYTE: scale = (0.5 / ((1 << 7) - 1)); break;
+
+ default:
+ throw new Error('Invalid type: ' + state.attributes[0].type);
+ }
+ value += (attribNdx != 0 ? ' + ' : '') + scale + ' * a_attrib' + attribNdx;
+ } else
+ value += (attribNdx != 0 ? ' + ' : '') + 'a_attrib' + attribNdx;
+ }
+
+ vtx +=
+ 'out mediump vec4 v_value;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ '\tv_value = ' + value + ';\n';
+
+ if (state.attributes[0].integer) {
+ var scale = 0.0;
+
+ switch (state.attributes[0].type) {
+ case gl.SHORT: scale = (1.0 / ((1 << 14) - 1)); break;
+ case gl.UNSIGNED_SHORT: scale = (1.0 / ((1 << 15) - 1)); break;
+ case gl.INT: scale = (1.0 / ((1 << 30) - 1)); break;
+ case gl.UNSIGNED_INT: scale = (1.0 / ((1 << 31) - 1)); break;
+ case gl.BYTE: scale = (1.0 / ((1 << 6) - 1)); break;
+ case gl.UNSIGNED_BYTE: scale = (1.0 / ((1 << 7) - 1)); break;
+
+ default:
+ throw new Error('Invalid type: ' + state.attributes[0].type);
+ }
+
+ vtx +=
+ '\tgl_Position = vec4(' + scale + ' * ' + 'vec3(a_attrib0.xyz), 1.0);\n' +
+ '}';
+ } else {
+ if (state.attributes[0].normalized || state.attributes[0].type == gl.FLOAT) {
+ vtx +=
+ '\tgl_Position = vec4(a_attrib0.xyz, 1.0);\n' +
+ '}';
+ } else {
+ var scale = 0.0;
+
+ switch (state.attributes[0].type) {
+ case gl.SHORT: scale = (1.0 / ((1 << 14) - 1)); break;
+ case gl.UNSIGNED_SHORT: scale = (1.0 / ((1 << 15) - 1)); break;
+ case gl.INT: scale = (1.0 / ((1 << 30) - 1)); break;
+ case gl.UNSIGNED_INT: scale = (1.0 / ((1 << 31) - 1)); break;
+ case gl.BYTE: scale = (1.0 / ((1 << 6) - 1)); break;
+ case gl.UNSIGNED_BYTE: scale = (1.0 / ((1 << 7) - 1)); break;
+
+ default:
+ throw new Error('Invalid type: ' + state.attributes[0].type);
+ }
+
+ scale *= 0.5;
+
+ vtx +=
+ '\tgl_Position = vec4(' + scale + ' * ' + 'a_attrib0.xyz, 1.0);\n' +
+ '}';
+ }
+ }
+
+ var fragmentShader =
+ '#version 300 es\n' +
+ 'in mediump vec4 v_value;\n' +
+ 'layout(location = 0) out mediump vec4 fragColor;\n' +
+ 'void main (void)\n' +
+ '{\n' +
+ '\tfragColor = vec4(v_value.xyz, 1.0);\n' +
+ '}';
+
+ return new gluShaderProgram.ShaderProgram(gl, gluShaderProgram.makeVtxFragSources(vtx, fragmentShader));
+};
+
+/**
+ * @param {es3fVertexArrayObjectTests.VertexArrayState} state
+ */
+es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.setState = function(state) {
+ this.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, state.elementArrayBuffer);
+
+ for (var attribNdx = 0; attribNdx < state.attributes.length; attribNdx++) {
+ this.bindBuffer(gl.ARRAY_BUFFER, state.attributes[attribNdx].bufferNdx);
+ if (state.attributes[attribNdx].enabled)
+ gl.enableVertexAttribArray(attribNdx);
+ else
+ gl.disableVertexAttribArray(attribNdx);
+
+ if (state.attributes[attribNdx].integer)
+ gl.vertexAttribIPointer(attribNdx, state.attributes[attribNdx].size, state.attributes[attribNdx].type, state.attributes[attribNdx].stride, state.attributes[attribNdx].offset);
+ else
+ gl.vertexAttribPointer(attribNdx, state.attributes[attribNdx].size, state.attributes[attribNdx].type, state.attributes[attribNdx].normalized, state.attributes[attribNdx].stride, state.attributes[attribNdx].offset);
+
+ gl.vertexAttribDivisor(attribNdx, state.attributes[attribNdx].divisor);
+ }
+};
+
+/**
+ * @param {es3fVertexArrayObjectTests.VertexArrayState} state
+ */
+es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.makeDrawCall = function(state) {
+ gl.clearColor(0.7, 0.7, 0.7, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ var spec = this.m_spec;
+
+ if (spec.useDrawElements) {
+ if (spec.instances == 0)
+ gl.drawElements(gl.TRIANGLES, spec.count, spec.indexType, spec.indexOffset);
+ else
+ gl.drawElementsInstanced(gl.TRIANGLES, spec.count, spec.indexType, spec.indexOffset, spec.instances);
+ } else {
+ if (spec.instances == 0)
+ gl.drawArrays(gl.TRIANGLES, 0, spec.count);
+ else
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, spec.count, spec.instances);
+ }
+};
+
+/**
+ * @param {tcuSurface.Surface} vaoResult
+ * @param {tcuSurface.Surface} defaultResult
+ */
+es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.render = function(vaoResult, defaultResult) {
+ var vao = gl.createVertexArray();
+
+ gl.bindVertexArray(vao);
+ this.setState(this.m_spec.vao);
+ gl.bindVertexArray(null);
+
+ this.setState(this.m_spec.state);
+
+ gl.bindVertexArray(vao);
+ gl.useProgram(this.m_vaoProgram.getProgram());
+ this.makeDrawCall(this.m_spec.vao);
+ vaoResult.readViewport();
+ this.setState(this.m_spec.vao);
+ gl.bindVertexArray(null);
+
+ gl.useProgram(this.m_stateProgram.getProgram());
+ this.makeDrawCall(this.m_spec.state);
+ defaultResult.readViewport();
+
+ gl.deleteVertexArray(vao);
+};
+
+/**
+ * @param {tcuSurface.Surface} vaoRef
+ * @param {tcuSurface.Surface} defaultRef
+ */
+es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.genReferences = function(vaoRef, defaultRef) {
+ this.setState(this.m_spec.vao);
+ gl.useProgram(this.m_vaoProgram.getProgram());
+ this.makeDrawCall(this.m_spec.vao);
+ vaoRef.readViewport();
+
+ this.setState(this.m_spec.state);
+ gl.useProgram(this.m_stateProgram.getProgram());
+ this.makeDrawCall(this.m_spec.state);
+ defaultRef.readViewport();
+};
+
+es3fVertexArrayObjectTests.VertexArrayObjectTest.prototype.iterate = function() {
+ var vaoReference = new tcuSurface.Surface();
+ var stateReference = new tcuSurface.Surface();
+ var vaoResult = new tcuSurface.Surface();
+ var stateResult = new tcuSurface.Surface();
+
+ var isOk;
+
+ // logVertexArrayState(m_log, m_spec.vao, "Vertex Array Object State");
+ // logVertexArrayState(m_log, m_spec.state, "OpenGL Vertex Array State");
+ this.genReferences(stateReference, vaoReference);
+ this.render(stateResult, vaoResult);
+
+ isOk = tcuImageCompare.pixelThresholdCompare('Results', 'Comparison result from rendering with Vertex Array State', stateReference, stateResult, [0, 0, 0, 0]);
+ isOk = isOk && tcuImageCompare.pixelThresholdCompare('Results', 'Comparison result from rendering with Vertex Array Object', vaoReference, vaoResult, [0, 0, 0, 0]);
+
+ if (!isOk)
+ testFailedOptions('Result comparison failed', false);
+ else
+ testPassedOptions('Pass', true);
+
+ return tcuTestCase.IterateResult.STOP;
+};
+
+/**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+es3fVertexArrayObjectTests.VertexArrayObjectTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'vertex_array_objects', 'Vertex array object test cases');
+};
+
+es3fVertexArrayObjectTests.VertexArrayObjectTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+es3fVertexArrayObjectTests.VertexArrayObjectTests.prototype.constructor = es3fVertexArrayObjectTests.VertexArrayObjectTests;
+
+es3fVertexArrayObjectTests.VertexArrayObjectTests.prototype.init = function() {
+ var floatCoordBuffer48_1 = new es3fVertexArrayObjectTests.BufferSpec(48, 384, 2, 0, 0, gl.FLOAT, 0, 0, -1.0, 1.0);
+ var floatCoordBuffer48_2 = new es3fVertexArrayObjectTests.BufferSpec(48, 384, 2, 0, 0, gl.FLOAT, 0, 0, -1.0, 1.0);
+
+ var shortCoordBuffer48 = new es3fVertexArrayObjectTests.BufferSpec(48, 192, 2, 0, 0, gl.SHORT, -32768, 32768, 0.0, 0.0);
+
+ var spec;
+ var state;
+ // Different buffer
+ spec = new es3fVertexArrayObjectTests.Spec();
+
+ state = new es3fVertexArrayObjectTests.VertexArrayState();
+
+ state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
+
+ state.attributes[0].enabled = true;
+ state.attributes[0].size = 2;
+ state.attributes[0].stride = 0;
+ state.attributes[0].type = gl.FLOAT;
+ state.attributes[0].integer = false;
+ state.attributes[0].divisor = 0;
+ state.attributes[0].offset = 0;
+ state.attributes[0].normalized = false;
+
+ state.elementArrayBuffer = 0;
+
+ spec.buffers.push(floatCoordBuffer48_1);
+ spec.buffers.push(floatCoordBuffer48_2);
+
+ spec.useDrawElements = false;
+ spec.instances = 0;
+ spec.count = 48;
+ spec.vao = state;
+ spec.state = deUtil.clone(state);
+ spec.indexOffset = 0;
+ spec.indexRangeMin = 0;
+ spec.indexRangeMax = 0;
+ spec.indexType = gl.NONE;
+ spec.indexCount = 0;
+
+ spec.state.attributes[0].bufferNdx = 1;
+ spec.vao.attributes[0].bufferNdx = 2;
+ this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_buffer', 'diff_buffer'));
+
+ // Different size
+ spec = new es3fVertexArrayObjectTests.Spec();
+
+ state = new es3fVertexArrayObjectTests.VertexArrayState();
+
+ state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
+
+ state.attributes[0].enabled = true;
+ state.attributes[0].size = 2;
+ state.attributes[0].stride = 0;
+ state.attributes[0].type = gl.FLOAT;
+ state.attributes[0].integer = false;
+ state.attributes[0].divisor = 0;
+ state.attributes[0].offset = 0;
+ state.attributes[0].normalized = false;
+ state.attributes[0].bufferNdx = 1;
+
+ state.elementArrayBuffer = 0;
+
+ spec.buffers.push(floatCoordBuffer48_1);
+
+ spec.useDrawElements = false;
+ spec.instances = 0;
+ spec.count = 24;
+ spec.vao = state;
+ spec.state = deUtil.clone(state);
+ spec.indexOffset = 0;
+ spec.indexRangeMin = 0;
+ spec.indexRangeMax = 0;
+ spec.indexType = gl.NONE;
+ spec.indexCount = 0;
+
+ spec.state.attributes[0].size = 2;
+ spec.vao.attributes[0].size = 3;
+ this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_size', 'diff_size'));
+
+ // Different stride
+ spec = new es3fVertexArrayObjectTests.Spec();
+
+ state = new es3fVertexArrayObjectTests.VertexArrayState();
+
+ state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
+
+ state.attributes[0].enabled = true;
+ state.attributes[0].size = 2;
+ state.attributes[0].stride = 0;
+ state.attributes[0].type = gl.SHORT;
+ state.attributes[0].integer = false;
+ state.attributes[0].divisor = 0;
+ state.attributes[0].offset = 0;
+ state.attributes[0].normalized = true;
+ state.attributes[0].bufferNdx = 1;
+
+ state.elementArrayBuffer = 0;
+
+ spec.buffers.push(shortCoordBuffer48);
+
+ spec.useDrawElements = false;
+ spec.instances = 0;
+ spec.count = 24;
+ spec.vao = state;
+ spec.state = deUtil.clone(state);
+ spec.indexOffset = 0;
+ spec.indexRangeMin = 0;
+ spec.indexRangeMax = 0;
+ spec.indexType = gl.NONE;
+ spec.indexCount = 0;
+
+ spec.vao.attributes[0].stride = 2;
+ spec.state.attributes[0].stride = 4;
+ this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_stride', 'diff_stride'));
+
+ // Different types
+ spec = new es3fVertexArrayObjectTests.Spec();
+
+ state = new es3fVertexArrayObjectTests.VertexArrayState();
+
+ state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
+
+ state.attributes[0].enabled = true;
+ state.attributes[0].size = 2;
+ state.attributes[0].stride = 0;
+ state.attributes[0].type = gl.SHORT;
+ state.attributes[0].integer = false;
+ state.attributes[0].divisor = 0;
+ state.attributes[0].offset = 0;
+ state.attributes[0].normalized = true;
+ state.attributes[0].bufferNdx = 1;
+
+ state.elementArrayBuffer = 0;
+
+ spec.buffers.push(shortCoordBuffer48);
+
+ spec.useDrawElements = false;
+ spec.instances = 0;
+ spec.count = 24;
+ spec.vao = state;
+ spec.state = deUtil.clone(state);
+ spec.indexOffset = 0;
+ spec.indexRangeMin = 0;
+ spec.indexRangeMax = 0;
+ spec.indexType = gl.NONE;
+ spec.indexCount = 0;
+
+ spec.vao.attributes[0].type = gl.SHORT;
+ spec.state.attributes[0].type = gl.BYTE;
+ this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_type', 'diff_type'));
+
+ // Different "integer"
+ spec = new es3fVertexArrayObjectTests.Spec();
+
+ state = new es3fVertexArrayObjectTests.VertexArrayState();
+
+ state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
+
+ state.attributes[0].enabled = true;
+ state.attributes[0].size = 2;
+ state.attributes[0].stride = 0;
+ state.attributes[0].type = gl.BYTE;
+ state.attributes[0].integer = true;
+ state.attributes[0].divisor = 0;
+ state.attributes[0].offset = 0;
+ state.attributes[0].normalized = false;
+ state.attributes[0].bufferNdx = 1;
+
+ state.elementArrayBuffer = 0;
+
+ spec.buffers.push(shortCoordBuffer48);
+
+ spec.useDrawElements = false;
+ spec.count = 24;
+ spec.vao = state;
+ spec.state = deUtil.clone(state);
+ spec.instances = 0;
+ spec.indexOffset = 0;
+ spec.indexRangeMin = 0;
+ spec.indexRangeMax = 0;
+ spec.indexType = gl.NONE;
+ spec.indexCount = 0;
+
+ spec.state.attributes[0].integer = false;
+ spec.vao.attributes[0].integer = true;
+ this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_integer', 'diff_integer'));
+
+ // Different divisor
+ spec = new es3fVertexArrayObjectTests.Spec();
+
+ state = new es3fVertexArrayObjectTests.VertexArrayState();
+
+ state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
+ state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
+
+ state.attributes[0].enabled = true;
+ state.attributes[0].size = 2;
+ state.attributes[0].stride = 0;
+ state.attributes[0].type = gl.SHORT;
+ state.attributes[0].integer = false;
+ state.attributes[0].divisor = 0;
+ state.attributes[0].offset = 0;
+ state.attributes[0].normalized = true;
+ state.attributes[0].bufferNdx = 1;
+
+ state.attributes[1].enabled = true;
+ state.attributes[1].size = 4;
+ state.attributes[1].stride = 0;
+ state.attributes[1].type = gl.FLOAT;
+ state.attributes[1].integer = false;
+ state.attributes[1].divisor = 0;
+ state.attributes[1].offset = 0;
+ state.attributes[1].normalized = false;
+ state.attributes[1].bufferNdx = 2;
+
+ state.elementArrayBuffer = 0;
+
+ spec.buffers.push(shortCoordBuffer48);
+ spec.buffers.push(floatCoordBuffer48_1);
+
+ spec.useDrawElements = false;
+ spec.instances = 10;
+ spec.count = 12;
+ spec.vao = state;
+ spec.state = deUtil.clone(state);
+ spec.indexOffset = 0;
+ spec.indexRangeMin = 0;
+ spec.indexRangeMax = 0;
+ spec.indexType = gl.NONE;
+ spec.indexCount = 0;
+
+ spec.vao.attributes[1].divisor = 3;
+ spec.state.attributes[1].divisor = 2;
+
+ this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_divisor', 'diff_divisor'));
+
+ // Different offset
+ spec = new es3fVertexArrayObjectTests.Spec();
+
+ state = new es3fVertexArrayObjectTests.VertexArrayState();
+
+ state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
+
+ state.attributes[0].enabled = true;
+ state.attributes[0].size = 2;
+ state.attributes[0].stride = 0;
+ state.attributes[0].type = gl.SHORT;
+ state.attributes[0].integer = false;
+ state.attributes[0].divisor = 0;
+ state.attributes[0].offset = 0;
+ state.attributes[0].normalized = true;
+ state.attributes[0].bufferNdx = 1;
+
+ state.elementArrayBuffer = 0;
+
+ spec.buffers.push(shortCoordBuffer48);
+
+ spec.useDrawElements = false;
+ spec.instances = 0;
+ spec.count = 24;
+ spec.vao = state;
+ spec.state = deUtil.clone(state);
+ spec.indexOffset = 0;
+ spec.indexRangeMin = 0;
+ spec.indexRangeMax = 0;
+ spec.indexType = gl.NONE;
+ spec.indexCount = 0;
+
+ spec.vao.attributes[0].offset = 2;
+ spec.state.attributes[0].offset = 4;
+ this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_offset', 'diff_offset'));
+
+ // Different normalize
+ spec = new es3fVertexArrayObjectTests.Spec();
+
+ state = new es3fVertexArrayObjectTests.VertexArrayState();
+
+ state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
+
+ state.attributes[0].enabled = true;
+ state.attributes[0].size = 2;
+ state.attributes[0].stride = 0;
+ state.attributes[0].type = gl.SHORT;
+ state.attributes[0].integer = false;
+ state.attributes[0].divisor = 0;
+ state.attributes[0].offset = 0;
+ state.attributes[0].normalized = true;
+ state.attributes[0].bufferNdx = 1;
+
+ state.elementArrayBuffer = 0;
+
+ spec.buffers.push(shortCoordBuffer48);
+
+ spec.useDrawElements = false;
+ spec.instances = 0;
+ spec.count = 48;
+ spec.vao = state;
+ spec.state = deUtil.clone(state);
+ spec.indexOffset = 0;
+ spec.indexRangeMin = 0;
+ spec.indexRangeMax = 0;
+ spec.indexType = gl.NONE;
+ spec.indexCount = 0;
+
+ spec.vao.attributes[0].normalized = true;
+ spec.state.attributes[0].normalized = false;
+ this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_normalize', 'diff_normalize'));
+
+ // DrawElements with buffer
+ spec = new es3fVertexArrayObjectTests.Spec();
+
+ state = new es3fVertexArrayObjectTests.VertexArrayState();
+
+ state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
+
+ state.attributes[0].enabled = true;
+ state.attributes[0].size = 2;
+ state.attributes[0].stride = 0;
+ state.attributes[0].type = gl.FLOAT;
+ state.attributes[0].integer = false;
+ state.attributes[0].divisor = 0;
+ state.attributes[0].offset = 0;
+ state.attributes[0].normalized = true;
+ state.attributes[0].bufferNdx = 1;
+
+ state.elementArrayBuffer = 0;
+
+ spec.buffers.push(floatCoordBuffer48_1);
+
+ var indexBuffer = new es3fVertexArrayObjectTests.BufferSpec(24, 192, 1, 0, 0, gl.UNSIGNED_SHORT, 0, 47, 0.0, 0.0);
+ spec.buffers.push(indexBuffer);
+ spec.buffers.push(indexBuffer);
+
+ spec.useDrawElements = true;
+ spec.count = 24;
+ spec.vao = state;
+ spec.state = deUtil.clone(state);
+ spec.instances = 0;
+ spec.indexOffset = 0;
+ spec.indexRangeMin = 0;
+ spec.indexRangeMax = 48;
+ spec.indexType = gl.UNSIGNED_SHORT;
+ spec.indexCount = 24;
+
+ spec.state.elementArrayBuffer = 3;
+ spec.vao.elementArrayBuffer = 2;
+ this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'diff_indices', 'diff_indices'));
+
+ var attribCount = /** @type {number} */ (gl.getParameter(gl.MAX_VERTEX_ATTRIBS));
+ var random = new deRandom.Random(attribCount);
+ spec = new es3fVertexArrayObjectTests.Spec();
+
+ state = new es3fVertexArrayObjectTests.VertexArrayState();
+
+ spec.useDrawElements = false;
+ spec.instances = 0;
+ spec.count = 24;
+ spec.vao = state;
+ spec.state = deUtil.clone(state);
+ spec.indexOffset = 0;
+ spec.indexRangeMin = 0;
+ spec.indexRangeMax = 0;
+ spec.indexType = gl.NONE;
+ spec.indexCount = 0;
+ spec.vao.elementArrayBuffer = 0;
+ spec.state.elementArrayBuffer = 0;
+
+ // Use all attributes
+ for (var attribNdx = 0; attribNdx < attribCount; attribNdx++) {
+ spec.buffers.push(shortCoordBuffer48);
+
+ spec.state.attributes.push(new es3fVertexArrayObjectTests.Attribute());
+ spec.state.attributes[attribNdx].enabled = (random.getInt(0, 4) == 0) ? false : true;
+ spec.state.attributes[attribNdx].size = random.getInt(2, 4);
+ spec.state.attributes[attribNdx].stride = 2 * random.getInt(1, 3);
+ spec.state.attributes[attribNdx].type = gl.SHORT;
+ spec.state.attributes[attribNdx].integer = random.getBool();
+ spec.state.attributes[attribNdx].divisor = random.getInt(0, 1);
+ spec.state.attributes[attribNdx].offset = 2 * random.getInt(0, 2);
+ spec.state.attributes[attribNdx].normalized = random.getBool();
+ spec.state.attributes[attribNdx].bufferNdx = attribNdx + 1;
+
+ if (attribNdx == 0) {
+ spec.state.attributes[attribNdx].divisor = 0;
+ spec.state.attributes[attribNdx].enabled = true;
+ spec.state.attributes[attribNdx].size = 2;
+ }
+
+ spec.vao.attributes.push(new es3fVertexArrayObjectTests.Attribute());
+ spec.vao.attributes[attribNdx].enabled = (random.getInt(0, 4) == 0) ? false : true;
+ spec.vao.attributes[attribNdx].size = random.getInt(2, 4);
+ spec.vao.attributes[attribNdx].stride = 2 * random.getInt(1, 3);
+ spec.vao.attributes[attribNdx].type = gl.SHORT;
+ spec.vao.attributes[attribNdx].integer = random.getBool();
+ spec.vao.attributes[attribNdx].divisor = random.getInt(0, 1);
+ spec.vao.attributes[attribNdx].offset = 2 * random.getInt(0, 2);
+ spec.vao.attributes[attribNdx].normalized = random.getBool();
+ spec.vao.attributes[attribNdx].bufferNdx = attribCount - attribNdx;
+
+ if (attribNdx == 0) {
+ spec.vao.attributes[attribNdx].divisor = 0;
+ spec.vao.attributes[attribNdx].enabled = true;
+ spec.vao.attributes[attribNdx].size = 2;
+ }
+
+ }
+ this.addChild(new es3fVertexArrayObjectTests.VertexArrayObjectTest(spec, 'all_attributes', 'all_attributes'));
+
+};
+
+/**
+ * Run test
+ * @param {WebGL2RenderingContext} context
+ */
+es3fVertexArrayObjectTests.run = function(context) {
+ gl = context;
+ //Set up Test Root parameters
+ var state = tcuTestCase.runner;
+ state.setRoot(new es3fVertexArrayObjectTests.VertexArrayObjectTests());
+
+ //Set up name and description of this test series.
+ setCurrentTestName(state.testCases.fullName());
+ description(state.testCases.getDescription());
+
+ try {
+ //Run test cases
+ tcuTestCase.runTestCases();
+ }
+ catch (err) {
+ testFailedOptions('Failed to es3fVertexArrayObjectTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+};
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fVertexArrayTests.js b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fVertexArrayTests.js
new file mode 100644
index 0000000000..ccfd343313
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/es3fVertexArrayTests.js
@@ -0,0 +1,1103 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES Utilities
+ * ------------------------------------------------
+ *
+ * Copyright 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+'use strict';
+goog.provide('functional.gles3.es3fVertexArrayTests');
+goog.require('framework.common.tcuSurface');
+goog.require('framework.common.tcuTestCase');
+goog.require('framework.common.tcuTexture');
+goog.require('framework.delibs.debase.deMath');
+goog.require('framework.delibs.debase.deRandom');
+goog.require('framework.delibs.debase.deString');
+goog.require('framework.delibs.debase.deUtil');
+goog.require('framework.opengl.gluDrawUtil');
+goog.require('framework.opengl.gluShaderProgram');
+goog.require('framework.opengl.gluShaderUtil');
+goog.require('framework.opengl.gluTexture');
+goog.require('framework.opengl.gluVarType');
+goog.require('modules.shared.glsVertexArrayTests');
+
+goog.scope(function() {
+
+ var es3fVertexArrayTests = functional.gles3.es3fVertexArrayTests;
+ var gluDrawUtil = framework.opengl.gluDrawUtil;
+ var gluShaderUtil = framework.opengl.gluShaderUtil;
+ var gluShaderProgram = framework.opengl.gluShaderProgram;
+ var gluTexture = framework.opengl.gluTexture;
+ var gluVarType = framework.opengl.gluVarType;
+ var tcuTestCase = framework.common.tcuTestCase;
+ var tcuSurface = framework.common.tcuSurface;
+ var tcuTexture = framework.common.tcuTexture;
+ var deMath = framework.delibs.debase.deMath;
+ var deString = framework.delibs.debase.deString;
+ var deRandom = framework.delibs.debase.deRandom;
+ var deUtil = framework.delibs.debase.deUtil;
+ var glsVertexArrayTests = modules.shared.glsVertexArrayTests;
+
+ var DE_ASSERT = function(x) {
+ if (!x)
+ throw new Error('Assert failed');
+ };
+
+ /**
+ * es3fVertexArrayTests.SingleVertexArrayUsageGroup
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {glsVertexArrayTests.deArray.Usage} usage
+ */
+ es3fVertexArrayTests.SingleVertexArrayUsageGroup = function(usage) {
+ tcuTestCase.DeqpTest.call(
+ this,
+ "single_attribute.usages." + glsVertexArrayTests.deArray.usageTypeToString(usage),
+ glsVertexArrayTests.deArray.usageTypeToString(usage)
+ );
+ this.makeExecutable();
+ this.m_usage = usage;
+ };
+
+ es3fVertexArrayTests.SingleVertexArrayUsageGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fVertexArrayTests.SingleVertexArrayUsageGroup.prototype.constructor = es3fVertexArrayTests.SingleVertexArrayUsageGroup;
+
+ /**
+ * init
+ */
+ es3fVertexArrayTests.SingleVertexArrayUsageGroup.prototype.init = function() {
+ /** @type {Array<number>} */ var counts = [1, 256];
+ /** @type {Array<number>} */ var strides = [0, -1, 17, 32]; // Treat negative value as sizeof input. Same as 0, but done outside of GL.
+ /** @type {Array<glsVertexArrayTests.deArray.InputType>} */ var inputTypes = [
+ glsVertexArrayTests.deArray.InputType.FLOAT,
+ /*glsVertexArrayTests.deArray.InputType.FIXED,*/
+ glsVertexArrayTests.deArray.InputType.SHORT,
+ glsVertexArrayTests.deArray.InputType.BYTE
+ ];
+
+ for (var inputTypeNdx = 0; inputTypeNdx < inputTypes.length; inputTypeNdx++) {
+ for (var countNdx = 0; countNdx < counts.length; countNdx++) {
+ for (var strideNdx = 0; strideNdx < strides.length; strideNdx++) {
+ /** @type {number} */ var stride = (strides[strideNdx] < 0 ? glsVertexArrayTests.deArray.inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]);
+ /** @type {boolean} */ var aligned = (stride % glsVertexArrayTests.deArray.inputTypeSize(inputTypes[inputTypeNdx])) == 0;
+ /** @type {string} */ var name = 'stride' + stride + '_' + glsVertexArrayTests.deArray.inputTypeToString(inputTypes[inputTypeNdx]) + '_quads' + counts[countNdx];
+
+ var arraySpec = new glsVertexArrayTests.MultiVertexArrayTest.Spec.ArraySpec(
+ inputTypes[inputTypeNdx],
+ glsVertexArrayTests.deArray.OutputType.VEC2,
+ glsVertexArrayTests.deArray.Storage.BUFFER,
+ this.m_usage,
+ 2,
+ 0,
+ stride,
+ false,
+ glsVertexArrayTests.GLValue.getMinValue(inputTypes[inputTypeNdx]),
+ glsVertexArrayTests.GLValue.getMaxValue(inputTypes[inputTypeNdx])
+ );
+
+ var spec = new glsVertexArrayTests.MultiVertexArrayTest.Spec();
+ spec.primitive = glsVertexArrayTests.deArray.Primitive.TRIANGLES;
+ spec.drawCount = counts[countNdx];
+ spec.first = 0;
+ spec.arrays.push(arraySpec);
+
+ if (aligned)
+ this.addChild(
+ new glsVertexArrayTests.MultiVertexArrayTest(
+ spec, name, name
+ )
+ );
+ }
+ }
+ }
+ };
+
+ /**
+ * es3fVertexArrayTests.SingleVertexArrayStrideGroup
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {glsVertexArrayTests.deArray.InputType} type
+ */
+ es3fVertexArrayTests.SingleVertexArrayStrideGroup = function(type) {
+ tcuTestCase.DeqpTest.call(this, glsVertexArrayTests.deArray.inputTypeToString(type), glsVertexArrayTests.deArray.inputTypeToString(type));
+ this.makeExecutable();
+ this.m_type = type;
+ };
+
+ es3fVertexArrayTests.SingleVertexArrayStrideGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fVertexArrayTests.SingleVertexArrayStrideGroup.prototype.constructor = es3fVertexArrayTests.SingleVertexArrayStrideGroup;
+
+ /**
+ * init
+ */
+ es3fVertexArrayTests.SingleVertexArrayStrideGroup.prototype.init = function() {
+ /** @type {Array<glsVertexArrayTests.deArray.Storage>} */ var storages = [
+ // User storage not supported in WebGL - glsVertexArrayTests.deArray.Storage.USER,
+ glsVertexArrayTests.deArray.Storage.BUFFER
+ ];
+ var counts = [1, 256];
+ var strides = [/*0,*/ -1, 17, 32]; // Treat negative value as sizeof input. Same as 0, but done outside of GL.
+
+ for (var storageNdx = 0; storageNdx < storages.length; storageNdx++) {
+ for (var componentCount = 2; componentCount < 5; componentCount++) {
+ for (var countNdx = 0; countNdx < counts.length; countNdx++) {
+ for (var strideNdx = 0; strideNdx < strides.length; strideNdx++) {
+ /** @type {boolean} */ var packed = this.m_type == glsVertexArrayTests.deArray.InputType.UNSIGNED_INT_2_10_10_10 || this.m_type == glsVertexArrayTests.deArray.InputType.INT_2_10_10_10;
+ /** @type {number} */ var stride = (strides[strideNdx] < 0) ? ((packed) ? (16) : (glsVertexArrayTests.deArray.inputTypeSize(this.m_type) * componentCount)) : (strides[strideNdx]);
+ /** @type {number} */ var alignment = (packed) ? (glsVertexArrayTests.deArray.inputTypeSize(this.m_type) * componentCount) : (glsVertexArrayTests.deArray.inputTypeSize(this.m_type));
+ /** @type {boolean} */ var bufferUnaligned = (storages[storageNdx] == glsVertexArrayTests.deArray.Storage.BUFFER) && (stride % alignment) != 0;
+
+ /** @type {string} */ var name = glsVertexArrayTests.deArray.storageToString(storages[storageNdx]) + '_stride' + stride + '_components' + componentCount + '_quads' + counts[countNdx];
+
+ if ((this.m_type == glsVertexArrayTests.deArray.InputType.UNSIGNED_INT_2_10_10_10 ||
+ this.m_type == glsVertexArrayTests.deArray.InputType.INT_2_10_10_10) && componentCount != 4)
+ continue;
+
+ /** @type {glsVertexArrayTests.MultiVertexArrayTest.Spec.ArraySpec} */ var arraySpec = new glsVertexArrayTests.MultiVertexArrayTest.Spec.ArraySpec(
+ this.m_type,
+ glsVertexArrayTests.deArray.OutputType.VEC4,
+ storages[storageNdx],
+ glsVertexArrayTests.deArray.Usage.DYNAMIC_DRAW,
+ componentCount,
+ 0,
+ stride,
+ false,
+ glsVertexArrayTests.GLValue.getMinValue(this.m_type),
+ glsVertexArrayTests.GLValue.getMaxValue(this.m_type)
+ );
+
+ var spec = new glsVertexArrayTests.MultiVertexArrayTest.Spec();
+
+ spec.primitive = glsVertexArrayTests.deArray.Primitive.TRIANGLES;
+ spec.drawCount = counts[countNdx];
+ spec.first = 0;
+ spec.arrays.push(arraySpec);
+
+ if (!bufferUnaligned)
+ this.addChild(
+ new glsVertexArrayTests.MultiVertexArrayTest(
+ spec, name, name
+ )
+ );
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * es3fVertexArrayTests.SingleVertexArrayStrideTests
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fVertexArrayTests.SingleVertexArrayStrideTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'single_attribute.strides', 'Single stride vertex atribute');
+ this.makeExecutable();
+ };
+
+ es3fVertexArrayTests.SingleVertexArrayStrideTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fVertexArrayTests.SingleVertexArrayStrideTests.prototype.constructor = es3fVertexArrayTests.SingleVertexArrayStrideTests;
+
+ es3fVertexArrayTests.SingleVertexArrayStrideTests.prototype.init = function() {
+ /** @type {Array<glsVertexArrayTests.deArray.InputType>} */ var inputTypes = [
+ glsVertexArrayTests.deArray.InputType.FLOAT,
+ glsVertexArrayTests.deArray.InputType.SHORT,
+ glsVertexArrayTests.deArray.InputType.BYTE,
+ /*glsVertexArrayTests.deArray.InputType.UNSIGNED_SHORT,
+ glsVertexArrayTests.deArray.InputType.UNSIGNED_BYTE,
+ glsVertexArrayTests.deArray.InputType.FIXED,*/
+ glsVertexArrayTests.deArray.InputType.INT_2_10_10_10
+ ];
+
+ for (var inputTypeNdx = 0; inputTypeNdx < inputTypes.length; inputTypeNdx++)
+ this.addChild(
+ new es3fVertexArrayTests.SingleVertexArrayStrideGroup(
+ inputTypes[inputTypeNdx]
+ )
+ );
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {glsVertexArrayTests.deArray.InputType} type
+ */
+ es3fVertexArrayTests.SingleVertexArrayFirstGroup = function(type) {
+ tcuTestCase.DeqpTest.call(
+ this,
+ glsVertexArrayTests.deArray.inputTypeToString(type),
+ glsVertexArrayTests.deArray.inputTypeToString(type)
+ );
+ this.makeExecutable();
+
+ this.m_type = type;
+ };
+
+ es3fVertexArrayTests.SingleVertexArrayFirstGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fVertexArrayTests.SingleVertexArrayFirstGroup.prototype.constructor = es3fVertexArrayTests.SingleVertexArrayFirstGroup;
+
+ /**
+ * init
+ */
+ es3fVertexArrayTests.SingleVertexArrayFirstGroup.prototype.init = function() {
+ var counts = [5, 256];
+ var firsts = [6, 24];
+ var offsets = [1, 16, 17];
+ var strides = [/*0,*/ -1, 17, 32]; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
+
+ for (var offsetNdx = 0; offsetNdx < offsets.length; offsetNdx++) {
+ for (var countNdx = 0; countNdx < counts.length; countNdx++) {
+ for (var strideNdx = 0; strideNdx < strides.length; strideNdx++) {
+ for (var firstNdx = 0; firstNdx < firsts.length; firstNdx++) {
+ var packed = this.m_type == glsVertexArrayTests.deArray.InputType.UNSIGNED_INT_2_10_10_10 ||
+ this.m_type == glsVertexArrayTests.deArray.InputType.INT_2_10_10_10;
+ var componentCount = packed ? 4 : 2;
+ var stride = strides[strideNdx] < 0 ?
+ (packed ? 8 : (glsVertexArrayTests.deArray.inputTypeSize(this.m_type) * componentCount)) :
+ (strides[strideNdx]);
+ var alignment = packed ?
+ (glsVertexArrayTests.deArray.inputTypeSize(this.m_type) * componentCount) :
+ (glsVertexArrayTests.deArray.inputTypeSize(this.m_type));
+ var aligned = ((stride % alignment) == 0) &&
+ ((offsets[offsetNdx] % alignment) == 0);
+ var name = 'first' + firsts[firstNdx] + '_offset' + offsets[offsetNdx] + '_stride' + stride + '_quads' + counts[countNdx];
+
+ var arraySpec = new glsVertexArrayTests.MultiVertexArrayTest.Spec.ArraySpec(
+ this.m_type,
+ glsVertexArrayTests.deArray.OutputType.VEC2,
+ glsVertexArrayTests.deArray.Storage.BUFFER,
+ glsVertexArrayTests.deArray.Usage.DYNAMIC_DRAW,
+ componentCount,
+ offsets[offsetNdx],
+ stride,
+ false,
+ glsVertexArrayTests.GLValue.getMinValue(this.m_type),
+ glsVertexArrayTests.GLValue.getMaxValue(this.m_type)
+ );
+
+ var spec = new glsVertexArrayTests.MultiVertexArrayTest.Spec();
+ spec.primitive = glsVertexArrayTests.deArray.Primitive.TRIANGLES;
+ spec.drawCount = counts[countNdx];
+ spec.first = firsts[firstNdx];
+ spec.arrays.push(arraySpec);
+
+ if (aligned)
+ this.addChild(
+ new glsVertexArrayTests.MultiVertexArrayTest(
+ spec, name, name
+ )
+ );
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fVertexArrayTests.SingleVertexArrayFirstTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'single_attribute.first', 'Single vertex attribute, different first values to drawArrays');
+ this.makeExecutable();
+ };
+
+ es3fVertexArrayTests.SingleVertexArrayFirstTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fVertexArrayTests.SingleVertexArrayFirstTests.prototype.constructor = es3fVertexArrayTests.SingleVertexArrayFirstTests;
+
+ /**
+ * init
+ */
+ es3fVertexArrayTests.SingleVertexArrayFirstTests.prototype.init = function() {
+ // Test offset with different input types, component counts and storage, Usage(?)
+ var inputTypes = [
+ glsVertexArrayTests.deArray.InputType.FLOAT,
+ glsVertexArrayTests.deArray.InputType.BYTE,
+ glsVertexArrayTests.deArray.InputType.INT_2_10_10_10
+ ];
+
+ for (var inputTypeNdx = 0; inputTypeNdx < inputTypes.length; inputTypeNdx++) {
+ this.addChild(
+ new es3fVertexArrayTests.SingleVertexArrayFirstGroup(
+ inputTypes[inputTypeNdx]
+ )
+ );
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {glsVertexArrayTests.deArray.InputType} type
+ */
+ es3fVertexArrayTests.SingleVertexArrayOffsetGroup = function(type) {
+ tcuTestCase.DeqpTest.call(
+ this,
+ glsVertexArrayTests.deArray.inputTypeToString(type),
+ glsVertexArrayTests.deArray.inputTypeToString(type)
+ );
+ this.makeExecutable();
+ this.m_type = type;
+ };
+
+ es3fVertexArrayTests.SingleVertexArrayOffsetGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fVertexArrayTests.SingleVertexArrayOffsetGroup.prototype.constructor = es3fVertexArrayTests.SingleVertexArrayOffsetGroup;
+
+ /**
+ * init
+ */
+ es3fVertexArrayTests.SingleVertexArrayOffsetGroup.prototype.init = function() {
+ var counts = [1, 256];
+ var offsets = [1, 4, 17, 32];
+ var strides = [/*0,*/ -1, 17, 32]; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
+
+ for (var offsetNdx = 0; offsetNdx < offsets.length; offsetNdx++) {
+ for (var countNdx = 0; countNdx < counts.length; countNdx++) {
+ for (var strideNdx = 0; strideNdx < strides.length; strideNdx++) {
+ var packed = this.m_type == glsVertexArrayTests.deArray.InputType.UNSIGNED_INT_2_10_10_10 ||
+ this.m_type == glsVertexArrayTests.deArray.InputType.INT_2_10_10_10;
+ var componentCount = packed ? 4 : 2;
+ var stride = (
+ strides[strideNdx] < 0 ?
+ glsVertexArrayTests.deArray.inputTypeSize(
+ this.m_type
+ ) * componentCount :
+ strides[strideNdx]
+ );
+ var alignment = packed ?
+ glsVertexArrayTests.deArray.inputTypeSize(this.m_type) * componentCount :
+ glsVertexArrayTests.deArray.inputTypeSize(this.m_type);
+
+ var aligned = ((stride % alignment) == 0) &&
+ ((offsets[offsetNdx] % alignment) == 0);
+ var name = 'offset' + offsets[offsetNdx] +
+ '_stride' + stride + '_quads' +
+ counts[countNdx];
+
+ /** @type {glsVertexArrayTests.MultiVertexArrayTest.Spec.ArraySpec} */ var arraySpec = new glsVertexArrayTests.MultiVertexArrayTest.Spec.ArraySpec(
+ this.m_type,
+ glsVertexArrayTests.deArray.OutputType.VEC2,
+ glsVertexArrayTests.deArray.Storage.BUFFER,
+ glsVertexArrayTests.deArray.Usage.DYNAMIC_DRAW,
+ componentCount,
+ offsets[offsetNdx],
+ stride,
+ false,
+ glsVertexArrayTests.GLValue.getMinValue(this.m_type),
+ glsVertexArrayTests.GLValue.getMaxValue(this.m_type)
+ );
+
+ var spec = new glsVertexArrayTests.MultiVertexArrayTest.Spec();
+ spec.primitive = glsVertexArrayTests.deArray.Primitive.TRIANGLES;
+ spec.drawCount = counts[countNdx];
+ spec.first = 0;
+ spec.arrays.push(arraySpec);
+
+ if (aligned)
+ this.addChild(
+ new glsVertexArrayTests.MultiVertexArrayTest(
+ spec, name, name
+ )
+ );
+ }
+ }
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fVertexArrayTests.SingleVertexArrayOffsetTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'single_attribute.offset', 'Single vertex atribute offset element');
+ this.makeExecutable();
+ };
+
+ es3fVertexArrayTests.SingleVertexArrayOffsetTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fVertexArrayTests.SingleVertexArrayOffsetTests.prototype.constructor = es3fVertexArrayTests.SingleVertexArrayOffsetTests;
+
+ /**
+ * init
+ */
+ es3fVertexArrayTests.SingleVertexArrayOffsetTests.prototype.init = function() {
+ // Test offset with different input types, component counts and storage, Usage(?)
+ var inputTypes = [
+ glsVertexArrayTests.deArray.InputType.FLOAT,
+ glsVertexArrayTests.deArray.InputType.BYTE,
+ glsVertexArrayTests.deArray.InputType.INT_2_10_10_10
+ ];
+
+ for (var inputTypeNdx = 0; inputTypeNdx < inputTypes.length; inputTypeNdx++) {
+ this.addChild(
+ new es3fVertexArrayTests.SingleVertexArrayOffsetGroup(
+ inputTypes[inputTypeNdx]
+ )
+ );
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {glsVertexArrayTests.deArray.InputType} type
+ */
+ es3fVertexArrayTests.SingleVertexArrayNormalizeGroup = function(type) {
+ tcuTestCase.DeqpTest.call(
+ this,
+ glsVertexArrayTests.deArray.inputTypeToString(type),
+ glsVertexArrayTests.deArray.inputTypeToString(type)
+ );
+ this.makeExecutable();
+ this.m_type = type;
+ };
+
+ es3fVertexArrayTests.SingleVertexArrayNormalizeGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fVertexArrayTests.SingleVertexArrayNormalizeGroup.prototype.constructor = es3fVertexArrayTests.SingleVertexArrayNormalizeGroup;
+
+ /**
+ * init for SingleVertexArrayNormalizeGroup
+ */
+ es3fVertexArrayTests.SingleVertexArrayNormalizeGroup.prototype.init = function() {
+ var counts = [1, 256];
+
+ for (var componentCount = 2; componentCount < 5; componentCount++) {
+ for (var countNdx = 0; countNdx < counts.length; countNdx++) {
+ if (
+ (
+ this.m_type == glsVertexArrayTests.deArray.InputType.UNSIGNED_INT_2_10_10_10 ||
+ this.m_type == glsVertexArrayTests.deArray.InputType.INT_2_10_10_10
+ ) && componentCount != 4
+ )
+ continue;
+
+ var name = 'components' + componentCount.toString() + '_quads' + counts[countNdx].toString();
+
+ var arraySpec = new glsVertexArrayTests.MultiVertexArrayTest.Spec.ArraySpec(
+ this.m_type,
+ glsVertexArrayTests.deArray.OutputType.VEC4,
+ glsVertexArrayTests.deArray.Storage.BUFFER, //No USER Storage support in WebGL2
+ glsVertexArrayTests.deArray.Usage.DYNAMIC_DRAW,
+ componentCount,
+ 0,
+ 0,
+ true,
+ glsVertexArrayTests.GLValue.getMinValue(this.m_type),
+ glsVertexArrayTests.GLValue.getMaxValue(this.m_type)
+ );
+
+ var spec = new glsVertexArrayTests.MultiVertexArrayTest.Spec();
+ spec.primitive = glsVertexArrayTests.deArray.Primitive.TRIANGLES;
+ spec.drawCount = counts[countNdx];
+ spec.first = 0;
+ spec.arrays.push(arraySpec);
+
+ this.addChild(
+ new glsVertexArrayTests.MultiVertexArrayTest(
+ spec, name, name
+ )
+ );
+ }
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fVertexArrayTests.SingleVertexArrayNormalizeTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'single_attribute.normalize', 'Single normalize vertex atribute');
+ this.makeExecutable();
+ };
+
+ es3fVertexArrayTests.SingleVertexArrayNormalizeTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fVertexArrayTests.SingleVertexArrayNormalizeTests.prototype.constructor = es3fVertexArrayTests.SingleVertexArrayNormalizeTests;
+
+ /**
+ * init
+ */
+ es3fVertexArrayTests.SingleVertexArrayNormalizeTests.prototype.init = function() {
+ // Test normalization with different input types, component counts and storage
+ /** @type {Array<glsVertexArrayTests.deArray.InputType>} */ var inputTypes = [
+ glsVertexArrayTests.deArray.InputType.FLOAT,
+ glsVertexArrayTests.deArray.InputType.SHORT,
+ glsVertexArrayTests.deArray.InputType.BYTE,
+ glsVertexArrayTests.deArray.InputType.UNSIGNED_SHORT,
+ glsVertexArrayTests.deArray.InputType.UNSIGNED_BYTE,
+ //glsVertexArrayTests.deArray.InputType.FIXED,
+ glsVertexArrayTests.deArray.InputType.UNSIGNED_INT,
+ glsVertexArrayTests.deArray.InputType.INT,
+ glsVertexArrayTests.deArray.InputType.HALF,
+ glsVertexArrayTests.deArray.InputType.UNSIGNED_INT_2_10_10_10,
+ glsVertexArrayTests.deArray.InputType.INT_2_10_10_10
+ ];
+
+ for (var inputTypeNdx = 0; inputTypeNdx < inputTypes.length; inputTypeNdx++) {
+ this.addChild(
+ new es3fVertexArrayTests.SingleVertexArrayNormalizeGroup(
+ inputTypes[inputTypeNdx]
+ )
+ );
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ * @param {glsVertexArrayTests.deArray.InputType} type
+ */
+ es3fVertexArrayTests.SingleVertexArrayOutputTypeGroup = function(type) {
+ tcuTestCase.DeqpTest.call(
+ this,
+ "single_attribute.output_types." + glsVertexArrayTests.deArray.inputTypeToString(type),
+ glsVertexArrayTests.deArray.inputTypeToString(type)
+ );
+ this.makeExecutable();
+ this.m_type = type;
+ };
+
+ es3fVertexArrayTests.SingleVertexArrayOutputTypeGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fVertexArrayTests.SingleVertexArrayOutputTypeGroup.prototype.constructor = es3fVertexArrayTests.SingleVertexArrayOutputTypeGroup;
+
+ es3fVertexArrayTests.SingleVertexArrayOutputTypeGroup.prototype.init = function() {
+ var outputTypes = [
+ glsVertexArrayTests.deArray.OutputType.VEC2,
+ glsVertexArrayTests.deArray.OutputType.VEC3,
+ glsVertexArrayTests.deArray.OutputType.VEC4,
+ glsVertexArrayTests.deArray.OutputType.IVEC2,
+ glsVertexArrayTests.deArray.OutputType.IVEC3,
+ glsVertexArrayTests.deArray.OutputType.IVEC4,
+ glsVertexArrayTests.deArray.OutputType.UVEC2,
+ glsVertexArrayTests.deArray.OutputType.UVEC3,
+ glsVertexArrayTests.deArray.OutputType.UVEC4
+ ];
+ var storages = [glsVertexArrayTests.deArray.Storage.BUFFER]; //No USER storage support in WebGL2
+ var counts = [1, 256];
+
+ for (var outputTypeNdx = 0; outputTypeNdx < outputTypes.length; outputTypeNdx++) {
+ for (var storageNdx = 0; storageNdx < storages.length; storageNdx++) {
+ for (var componentCount = 2; componentCount < 5; componentCount++) {
+ for (var countNdx = 0; countNdx < counts.length; countNdx++) {
+ var name = 'components' + componentCount + '_' +
+ glsVertexArrayTests.deArray.outputTypeToString(
+ outputTypes[outputTypeNdx]
+ ) +
+ '_quads' + counts[countNdx];
+
+ var inputIsSignedInteger =
+ this.m_type == glsVertexArrayTests.deArray.InputType.INT ||
+ this.m_type == glsVertexArrayTests.deArray.InputType.SHORT ||
+ this.m_type == glsVertexArrayTests.deArray.InputType.BYTE;
+
+ var inputIsUnignedInteger =
+ this.m_type == glsVertexArrayTests.deArray.InputType.UNSIGNED_INT ||
+ this.m_type == glsVertexArrayTests.deArray.InputType.UNSIGNED_SHORT ||
+ this.m_type == glsVertexArrayTests.deArray.InputType.UNSIGNED_BYTE;
+
+ var outputIsSignedInteger =
+ outputTypes[outputTypeNdx] == glsVertexArrayTests.deArray.OutputType.IVEC2 ||
+ outputTypes[outputTypeNdx] == glsVertexArrayTests.deArray.OutputType.IVEC3 ||
+ outputTypes[outputTypeNdx] == glsVertexArrayTests.deArray.OutputType.IVEC4;
+
+ var outputIsUnsignedInteger =
+ outputTypes[outputTypeNdx] == glsVertexArrayTests.deArray.OutputType.UVEC2 ||
+ outputTypes[outputTypeNdx] == glsVertexArrayTests.deArray.OutputType.UVEC3 ||
+ outputTypes[outputTypeNdx] == glsVertexArrayTests.deArray.OutputType.UVEC4;
+
+ // If input type is float type and output type is int type skip
+ if ((this.m_type == glsVertexArrayTests.deArray.InputType.FLOAT ||
+ this.m_type == glsVertexArrayTests.deArray.InputType.HALF) &&
+ (outputTypes[outputTypeNdx] >= glsVertexArrayTests.deArray.OutputType.INT))
+ continue;
+
+ if ((this.m_type == glsVertexArrayTests.deArray.InputType.UNSIGNED_INT_2_10_10_10 ||
+ this.m_type == glsVertexArrayTests.deArray.InputType.INT_2_10_10_10) &&
+ (outputTypes[outputTypeNdx] >= glsVertexArrayTests.deArray.OutputType.INT))
+ continue;
+
+ if ((this.m_type == glsVertexArrayTests.deArray.InputType.UNSIGNED_INT_2_10_10_10 ||
+ this.m_type == glsVertexArrayTests.deArray.InputType.INT_2_10_10_10) &&
+ componentCount != 4)
+ continue;
+
+ // Loading signed data as unsigned causes undefined values and vice versa
+ if (inputIsSignedInteger && outputIsUnsignedInteger)
+ continue;
+ if (inputIsUnignedInteger && outputIsSignedInteger)
+ continue;
+
+ var arraySpec = new glsVertexArrayTests.MultiVertexArrayTest.Spec.ArraySpec(
+ this.m_type,
+ outputTypes[outputTypeNdx],
+ storages[storageNdx],
+ glsVertexArrayTests.deArray.Usage.DYNAMIC_DRAW,
+ componentCount,
+ 0,
+ 0,
+ false,
+ glsVertexArrayTests.GLValue.getMinValue(this.m_type),
+ glsVertexArrayTests.GLValue.getMaxValue(this.m_type)
+ );
+
+ var spec = new glsVertexArrayTests.MultiVertexArrayTest.Spec();
+ spec.primitive = glsVertexArrayTests.deArray.Primitive.TRIANGLES;
+ spec.drawCount = counts[countNdx];
+ spec.first = 0;
+ spec.arrays.push(arraySpec);
+
+ this.addChild(
+ new glsVertexArrayTests.MultiVertexArrayTest(
+ spec, name, name
+ )
+ );
+ }
+ }
+ }
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fVertexArrayTests.MultiVertexArrayCountTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'multiple_attributes.attribute_count', 'Attribute counts');
+ this.makeExecutable();
+ };
+
+ es3fVertexArrayTests.MultiVertexArrayCountTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fVertexArrayTests.MultiVertexArrayCountTests.prototype.constructor = es3fVertexArrayTests.MultiVertexArrayCountTests;
+
+ /**
+ * @param {glsVertexArrayTests.MultiVertexArrayTest.Spec} spec
+ * @return {string}
+ */
+ es3fVertexArrayTests.MultiVertexArrayCountTests.prototype.getTestName = function(spec) {
+ var name = '';
+ name += spec.arrays.length;
+
+ return name;
+ };
+
+ es3fVertexArrayTests.MultiVertexArrayCountTests.prototype.init = function() {
+ // Test attribute counts
+ var arrayCounts = [2, 3, 4, 5, 6, 7, 8];
+
+ for (var arrayCountNdx = 0; arrayCountNdx < arrayCounts.length; arrayCountNdx++) {
+ var spec = new glsVertexArrayTests.MultiVertexArrayTest.Spec();
+
+ spec.primitive = glsVertexArrayTests.deArray.Primitive.TRIANGLES;
+ spec.drawCount = 256;
+ spec.first = 0;
+
+ for (var arrayNdx = 0; arrayNdx < arrayCounts[arrayCountNdx]; arrayNdx++) {
+ var arraySpec = new glsVertexArrayTests.MultiVertexArrayTest.Spec.ArraySpec(
+ glsVertexArrayTests.deArray.InputType.FLOAT,
+ glsVertexArrayTests.deArray.OutputType.VEC2,
+ glsVertexArrayTests.deArray.Storage.BUFFER, // No USER storage support in WebGL2
+ glsVertexArrayTests.deArray.Usage.DYNAMIC_DRAW,
+ 2,
+ 0,
+ 0,
+ false,
+ glsVertexArrayTests.GLValue.getMinValue(glsVertexArrayTests.deArray.InputType.FLOAT),
+ glsVertexArrayTests.GLValue.getMaxValue(glsVertexArrayTests.deArray.InputType.FLOAT)
+ );
+ spec.arrays.push(arraySpec);
+ }
+
+ var name = this.getTestName(spec);
+ var desc = this.getTestName(spec);
+
+ this.addChild(
+ new glsVertexArrayTests.MultiVertexArrayTest(
+ spec, name, desc
+ )
+ );
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fVertexArrayTests.MultiVertexArrayStorageTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'multiple_attributes.storage', 'Attribute storages');
+ this.makeExecutable();
+ };
+
+ es3fVertexArrayTests.MultiVertexArrayStorageTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fVertexArrayTests.MultiVertexArrayStorageTests.prototype.constructor = es3fVertexArrayTests.MultiVertexArrayStorageTests;
+
+ /**
+ * @param {glsVertexArrayTests.MultiVertexArrayTest.Spec} spec
+ * @return {string}
+ */
+ es3fVertexArrayTests.MultiVertexArrayStorageTests.prototype.getTestName = function(spec) {
+ var name = '';
+ name += spec.arrays.length;
+
+ for (var arrayNdx = 0; arrayNdx < spec.arrays.length; arrayNdx++)
+ name += '_' + glsVertexArrayTests.deArray.storageToString(spec.arrays[arrayNdx].storage);
+
+ return name;
+ };
+
+ /**
+ * @param {glsVertexArrayTests.MultiVertexArrayTest.Spec} spec
+ * @param {number} depth
+ */
+ es3fVertexArrayTests.MultiVertexArrayStorageTests.prototype.addStorageCases = function(spec, depth) {
+ if (depth == 0) {
+ // Skip trivial case, used elsewhere
+ var ok = false;
+ for (var arrayNdx = 0; arrayNdx < spec.arrays.length; arrayNdx++) {
+ if (spec.arrays[arrayNdx].storage != glsVertexArrayTests.deArray.Storage.USER) {
+ ok = true;
+ break;
+ }
+ }
+
+ if (!ok)
+ return;
+
+ var name = this.getTestName(spec);
+ var desc = this.getTestName(spec);
+
+ this.addChild(
+ new glsVertexArrayTests.MultiVertexArrayTest(
+ spec, name, desc
+ )
+ );
+ return;
+ }
+
+ var storages = [
+ //glsVertexArrayTests.deArray.Storage.USER, Not supported in WebGL 2.0
+ glsVertexArrayTests.deArray.Storage.BUFFER
+ ];
+
+ for (var storageNdx = 0; storageNdx < storages.length; storageNdx++) {
+ var arraySpec = new glsVertexArrayTests.MultiVertexArrayTest.Spec.ArraySpec(
+ glsVertexArrayTests.deArray.InputType.FLOAT,
+ glsVertexArrayTests.deArray.OutputType.VEC2,
+ storages[storageNdx],
+ glsVertexArrayTests.deArray.Usage.DYNAMIC_DRAW,
+ 2,
+ 0,
+ 0,
+ false,
+ glsVertexArrayTests.GLValue.getMinValue(glsVertexArrayTests.deArray.InputType.FLOAT),
+ glsVertexArrayTests.GLValue.getMaxValue(glsVertexArrayTests.deArray.InputType.FLOAT)
+ );
+
+ var _spec = spec;
+ _spec.arrays.push(arraySpec);
+ this.addStorageCases(_spec, depth - 1);
+ }
+ };
+
+ /**
+ * init
+ */
+ es3fVertexArrayTests.MultiVertexArrayStorageTests.prototype.init = function() {
+ // Test different storages
+ var arrayCounts = [3];
+
+ var spec = new glsVertexArrayTests.MultiVertexArrayTest.Spec();
+
+ spec.primitive = glsVertexArrayTests.deArray.Primitive.TRIANGLES;
+ spec.drawCount = 256;
+ spec.first = 0;
+
+ for (var arrayCountNdx = 0; arrayCountNdx < arrayCounts.length; arrayCountNdx++)
+ this.addStorageCases(spec, arrayCounts[arrayCountNdx]);
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fVertexArrayTests.MultiVertexArrayStrideTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'multiple_attributes.stride', 'Strides');
+ this.makeExecutable();
+ };
+
+ es3fVertexArrayTests.MultiVertexArrayStrideTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fVertexArrayTests.MultiVertexArrayStrideTests.prototype.constructor = es3fVertexArrayTests.MultiVertexArrayStrideTests;
+
+ /**
+ * @param {glsVertexArrayTests.MultiVertexArrayTest.Spec} spec
+ * @return {string}
+ */
+ es3fVertexArrayTests.MultiVertexArrayStrideTests.prototype.getTestName = function(spec) {
+ var name = '';
+
+ name += spec.arrays.length;
+
+ for (var arrayNdx = 0; arrayNdx < spec.arrays.length; arrayNdx++) {
+ name += '_' +
+ glsVertexArrayTests.deArray.inputTypeToString(spec.arrays[arrayNdx].inputType) +
+ spec.arrays[arrayNdx].componentCount + '_' +
+ spec.arrays[arrayNdx].stride;
+ }
+
+ return name;
+ };
+
+ /**
+ * init
+ */
+ es3fVertexArrayTests.MultiVertexArrayStrideTests.prototype.init = function() {
+ // Test different strides, with multiple arrays, input types??
+ var arrayCounts = [3];
+
+ var spec = new glsVertexArrayTests.MultiVertexArrayTest.Spec();
+
+ spec.primitive = glsVertexArrayTests.deArray.Primitive.TRIANGLES;
+ spec.drawCount = 256;
+ spec.first = 0;
+
+ for (var arrayCountNdx = 0; arrayCountNdx < arrayCounts.length; arrayCountNdx++)
+ this.addStrideCases(spec, arrayCounts[arrayCountNdx]);
+ };
+
+ /**
+ * @param {glsVertexArrayTests.MultiVertexArrayTest.Spec} spec
+ * @param {number} depth
+ */
+ es3fVertexArrayTests.MultiVertexArrayStrideTests.prototype.addStrideCases = function(spec, depth) {
+ if (depth == 0) {
+ var name = this.getTestName(spec);
+ var desc = this.getTestName(spec);
+ this.addChild(
+ new glsVertexArrayTests.MultiVertexArrayTest(
+ spec, name, desc
+ )
+ );
+ return;
+ }
+
+ var strides = [0, -1, 17, 32];
+ var inputType = glsVertexArrayTests.deArray.InputType.FLOAT;
+
+ for (var strideNdx = 0; strideNdx < strides.length; strideNdx++) {
+ var componentCount = 2;
+ var stride = strides[strideNdx] >= 0 ? strides[strideNdx] : componentCount * glsVertexArrayTests.deArray.inputTypeSize(glsVertexArrayTests.deArray.InputType.FLOAT);
+ var arraySpec = new glsVertexArrayTests.MultiVertexArrayTest.Spec.ArraySpec(
+ inputType,
+ glsVertexArrayTests.deArray.OutputType.VEC2,
+ glsVertexArrayTests.deArray.Storage.BUFFER, //USER storage not supported in WebGL 2.0
+ glsVertexArrayTests.deArray.Usage.DYNAMIC_DRAW,
+ componentCount,
+ 0,
+ stride,
+ false,
+ glsVertexArrayTests.GLValue.getMinValue(glsVertexArrayTests.deArray.InputType.FLOAT),
+ glsVertexArrayTests.GLValue.getMaxValue(glsVertexArrayTests.deArray.InputType.FLOAT)
+ );
+
+ /** @type {boolean} */ var aligned = (stride % glsVertexArrayTests.deArray.inputTypeSize(inputType)) == 0;
+ if (aligned) {
+ var _spec = /** @type {glsVertexArrayTests.MultiVertexArrayTest.Spec} */ (deUtil.clone(spec)); //To assign spec by value;
+ _spec.arrays.push(arraySpec);
+ this.addStrideCases(_spec, depth - 1);
+ }
+ }
+ };
+
+ /**
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fVertexArrayTests.MultiVertexArrayOutputTests = function() {
+ tcuTestCase.DeqpTest.call(this, 'multiple_attributes.input_types', 'input types');
+ this.makeExecutable();
+ };
+
+ es3fVertexArrayTests.MultiVertexArrayOutputTests.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fVertexArrayTests.MultiVertexArrayOutputTests.prototype.constructor = es3fVertexArrayTests.MultiVertexArrayOutputTests;
+
+ /**
+ * @param {glsVertexArrayTests.MultiVertexArrayTest.Spec} spec
+ * @return {string}
+ */
+ es3fVertexArrayTests.MultiVertexArrayOutputTests.prototype.getTestName = function(spec) {
+ var name = '';
+
+ name += spec.arrays.length;
+
+ for (var arrayNdx = 0; arrayNdx < spec.arrays.length; arrayNdx++) {
+ name += '_' +
+ glsVertexArrayTests.deArray.inputTypeToString(spec.arrays[arrayNdx].inputType) +
+ spec.arrays[arrayNdx].componentCount + '_' +
+ glsVertexArrayTests.deArray.outputTypeToString(spec.arrays[arrayNdx].outputType);
+ }
+
+ return name;
+ };
+
+ /**
+ * init
+ */
+ es3fVertexArrayTests.MultiVertexArrayOutputTests.prototype.init = function() {
+ // Test different input types, with multiple arrays
+ var arrayCounts = [3];
+
+ var spec = new glsVertexArrayTests.MultiVertexArrayTest.Spec();
+
+ spec.primitive = glsVertexArrayTests.deArray.Primitive.TRIANGLES;
+ spec.drawCount = 256;
+ spec.first = 0;
+
+ for (var arrayCountNdx = 0; arrayCountNdx < arrayCounts.length; arrayCountNdx++)
+ this.addInputTypeCases(spec, arrayCounts[arrayCountNdx]);
+ };
+
+ /**
+ * @param {glsVertexArrayTests.MultiVertexArrayTest.Spec} spec
+ * @param {number} depth
+ */
+ es3fVertexArrayTests.MultiVertexArrayOutputTests.prototype.addInputTypeCases = function(spec, depth) {
+ if (depth == 0) {
+ var name = this.getTestName(spec);
+ var desc = this.getTestName(spec);
+ this.addChild(
+ new glsVertexArrayTests.MultiVertexArrayTest(
+ spec, name, desc
+ )
+ );
+ return;
+ }
+
+ var inputTypes = [
+ glsVertexArrayTests.deArray.InputType.BYTE,
+ glsVertexArrayTests.deArray.InputType.SHORT,
+ glsVertexArrayTests.deArray.InputType.UNSIGNED_BYTE,
+ glsVertexArrayTests.deArray.InputType.UNSIGNED_SHORT
+ ];
+
+ for (var inputTypeNdx = 0; inputTypeNdx < inputTypes.length; inputTypeNdx++) {
+ var arraySpec = new glsVertexArrayTests.MultiVertexArrayTest.Spec.ArraySpec(
+ inputTypes[inputTypeNdx],
+ glsVertexArrayTests.deArray.OutputType.VEC2,
+ glsVertexArrayTests.deArray.Storage.BUFFER, //USER storage not supported in WebGL 2.0
+ glsVertexArrayTests.deArray.Usage.DYNAMIC_DRAW,
+ 2,
+ 0,
+ 0,
+ false,
+ glsVertexArrayTests.GLValue.getMinValue(inputTypes[inputTypeNdx]),
+ glsVertexArrayTests.GLValue.getMaxValue(inputTypes[inputTypeNdx])
+ );
+
+ var _spec = /** @type {glsVertexArrayTests.MultiVertexArrayTest.Spec} */ (deUtil.clone(spec));
+ _spec.arrays.push(arraySpec);
+ this.addInputTypeCases(_spec, depth - 1);
+ }
+ };
+
+ /**
+ * es3fVertexArrayTests.VertexArrayTestGroup
+ * @constructor
+ * @extends {tcuTestCase.DeqpTest}
+ */
+ es3fVertexArrayTests.VertexArrayTestGroup = function() {
+ tcuTestCase.DeqpTest.call(this, 'vertex_arrays', 'Vertex array and array tests');
+ this.makeExecutable();
+ };
+
+ es3fVertexArrayTests.VertexArrayTestGroup.prototype = Object.create(tcuTestCase.DeqpTest.prototype);
+ es3fVertexArrayTests.VertexArrayTestGroup.prototype.constructor = es3fVertexArrayTests.VertexArrayTestGroup;
+
+ /**
+ * init
+ */
+ es3fVertexArrayTests.VertexArrayTestGroup.prototype.init = function() {
+ this.addChild(new es3fVertexArrayTests.SingleVertexArrayStrideTests());
+ this.addChild(new es3fVertexArrayTests.SingleVertexArrayNormalizeTests());
+
+ // Test output types with different input types, component counts and storage, Usage?, Precision?, float?
+ var inputTypes = [
+ glsVertexArrayTests.deArray.InputType.FLOAT,
+ glsVertexArrayTests.deArray.InputType.SHORT,
+ glsVertexArrayTests.deArray.InputType.BYTE,
+ glsVertexArrayTests.deArray.InputType.UNSIGNED_SHORT,
+ glsVertexArrayTests.deArray.InputType.UNSIGNED_BYTE,
+ glsVertexArrayTests.deArray.InputType.UNSIGNED_INT,
+ glsVertexArrayTests.deArray.InputType.INT,
+ glsVertexArrayTests.deArray.InputType.HALF,
+ glsVertexArrayTests.deArray.InputType.UNSIGNED_INT_2_10_10_10,
+ glsVertexArrayTests.deArray.InputType.INT_2_10_10_10
+ ];
+ for (var inputTypeNdx = 0; inputTypeNdx < inputTypes.length; inputTypeNdx++) {
+ this.addChild(new es3fVertexArrayTests.SingleVertexArrayOutputTypeGroup(inputTypes[inputTypeNdx]));
+ }
+
+ /** @type {Array<glsVertexArrayTests.deArray.Usage>} */ var usages = [
+ glsVertexArrayTests.deArray.Usage.STATIC_DRAW,
+ glsVertexArrayTests.deArray.Usage.STREAM_DRAW,
+ glsVertexArrayTests.deArray.Usage.DYNAMIC_DRAW,
+ glsVertexArrayTests.deArray.Usage.STATIC_COPY,
+ glsVertexArrayTests.deArray.Usage.STREAM_COPY,
+ glsVertexArrayTests.deArray.Usage.DYNAMIC_COPY,
+ glsVertexArrayTests.deArray.Usage.STATIC_READ,
+ glsVertexArrayTests.deArray.Usage.STREAM_READ,
+ glsVertexArrayTests.deArray.Usage.DYNAMIC_READ
+ ];
+ for (var usageNdx = 0; usageNdx < usages.length; usageNdx++) {
+ this.addChild(new es3fVertexArrayTests.SingleVertexArrayUsageGroup(usages[usageNdx]));
+ }
+
+ this.addChild(new es3fVertexArrayTests.SingleVertexArrayOffsetTests());
+ this.addChild(new es3fVertexArrayTests.SingleVertexArrayFirstTests());
+
+ this.addChild(new es3fVertexArrayTests.MultiVertexArrayCountTests());
+ this.addChild(new es3fVertexArrayTests.MultiVertexArrayStorageTests());
+ this.addChild(new es3fVertexArrayTests.MultiVertexArrayStrideTests());
+ this.addChild(new es3fVertexArrayTests.MultiVertexArrayOutputTests());
+ };
+
+ /**
+ * Create and execute the test cases
+ * @param {WebGL2RenderingContext} context
+ */
+ es3fVertexArrayTests.run = function(context, range) {
+ gl = context;
+ //Set up root Test
+ var state = tcuTestCase.runner;
+
+ var test = new es3fVertexArrayTests.VertexArrayTestGroup();
+ var testName = test.fullName();
+ var testDescription = test.getDescription();
+ state.testCases = test;
+ state.testName = testName;
+
+ //Set up name and description of this test series.
+ setCurrentTestName(testName);
+ description(testDescription);
+
+ try {
+ if (range)
+ state.setRange(range);
+ //Run test cases
+ tcuTestCase.runTestCases();
+ } catch (err) {
+ testFailedOptions('Failed to es3fVertexArrayTests.run tests', false);
+ tcuTestCase.runner.terminate();
+ }
+ };
+
+});
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer.html
new file mode 100644
index 0000000000..7908636028
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer.html
@@ -0,0 +1,32 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContextWithWrapperThatThrowsOnGLError('canvas', null, 2);
+
+
+ try {
+ functional.gles3.es3fFboColorbufferTests.run(gl);
+ }
+ catch(err)
+ {
+ bufferedLogToConsole(err);
+ }
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/00_test_list.txt
new file mode 100644
index 0000000000..d6d590a077
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/00_test_list.txt
@@ -0,0 +1,26 @@
+clear.html
+tex2d_00.html
+tex2d_01.html
+tex2d_02.html
+tex2d_03.html
+tex2d_04.html
+tex2d_05.html
+texcube_00.html
+texcube_01.html
+texcube_02.html
+texcube_03.html
+texcube_04.html
+texcube_05.html
+tex2darray_00.html
+tex2darray_01.html
+tex2darray_02.html
+tex2darray_03.html
+tex2darray_04.html
+tex2darray_05.html
+tex3d_00.html
+tex3d_01.html
+tex3d_02.html
+tex3d_03.html
+tex3d_04.html
+tex3d_05.html
+blend.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/blend.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/blend.html
new file mode 100644
index 0000000000..4826cf0cb7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/blend.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [25, 26]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/clear.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/clear.html
new file mode 100644
index 0000000000..f431afb364
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/clear.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/fbocolorbuffer_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/fbocolorbuffer_test_generator.py
new file mode 100644
index 0000000000..9307b8d3f4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/fbocolorbuffer_test_generator.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for fbocolorbuffer* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'clear',
+ 'tex2d',
+ 'texcube',
+ 'tex2darray',
+ 'tex3d',
+ 'blend',
+]
+
+_GROUP_TEST_COUNTS = [
+ 1,
+ 6,
+ 6,
+ 6,
+ 6,
+ 1
+]
+
+def GenerateFilename(group, count, index):
+ """Generate test filename."""
+ filename = group
+ assert index >= 0 and index < count
+ if count > 1:
+ index_str = str(index)
+ if index < 10:
+ index_str = "0" + index_str
+ filename += "_" + index_str
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ assert len(_GROUPS) == len(_GROUP_TEST_COUNTS)
+ test_index = 0
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ group = _GROUPS[ii]
+ count = _GROUP_TEST_COUNTS[ii]
+ for index in range(count):
+ filename = GenerateFilename(group, count, index)
+ filelist.append(filename)
+ WriteTest(filename, test_index, test_index + 1)
+ test_index += 1
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_00.html
new file mode 100644
index 0000000000..b9918b2dd7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_00.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_01.html
new file mode 100644
index 0000000000..653f89e2a9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_01.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_02.html
new file mode 100644
index 0000000000..2e955cb8f0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_02.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_03.html
new file mode 100644
index 0000000000..993108e86f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_03.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_04.html
new file mode 100644
index 0000000000..d7f5b2782f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_04.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_05.html
new file mode 100644
index 0000000000..1d8bdcbaab
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2d_05.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_00.html
new file mode 100644
index 0000000000..5e42f0021c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_00.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [13, 14]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_01.html
new file mode 100644
index 0000000000..e01cee3b22
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_01.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [14, 15]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_02.html
new file mode 100644
index 0000000000..2f9dd6061c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_02.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [15, 16]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_03.html
new file mode 100644
index 0000000000..0f9b76857e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_03.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [16, 17]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_04.html
new file mode 100644
index 0000000000..82ef5b6cf7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_04.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [17, 18]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_05.html
new file mode 100644
index 0000000000..28668bd635
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex2darray_05.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [18, 19]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_00.html
new file mode 100644
index 0000000000..98c04df0e7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_00.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [19, 20]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_01.html
new file mode 100644
index 0000000000..adb01c169e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_01.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [20, 21]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_02.html
new file mode 100644
index 0000000000..87a7e291e9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_02.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [21, 22]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_03.html
new file mode 100644
index 0000000000..b7f7f18d8f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_03.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [22, 23]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_04.html
new file mode 100644
index 0000000000..a0a4473857
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_04.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [23, 24]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_05.html
new file mode 100644
index 0000000000..91ce46cc33
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/tex3d_05.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [24, 25]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_00.html
new file mode 100644
index 0000000000..0ff04bee2d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_00.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_01.html
new file mode 100644
index 0000000000..38512eb0ac
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_01.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_02.html
new file mode 100644
index 0000000000..2cf3fa750e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_02.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [9, 10]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_03.html
new file mode 100644
index 0000000000..2e55800859
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_03.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [10, 11]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_04.html
new file mode 100644
index 0000000000..9602acaf25
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_04.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [11, 12]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_05.html
new file mode 100644
index 0000000000..a77a1bd248
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocolorbuffer/texcube_05.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fbocolorbuffer_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Color Buffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboColorbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+var ext = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboColorbufferTests.run(gl, [12, 13]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocompleteness.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocompleteness.html
new file mode 100644
index 0000000000..40dc055543
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbocompleteness.html
@@ -0,0 +1,32 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Completeness Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboCompletenessTests');</script>
+<script>goog.require('modules.shared.glsFboUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+
+ var wtu = WebGLTestUtils;
+ var gl = wtu.create3DContext('canvas', null, 2);
+
+ try {
+ functional.gles3.es3fFboCompletenessTests.initGlDependents(gl);
+ functional.gles3.es3fFboCompletenessTests.run(gl);
+ }
+ catch(err) {
+ bufferedLogToConsole(err);
+ }
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbodepthbuffer.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbodepthbuffer.html
new file mode 100644
index 0000000000..e74b8285c0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbodepthbuffer.html
@@ -0,0 +1,32 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Depthbuffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboDepthbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContextWithWrapperThatThrowsOnGLError('canvas', null, 2);
+
+
+ try {
+ functional.gles3.es3fFboDepthbufferTests.run(gl);
+ }
+ catch(err)
+ {
+ bufferedLogToConsole(err);
+ }
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/00_test_list.txt
new file mode 100644
index 0000000000..189ebc1d17
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/00_test_list.txt
@@ -0,0 +1,7 @@
+default.html
+whole.html
+sub.html
+format_00.html
+format_01.html
+format_02.html
+target.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/default.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/default.html
new file mode 100644
index 0000000000..ea07a5f6db
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/default.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fboinvalidate_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Invalidate Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboInvalidateTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="128" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {stencil: true}, 2);
+var extention = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboInvalidateTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/fboinvalidate_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/fboinvalidate_test_generator.py
new file mode 100644
index 0000000000..ddb7efa091
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/fboinvalidate_test_generator.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for fboinvalidate* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from fboinvalidate_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Invalidate Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboInvalidateTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="128" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {stencil: true}, 2);
+var extention = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboInvalidateTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'default',
+ 'whole',
+ 'sub',
+ 'format',
+ 'target',
+]
+
+_GROUP_TEST_COUNTS = [
+ 1,
+ 1,
+ 1,
+ 3,
+ 1
+]
+
+def GenerateFilename(group, count, index):
+ """Generate test filename."""
+ filename = group
+ assert index >= 0 and index < count
+ if count > 1:
+ index_str = str(index)
+ if index < 10:
+ index_str = "0" + index_str
+ filename += "_" + index_str
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ assert len(_GROUPS) == len(_GROUP_TEST_COUNTS)
+ test_index = 0
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ group = _GROUPS[ii]
+ count = _GROUP_TEST_COUNTS[ii]
+ for index in range(count):
+ filename = GenerateFilename(group, count, index)
+ filelist.append(filename)
+ WriteTest(filename, test_index, test_index + 1)
+ test_index += 1
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/format_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/format_00.html
new file mode 100644
index 0000000000..50a4fad63d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/format_00.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fboinvalidate_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Invalidate Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboInvalidateTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="128" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {stencil: true}, 2);
+var extention = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboInvalidateTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/format_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/format_01.html
new file mode 100644
index 0000000000..2a130faadb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/format_01.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fboinvalidate_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Invalidate Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboInvalidateTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="128" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {stencil: true}, 2);
+var extention = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboInvalidateTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/format_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/format_02.html
new file mode 100644
index 0000000000..7aecfbf1a5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/format_02.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fboinvalidate_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Invalidate Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboInvalidateTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="128" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {stencil: true}, 2);
+var extention = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboInvalidateTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/sub.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/sub.html
new file mode 100644
index 0000000000..0a883c0c44
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/sub.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fboinvalidate_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Invalidate Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboInvalidateTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="128" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {stencil: true}, 2);
+var extention = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboInvalidateTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/target.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/target.html
new file mode 100644
index 0000000000..e36c335d4f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/target.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fboinvalidate_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Invalidate Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboInvalidateTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="128" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {stencil: true}, 2);
+var extention = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboInvalidateTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/whole.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/whole.html
new file mode 100644
index 0000000000..2792fa7652
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fboinvalidate/whole.html
@@ -0,0 +1,32 @@
+<!--
+
+This file is auto-generated from fboinvalidate_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL FBO Invalidate Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboInvalidateTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="128" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {stencil: true}, 2);
+var extention = gl.getExtension('EXT_color_buffer_float');
+
+functional.gles3.es3fFboInvalidateTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbomultisample.2_samples.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbomultisample.2_samples.html
new file mode 100644
index 0000000000..1de885749a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbomultisample.2_samples.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fbo Multisample Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboMultisampleTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="119" height="131"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboMultisampleTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbomultisample.4_samples.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbomultisample.4_samples.html
new file mode 100644
index 0000000000..5e8d75c691
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbomultisample.4_samples.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fbo Multisample Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboMultisampleTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="119" height="131"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboMultisampleTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbomultisample.8_samples.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbomultisample.8_samples.html
new file mode 100644
index 0000000000..c1fb9e70f2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbomultisample.8_samples.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fbo Multisample Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboMultisampleTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="119" height="131"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboMultisampleTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/00_test_list.txt
new file mode 100644
index 0000000000..65e66c8949
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/00_test_list.txt
@@ -0,0 +1,18 @@
+stencil_clear.html
+shared_colorbuffer_clear.html
+shared_colorbuffer_00.html
+shared_colorbuffer_01.html
+shared_colorbuffer_02.html
+shared_depth_stencil.html
+resize_00.html
+resize_01.html
+resize_02.html
+resize_03.html
+recreate_color_00.html
+recreate_color_01.html
+recreate_color_02.html
+recreate_color_03.html
+recreate_color_04.html
+recreate_color_05.html
+recreate_color_06.html
+recreate_depth_stencil.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/fborender_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/fborender_test_generator.py
new file mode 100644
index 0000000000..a1065d4629
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/fborender_test_generator.py
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for fborender* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'stencil_clear',
+ 'shared_colorbuffer_clear',
+ 'shared_colorbuffer',
+ 'shared_depth_stencil',
+ 'resize',
+ 'recreate_color',
+ 'recreate_depth_stencil'
+]
+
+_GROUP_TEST_COUNTS = [
+ 1,
+ 1,
+ 3,
+ 1,
+ 4,
+ 7,
+ 1
+]
+
+def GenerateFilename(group, count, index):
+ """Generate test filename."""
+ filename = group
+ assert index >= 0 and index < count
+ if count > 1:
+ index_str = str(index)
+ if index < 10:
+ index_str = "0" + index_str
+ filename += "_" + index_str
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ assert len(_GROUPS) == len(_GROUP_TEST_COUNTS)
+ test_index = 0
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ group = _GROUPS[ii]
+ count = _GROUP_TEST_COUNTS[ii]
+ for index in range(count):
+ filename = GenerateFilename(group, count, index)
+ filelist.append(filename)
+ WriteTest(filename, test_index, test_index + 1)
+ test_index += 1
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_00.html
new file mode 100644
index 0000000000..e318ee0e6e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [10, 11]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_01.html
new file mode 100644
index 0000000000..9fb93d4863
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [11, 12]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_02.html
new file mode 100644
index 0000000000..08076ed79b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [12, 13]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_03.html
new file mode 100644
index 0000000000..3c72f2bcab
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [13, 14]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_04.html
new file mode 100644
index 0000000000..1007e8c749
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [14, 15]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_05.html
new file mode 100644
index 0000000000..1ec97a5912
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_05.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [15, 16]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_06.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_06.html
new file mode 100644
index 0000000000..51ab8dec97
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_color_06.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [16, 17]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_depth_stencil.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_depth_stencil.html
new file mode 100644
index 0000000000..0e4ca74e54
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/recreate_depth_stencil.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [17, 18]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_00.html
new file mode 100644
index 0000000000..5d9bab23f2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_01.html
new file mode 100644
index 0000000000..94cb09653c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_02.html
new file mode 100644
index 0000000000..c1f4c13616
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_03.html
new file mode 100644
index 0000000000..4a6e2c81d7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/resize_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [9, 10]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_00.html
new file mode 100644
index 0000000000..54004f2d7c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_01.html
new file mode 100644
index 0000000000..b3ac79efbc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_02.html
new file mode 100644
index 0000000000..2f85029b1f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_clear.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_clear.html
new file mode 100644
index 0000000000..69a46744ca
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_colorbuffer_clear.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_depth_stencil.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_depth_stencil.html
new file mode 100644
index 0000000000..ff5c626431
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/shared_depth_stencil.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/stencil_clear.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/stencil_clear.html
new file mode 100644
index 0000000000..59c0819fe6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fborender/stencil_clear.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fborender_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Render Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboRenderTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="128"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboRenderTest.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbostatequery.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbostatequery.html
new file mode 100644
index 0000000000..95cc36b6a1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbostatequery.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fbo State Query Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboStateQueryTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboStateQueryTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbostencilbuffer.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbostencilbuffer.html
new file mode 100644
index 0000000000..251acc57dd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fbostencilbuffer.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fbo Stencilbuffer Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFboStencilbufferTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFboStencilbufferTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/floatstatequery.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/floatstatequery.html
new file mode 100644
index 0000000000..1fd326939e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/floatstatequery.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Float State Query Tests Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFloatStateQueryTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFloatStateQueryTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragdepth.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragdepth.html
new file mode 100644
index 0000000000..31ee874ae3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragdepth.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Frag Depth Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFragDepthTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFragDepthTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/00_test_list.txt
new file mode 100644
index 0000000000..8a410f6506
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/00_test_list.txt
@@ -0,0 +1,11 @@
+basic.float.html
+basic.fixed.html
+basic.int.html
+basic.uint.html
+array.float.html
+array.fixed.html
+array.int.html
+array.uint.html
+random_00.html
+random_01.html
+random_02.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.fixed.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.fixed.html
new file mode 100644
index 0000000000..ab4c17aec6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.fixed.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fragmentoutput_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fragment Output Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFragmentOutputTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFragmentOutputTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.float.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.float.html
new file mode 100644
index 0000000000..474fe78eec
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.float.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fragmentoutput_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fragment Output Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFragmentOutputTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFragmentOutputTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.int.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.int.html
new file mode 100644
index 0000000000..f100e804b6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.int.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fragmentoutput_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fragment Output Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFragmentOutputTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFragmentOutputTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.uint.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.uint.html
new file mode 100644
index 0000000000..fb3e5d96a6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/array.uint.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fragmentoutput_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fragment Output Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFragmentOutputTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFragmentOutputTests.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.fixed.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.fixed.html
new file mode 100644
index 0000000000..e58eda69c8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.fixed.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fragmentoutput_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fragment Output Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFragmentOutputTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFragmentOutputTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.float.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.float.html
new file mode 100644
index 0000000000..b0fe9a2fff
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.float.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fragmentoutput_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fragment Output Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFragmentOutputTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFragmentOutputTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.int.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.int.html
new file mode 100644
index 0000000000..871d8d0151
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.int.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fragmentoutput_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fragment Output Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFragmentOutputTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFragmentOutputTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.uint.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.uint.html
new file mode 100644
index 0000000000..915aa90d9e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/basic.uint.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fragmentoutput_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fragment Output Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFragmentOutputTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFragmentOutputTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/fragmentoutput_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/fragmentoutput_test_generator.py
new file mode 100644
index 0000000000..5f7ea66d23
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/fragmentoutput_test_generator.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for fragmentoutput* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from fragmentoutput_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fragment Output Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFragmentOutputTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFragmentOutputTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'basic.float',
+ 'basic.fixed',
+ 'basic.int',
+ 'basic.uint',
+ 'array.float',
+ 'array.fixed',
+ 'array.int',
+ 'array.uint',
+ 'random_00',
+ 'random_01',
+ 'random_02'
+]
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ filename = _GROUPS[ii] + '.html'
+ filelist.append(filename)
+ WriteTest(filename, ii, ii + 1)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/random_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/random_00.html
new file mode 100644
index 0000000000..d592e2f114
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/random_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fragmentoutput_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fragment Output Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFragmentOutputTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFragmentOutputTests.run(gl, [8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/random_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/random_01.html
new file mode 100644
index 0000000000..4e62689ce0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/random_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fragmentoutput_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fragment Output Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFragmentOutputTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFragmentOutputTests.run(gl, [9, 10]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/random_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/random_02.html
new file mode 100644
index 0000000000..3bcf9c5442
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/fragmentoutput/random_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from fragmentoutput_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fragment Output Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFragmentOutputTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFragmentOutputTests.run(gl, [10, 11]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/00_test_list.txt
new file mode 100644
index 0000000000..6aeeaf64ab
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/00_test_list.txt
@@ -0,0 +1,50 @@
+rect_00.html
+rect_01.html
+rect_02.html
+rect_03.html
+rect_04.html
+rect_05.html
+rect_06.html
+conversion_00.html
+conversion_01.html
+conversion_02.html
+conversion_03.html
+conversion_04.html
+conversion_05.html
+conversion_06.html
+conversion_07.html
+conversion_08.html
+conversion_09.html
+conversion_10.html
+conversion_11.html
+conversion_12.html
+conversion_13.html
+conversion_14.html
+conversion_15.html
+conversion_16.html
+conversion_17.html
+conversion_18.html
+conversion_19.html
+conversion_20.html
+conversion_21.html
+conversion_22.html
+conversion_23.html
+conversion_24.html
+conversion_25.html
+conversion_26.html
+conversion_27.html
+conversion_28.html
+conversion_29.html
+conversion_30.html
+conversion_31.html
+conversion_32.html
+conversion_33.html
+conversion_34.html
+depth_stencil.html
+default_framebuffer_00.html
+default_framebuffer_01.html
+default_framebuffer_02.html
+default_framebuffer_03.html
+default_framebuffer_04.html
+default_framebuffer_05.html
+default_framebuffer_06.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_00.html
new file mode 100644
index 0000000000..6124a65698
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_01.html
new file mode 100644
index 0000000000..d0389725fb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_02.html
new file mode 100644
index 0000000000..cebfd04d06
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [9, 10]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_03.html
new file mode 100644
index 0000000000..2539865a9a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [10, 11]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_04.html
new file mode 100644
index 0000000000..d98f9268d6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [11, 12]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_05.html
new file mode 100644
index 0000000000..6045c4a870
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_05.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [12, 13]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_06.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_06.html
new file mode 100644
index 0000000000..f851a73d5c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_06.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [13, 14]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_07.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_07.html
new file mode 100644
index 0000000000..900c2c1567
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_07.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [14, 15]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_08.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_08.html
new file mode 100644
index 0000000000..f9ea2cce4f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_08.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [15, 16]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_09.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_09.html
new file mode 100644
index 0000000000..f20d4bea67
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_09.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [16, 17]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_10.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_10.html
new file mode 100644
index 0000000000..1f15f08f1e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_10.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [17, 18]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_11.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_11.html
new file mode 100644
index 0000000000..9a8a2760c2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_11.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [18, 19]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_12.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_12.html
new file mode 100644
index 0000000000..d4954fb187
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_12.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [19, 20]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_13.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_13.html
new file mode 100644
index 0000000000..a68d778d84
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_13.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [20, 21]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_14.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_14.html
new file mode 100644
index 0000000000..5fbc4b1c68
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_14.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [21, 22]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_15.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_15.html
new file mode 100644
index 0000000000..0b31db5a2a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_15.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [22, 23]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_16.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_16.html
new file mode 100644
index 0000000000..31de2fb37e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_16.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [23, 24]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_17.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_17.html
new file mode 100644
index 0000000000..85939968f6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_17.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [24, 25]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_18.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_18.html
new file mode 100644
index 0000000000..303b1f9d22
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_18.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [25, 26]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_19.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_19.html
new file mode 100644
index 0000000000..4ca74e4ae1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_19.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [26, 27]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_20.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_20.html
new file mode 100644
index 0000000000..13dfe1137c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_20.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [27, 28]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_21.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_21.html
new file mode 100644
index 0000000000..717bcbbcce
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_21.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [28, 29]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_22.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_22.html
new file mode 100644
index 0000000000..8bf21f9e3b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_22.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [29, 30]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_23.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_23.html
new file mode 100644
index 0000000000..7238bdb419
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_23.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [30, 31]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_24.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_24.html
new file mode 100644
index 0000000000..2e7313a664
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_24.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [31, 32]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_25.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_25.html
new file mode 100644
index 0000000000..053dd4be5f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_25.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [32, 33]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_26.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_26.html
new file mode 100644
index 0000000000..c7f79eca6f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_26.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [33, 34]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_27.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_27.html
new file mode 100644
index 0000000000..f8c41645f7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_27.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [34, 35]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_28.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_28.html
new file mode 100644
index 0000000000..2222bb7f30
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_28.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [35, 36]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_29.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_29.html
new file mode 100644
index 0000000000..51d29810cd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_29.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [36, 37]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_30.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_30.html
new file mode 100644
index 0000000000..eae41bfcc6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_30.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [37, 38]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_31.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_31.html
new file mode 100644
index 0000000000..55e96090e3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_31.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [38, 39]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_32.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_32.html
new file mode 100644
index 0000000000..2ddd49fce8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_32.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [39, 40]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_33.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_33.html
new file mode 100644
index 0000000000..83a32646ae
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_33.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [40, 41]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_34.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_34.html
new file mode 100644
index 0000000000..062cb7f3ca
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/conversion_34.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [41, 42]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_00.html
new file mode 100644
index 0000000000..749c9bff5b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [43, 44]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_01.html
new file mode 100644
index 0000000000..42cf9a6471
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [44, 45]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_02.html
new file mode 100644
index 0000000000..3789b97c6c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [45, 46]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_03.html
new file mode 100644
index 0000000000..f1b0252daa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [46, 47]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_04.html
new file mode 100644
index 0000000000..60562a9998
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [47, 48]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_05.html
new file mode 100644
index 0000000000..7bd5c7db54
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_05.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [48, 49]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_06.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_06.html
new file mode 100644
index 0000000000..74645cf2c1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/default_framebuffer_06.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [49, 50]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/depth_stencil.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/depth_stencil.html
new file mode 100644
index 0000000000..fb09d67f70
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/depth_stencil.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [42, 43]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/frambufferblit_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/frambufferblit_test_generator.py
new file mode 100644
index 0000000000..5e347a0ca1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/frambufferblit_test_generator.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for framebufferblit* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'rect',
+ 'conversion',
+ 'depth_stencil',
+ 'default_framebuffer',
+]
+
+_GROUP_TEST_COUNTS = [
+ 7,
+ 35,
+ 1,
+ 7
+]
+
+def GenerateFilename(group, count, index):
+ """Generate test filename."""
+ filename = group
+ assert index >= 0 and index < count
+ if count > 1:
+ index_str = str(index)
+ if index < 10:
+ index_str = "0" + index_str
+ filename += "_" + index_str
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ assert len(_GROUPS) == len(_GROUP_TEST_COUNTS)
+ test_index = 0
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ group = _GROUPS[ii]
+ count = _GROUP_TEST_COUNTS[ii]
+ for index in range(count):
+ filename = GenerateFilename(group, count, index)
+ filelist.append(filename)
+ WriteTest(filename, test_index, test_index + 1)
+ test_index += 1
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_00.html
new file mode 100644
index 0000000000..c0076c02ea
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_01.html
new file mode 100644
index 0000000000..d2a53cedcf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_02.html
new file mode 100644
index 0000000000..b73eb396d6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_03.html
new file mode 100644
index 0000000000..86971ca0f0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_04.html
new file mode 100644
index 0000000000..c9239f32f3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_05.html
new file mode 100644
index 0000000000..b40353a15c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_05.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_06.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_06.html
new file mode 100644
index 0000000000..8fb90dda48
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/framebufferblit/rect_06.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from framebufferblit_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Framebuffer Blit Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fFramebufferBlitTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="200"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fFramebufferBlitTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/indexedstatequery.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/indexedstatequery.html
new file mode 100644
index 0000000000..ee57dcb183
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/indexedstatequery.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Indexed Integer Values Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fIndexedStateQueryTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fIndexedStateQueryTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/instancedrendering.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/instancedrendering.html
new file mode 100644
index 0000000000..6de0a016c4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/instancedrendering.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Instanced Rendering Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fInstancedRenderingTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fInstancedRenderingTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/integerstatequery.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/integerstatequery.html
new file mode 100644
index 0000000000..610ddf9888
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/integerstatequery.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Integer Values Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fIntegerStateQueryTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fIntegerStateQueryTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/internalformatquery.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/internalformatquery.html
new file mode 100644
index 0000000000..765dede408
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/internalformatquery.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Internalformat query tests Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fInternalFormatQueryTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fInternalFormatQueryTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/lifetime.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/lifetime.html
new file mode 100644
index 0000000000..7cf80807e0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/lifetime.html
@@ -0,0 +1,34 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Lifetime Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fLifetimeTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+testName = 'lifetime';
+setCurrentTestName(testName);
+description("Functional test: " + testName + ".");
+
+var wtu = WebGLTestUtils;
+/** @type {WebGL2RenderingContext} */ var gl = wtu.create3DContext('canvas', null, 2);
+
+ try{
+ functional.gles3.es3fLifetimeTests.run(gl);
+ }
+ catch(err)
+ {
+ bufferedLogToConsole(err);
+ }
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/00_test_list.txt
new file mode 100644
index 0000000000..6c5e238d0d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/00_test_list.txt
@@ -0,0 +1,6 @@
+# This file is auto-generated from multisample_test_generator.py
+# DO NOT EDIT!
+default_fbo.html
+fbo_4_samples.html
+fbo_8_samples.html
+fbo_max_samples.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/default_fbo.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/default_fbo.html
new file mode 100644
index 0000000000..71d3f06bf9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/default_fbo.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from multisample_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Multisample Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fMultisampleTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fMultisampleTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/fbo_4_samples.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/fbo_4_samples.html
new file mode 100644
index 0000000000..c021f57ba9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/fbo_4_samples.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from multisample_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Multisample Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fMultisampleTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fMultisampleTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/fbo_8_samples.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/fbo_8_samples.html
new file mode 100644
index 0000000000..adca5aeafe
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/fbo_8_samples.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from multisample_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Multisample Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fMultisampleTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fMultisampleTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/fbo_max_samples.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/fbo_max_samples.html
new file mode 100644
index 0000000000..32c75c721f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/fbo_max_samples.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from multisample_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Multisample Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fMultisampleTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fMultisampleTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/multisample_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/multisample_test_generator.py
new file mode 100755
index 0000000000..2107a572f0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/multisample/multisample_test_generator.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2021 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for multisample* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from multisample_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_DO_NOT_EDIT_TEST_LIST_WARNING = """# This file is auto-generated from multisample_test_generator.py
+# DO NOT EDIT!
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Multisample Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fMultisampleTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fMultisampleTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+# Note: must match CaseType in es3fMultisampleTests.js.
+_GROUPS = [
+ 'default_fbo',
+ 'fbo_4_samples',
+ 'fbo_8_samples',
+ 'fbo_max_samples',
+]
+
+def GenerateFilename(group):
+ """Generate test filename."""
+ filename = group
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ filename = GenerateFilename(_GROUPS[ii])
+ filelist.append(filename)
+ WriteTest(filename, ii, ii + 1)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write(_DO_NOT_EDIT_TEST_LIST_WARNING)
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativebufferapi.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativebufferapi.html
new file mode 100644
index 0000000000..f754359818
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativebufferapi.html
@@ -0,0 +1,30 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Negative Buffer API Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fNegativeBufferApiTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+
+ var wtu = WebGLTestUtils;
+ var gl = wtu.create3DContext('canvas', null, 2);
+
+ try {
+ functional.gles3.es3fNegativeBufferApiTests.run(gl);
+ }
+ catch(err) {
+ bufferedLogToConsole(err);
+ }
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativefragmentapi.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativefragmentapi.html
new file mode 100644
index 0000000000..91de0c29c2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativefragmentapi.html
@@ -0,0 +1,23 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Negative Fragment API Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fNegativeFragmentApiTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fNegativeFragmentApiTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativeshaderapi.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativeshaderapi.html
new file mode 100644
index 0000000000..a1d9fc66eb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativeshaderapi.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Negative Shader API Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fNegativeShaderApiTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fNegativeShaderApiTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativestateapi.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativestateapi.html
new file mode 100644
index 0000000000..d54090eaf8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativestateapi.html
@@ -0,0 +1,23 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Negative State API Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fNegativeStateApiTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fNegativeStateApiTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativetextureapi.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativetextureapi.html
new file mode 100644
index 0000000000..dd61480039
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativetextureapi.html
@@ -0,0 +1,30 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Negative Texture API Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fNegativeTextureApiTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+
+ var wtu = WebGLTestUtils;
+ var gl = wtu.create3DContext('canvas', null, 2);
+
+ try {
+ functional.gles3.es3fNegativeTextureApiTests.run(gl);
+ }
+ catch(err) {
+ bufferedLogToConsole(err);
+ }
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativevertexarrayapi.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativevertexarrayapi.html
new file mode 100644
index 0000000000..c93514cb85
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/negativevertexarrayapi.html
@@ -0,0 +1,30 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Negative Vertex Array API Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fNegativeVertexArrayApiTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+
+ var wtu = WebGLTestUtils;
+ var gl = wtu.create3DContext('canvas', null, 2);
+
+ try {
+ functional.gles3.es3fNegativeVertexArrayApiTests.run(gl);
+ }
+ catch(err) {
+ bufferedLogToConsole(err);
+ }
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/occlusionquery_conservative.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/occlusionquery_conservative.html
new file mode 100644
index 0000000000..d05abc128f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/occlusionquery_conservative.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Occlusion Query Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fOcclusionQueryTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {stencil: true, preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fOcclusionQueryTests.run(gl, [31, 62]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/occlusionquery_strict.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/occlusionquery_strict.html
new file mode 100644
index 0000000000..bc04e961ce
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/occlusionquery_strict.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Occlusion Query Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fOcclusionQueryTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {stencil: true, preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fOcclusionQueryTests.run(gl, [0, 31]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/pixelbufferobject.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/pixelbufferobject.html
new file mode 100644
index 0000000000..1d9dd317de
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/pixelbufferobject.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Pixel Buffer Object Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fPixelBufferObjectTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fPixelBufferObjectTest.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/00.html
new file mode 100644
index 0000000000..46ea49ed22
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from primitiverestart_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Primitive Restart Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fPrimitiveRestartTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fPrimitiveRestartTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/00_test_list.txt
new file mode 100644
index 0000000000..6812378afe
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/00_test_list.txt
@@ -0,0 +1,8 @@
+00.html
+01.html
+02.html
+03.html
+04.html
+05.html
+06.html
+07.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/01.html
new file mode 100644
index 0000000000..59c6331b63
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from primitiverestart_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Primitive Restart Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fPrimitiveRestartTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fPrimitiveRestartTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/02.html
new file mode 100644
index 0000000000..5552f59172
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from primitiverestart_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Primitive Restart Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fPrimitiveRestartTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fPrimitiveRestartTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/03.html
new file mode 100644
index 0000000000..c6b5fb2b9c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from primitiverestart_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Primitive Restart Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fPrimitiveRestartTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fPrimitiveRestartTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/04.html
new file mode 100644
index 0000000000..e7354067a6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from primitiverestart_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Primitive Restart Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fPrimitiveRestartTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fPrimitiveRestartTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/05.html
new file mode 100644
index 0000000000..4ed0938d0b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/05.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from primitiverestart_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Primitive Restart Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fPrimitiveRestartTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fPrimitiveRestartTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/06.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/06.html
new file mode 100644
index 0000000000..ed4039877b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/06.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from primitiverestart_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Primitive Restart Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fPrimitiveRestartTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fPrimitiveRestartTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/07.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/07.html
new file mode 100644
index 0000000000..bf8b47fb25
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/07.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from primitiverestart_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Primitive Restart Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fPrimitiveRestartTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fPrimitiveRestartTests.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/primitiverestart_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/primitiverestart_test_generator.py
new file mode 100644
index 0000000000..8eaf5ce245
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/primitiverestart/primitiverestart_test_generator.py
@@ -0,0 +1,84 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for primitiverestart* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from primitiverestart_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Primitive Restart Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fPrimitiveRestartTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fPrimitiveRestartTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_NUM_TESTS = 8
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ for ii in range(_NUM_TESTS):
+ index_str = str(ii)
+ if ii < 10:
+ index_str = "0" + index_str
+ filename = index_str + '.html'
+ filelist.append(filename)
+ WriteTest(filename, ii, ii + 1)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/rasterizerdiscard.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/rasterizerdiscard.html
new file mode 100644
index 0000000000..185a233404
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/rasterizerdiscard.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Rasterizer Discard Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fRasterizerDiscardTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {stencil: true}, 2);
+
+functional.gles3.es3fRasterizerDiscardTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/rbostatequery.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/rbostatequery.html
new file mode 100644
index 0000000000..bd11632053
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/rbostatequery.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Rbo State Query Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fRboStateQueryTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fRboStateQueryTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/readpixel.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/readpixel.html
new file mode 100644
index 0000000000..bbe1167f49
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/readpixel.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL ReadPixel Tests Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fReadPixelTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fReadPixelTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/samplerobject.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/samplerobject.html
new file mode 100644
index 0000000000..6f9187657a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/samplerobject.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Sampler Object Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fSamplerObjectTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fSamplerObjectTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/samplerstatequery.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/samplerstatequery.html
new file mode 100644
index 0000000000..c78debef2e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/samplerstatequery.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Sampler State Query Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fSamplerStateQueryTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fSamplerStateQueryTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderapi.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderapi.html
new file mode 100644
index 0000000000..d33e78148e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderapi.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader API Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderApiTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderApiTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderbuiltinvar.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderbuiltinvar.html
new file mode 100644
index 0000000000..f8a7be22e1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderbuiltinvar.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Built-in Var Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderBuiltinVarTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fShaderBuiltinVarTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadercommonfunction.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadercommonfunction.html
new file mode 100644
index 0000000000..0dbad257fa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadercommonfunction.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Common Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderCommonFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderCommonFunctionTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderderivate_dfdx.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderderivate_dfdx.html
new file mode 100644
index 0000000000..4c2c679ef4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderderivate_dfdx.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Derivate Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderDerivateTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderDerivateTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderderivate_dfdy.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderderivate_dfdy.html
new file mode 100644
index 0000000000..27a2da3ac1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderderivate_dfdy.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Derivate Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderDerivateTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderDerivateTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderderivate_fwidth.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderderivate_fwidth.html
new file mode 100644
index 0000000000..bb8b90f913
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderderivate_fwidth.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Derivate Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderDerivateTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderDerivateTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/00_test_list.txt
new file mode 100644
index 0000000000..da4d02b37d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/00_test_list.txt
@@ -0,0 +1,9 @@
+varying.html
+uniform.html
+tmp.html
+vec2.html
+vec3.html
+vec4.html
+mat_00.html
+mat_01.html
+mat_02.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/mat_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/mat_00.html
new file mode 100644
index 0000000000..2cd7e98fa2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/mat_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shaderindexing_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Indexing Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderIndexingTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderIndexingTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/mat_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/mat_01.html
new file mode 100644
index 0000000000..ee6c322e31
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/mat_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shaderindexing_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Indexing Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderIndexingTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderIndexingTests.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/mat_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/mat_02.html
new file mode 100644
index 0000000000..debdc57c2e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/mat_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shaderindexing_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Indexing Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderIndexingTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderIndexingTests.run(gl, [8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/shaderindexing_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/shaderindexing_test_generator.py
new file mode 100644
index 0000000000..beaace3469
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/shaderindexing_test_generator.py
@@ -0,0 +1,97 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for shaderindexing* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from shaderindexing_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Indexing Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderIndexingTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderIndexingTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'varying',
+ 'uniform',
+ 'tmp',
+ 'vec2',
+ 'vec3',
+ 'vec4',
+ 'mat_00',
+ 'mat_01',
+ 'mat_02',
+]
+
+def GenerateFilename(group):
+ """Generate test filename."""
+ filename = group
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ filename = GenerateFilename(_GROUPS[ii])
+ filelist.append(filename)
+ WriteTest(filename, ii, ii + 1)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/tmp.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/tmp.html
new file mode 100644
index 0000000000..679a8884f8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/tmp.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shaderindexing_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Indexing Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderIndexingTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderIndexingTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/uniform.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/uniform.html
new file mode 100644
index 0000000000..7c86a6f185
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/uniform.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shaderindexing_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Indexing Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderIndexingTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderIndexingTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/varying.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/varying.html
new file mode 100644
index 0000000000..eea9c022f8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/varying.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shaderindexing_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Indexing Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderIndexingTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderIndexingTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/vec2.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/vec2.html
new file mode 100644
index 0000000000..d2c80c1c4e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/vec2.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shaderindexing_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Indexing Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderIndexingTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderIndexingTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/vec3.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/vec3.html
new file mode 100644
index 0000000000..aaabf027a3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/vec3.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shaderindexing_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Indexing Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderIndexingTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderIndexingTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/vec4.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/vec4.html
new file mode 100644
index 0000000000..a896e726b4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderindexing/vec4.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shaderindexing_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Indexing Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderIndexingTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderIndexingTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderloop_do_while.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderloop_do_while.html
new file mode 100644
index 0000000000..6b57433852
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderloop_do_while.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Loop Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderLoopTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderLoopTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderloop_for.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderloop_for.html
new file mode 100644
index 0000000000..a2c5095c91
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderloop_for.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Loop Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderLoopTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderLoopTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderloop_while.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderloop_while.html
new file mode 100644
index 0000000000..fac36651cb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderloop_while.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Loop Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderLoopTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderLoopTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/00_test_list.txt
new file mode 100644
index 0000000000..dd0bb5a550
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/00_test_list.txt
@@ -0,0 +1,33 @@
+add_const.html
+add_uniform.html
+add_dynamic.html
+sub_const.html
+sub_uniform.html
+sub_dynamic.html
+mul_const_lowp.html
+mul_const_mediump.html
+mul_const_highp.html
+mul_uniform_lowp.html
+mul_uniform_mediump.html
+mul_uniform_highp.html
+mul_dynamic_lowp.html
+mul_dynamic_mediump.html
+mul_dynamic_highp.html
+div_const.html
+div_uniform.html
+div_dynamic.html
+matrixcompmult.html
+outerproduct.html
+transpose.html
+determinant.html
+inverse.html
+unary_addition.html
+negation.html
+pre_increment.html
+pre_decrement.html
+post_increment.html
+post_decrement.html
+add_assign.html
+sub_assign.html
+mul_assign.html
+div_assign.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_assign.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_assign.html
new file mode 100644
index 0000000000..bb70e4d681
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_assign.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [29, 30]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_const.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_const.html
new file mode 100644
index 0000000000..bf15cb29ab
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_const.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_dynamic.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_dynamic.html
new file mode 100644
index 0000000000..3deeb287aa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_dynamic.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_uniform.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_uniform.html
new file mode 100644
index 0000000000..bf459f6c6c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/add_uniform.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/determinant.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/determinant.html
new file mode 100644
index 0000000000..5b885f8322
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/determinant.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [21, 22]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_assign.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_assign.html
new file mode 100644
index 0000000000..2d913df799
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_assign.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [32, 33]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_const.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_const.html
new file mode 100644
index 0000000000..a958d75036
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_const.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [15, 16]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_dynamic.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_dynamic.html
new file mode 100644
index 0000000000..623c9a9bc0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_dynamic.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [17, 18]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_uniform.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_uniform.html
new file mode 100644
index 0000000000..4c77847c95
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/div_uniform.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [16, 17]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/inverse.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/inverse.html
new file mode 100644
index 0000000000..c14a19e2c9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/inverse.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [22, 23]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/matrixcompmult.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/matrixcompmult.html
new file mode 100644
index 0000000000..eab68d362a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/matrixcompmult.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [18, 19]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_assign.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_assign.html
new file mode 100644
index 0000000000..771a1556b6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_assign.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [31, 32]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_const_highp.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_const_highp.html
new file mode 100644
index 0000000000..80ff18f77a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_const_highp.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_const_lowp.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_const_lowp.html
new file mode 100644
index 0000000000..40559ebf7a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_const_lowp.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_const_mediump.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_const_mediump.html
new file mode 100644
index 0000000000..21efaef930
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_const_mediump.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_dynamic_highp.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_dynamic_highp.html
new file mode 100644
index 0000000000..e3b57badd9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_dynamic_highp.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [14, 15]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_dynamic_lowp.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_dynamic_lowp.html
new file mode 100644
index 0000000000..d1d3ce1068
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_dynamic_lowp.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [12, 13]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_dynamic_mediump.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_dynamic_mediump.html
new file mode 100644
index 0000000000..bf95faf774
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_dynamic_mediump.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [13, 14]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_uniform_highp.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_uniform_highp.html
new file mode 100644
index 0000000000..713d7d21ac
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_uniform_highp.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [11, 12]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_uniform_lowp.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_uniform_lowp.html
new file mode 100644
index 0000000000..8da434cd2b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_uniform_lowp.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [9, 10]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_uniform_mediump.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_uniform_mediump.html
new file mode 100644
index 0000000000..91f022cb45
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/mul_uniform_mediump.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [10, 11]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/negation.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/negation.html
new file mode 100644
index 0000000000..da0fdb831f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/negation.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [24, 25]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/outerproduct.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/outerproduct.html
new file mode 100644
index 0000000000..1e3a5bb56a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/outerproduct.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [19, 20]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/post_decrement.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/post_decrement.html
new file mode 100644
index 0000000000..8a5f7bd46f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/post_decrement.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [28, 29]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/post_increment.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/post_increment.html
new file mode 100644
index 0000000000..a379fdb882
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/post_increment.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [27, 28]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/pre_decrement.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/pre_decrement.html
new file mode 100644
index 0000000000..3921fb697f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/pre_decrement.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [26, 27]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/pre_increment.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/pre_increment.html
new file mode 100644
index 0000000000..ac06ee71b1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/pre_increment.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [25, 26]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/shadermatrix_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/shadermatrix_test_generator.py
new file mode 100644
index 0000000000..1cf1889c52
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/shadermatrix_test_generator.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for shadermatrix* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'add_const',
+ 'add_uniform',
+ 'add_dynamic',
+ 'sub_const',
+ 'sub_uniform',
+ 'sub_dynamic',
+ 'mul_const_lowp',
+ 'mul_const_mediump',
+ 'mul_const_highp',
+ 'mul_uniform_lowp',
+ 'mul_uniform_mediump',
+ 'mul_uniform_highp',
+ 'mul_dynamic_lowp',
+ 'mul_dynamic_mediump',
+ 'mul_dynamic_highp',
+ 'div_const',
+ 'div_uniform',
+ 'div_dynamic',
+ 'matrixcompmult',
+ 'outerproduct',
+ 'transpose',
+ 'determinant',
+ 'inverse',
+ 'unary_addition',
+ 'negation',
+ 'pre_increment',
+ 'pre_decrement',
+ 'post_increment',
+ 'post_decrement',
+ 'add_assign',
+ 'sub_assign',
+ 'mul_assign',
+ 'div_assign',
+]
+
+def GenerateFilename(group):
+ """Generate test filename."""
+ filename = group
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ filename = GenerateFilename(_GROUPS[ii])
+ filelist.append(filename)
+ WriteTest(filename, ii, ii + 1)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_assign.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_assign.html
new file mode 100644
index 0000000000..79bf1fd344
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_assign.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [30, 31]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_const.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_const.html
new file mode 100644
index 0000000000..f574f6126b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_const.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_dynamic.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_dynamic.html
new file mode 100644
index 0000000000..4408df4743
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_dynamic.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_uniform.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_uniform.html
new file mode 100644
index 0000000000..5d7c293d0c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/sub_uniform.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/transpose.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/transpose.html
new file mode 100644
index 0000000000..52465410fd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/transpose.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [20, 21]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/unary_addition.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/unary_addition.html
new file mode 100644
index 0000000000..1bcb526ebb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadermatrix/unary_addition.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadermatrix_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Matrix Test</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderMatrixTest');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderMatrixTest.run(gl, [23, 24]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/00_test_list.txt
new file mode 100644
index 0000000000..1c197d6b8e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/00_test_list.txt
@@ -0,0 +1,37 @@
+unary_operator_00.html
+unary_operator_01.html
+unary_operator_02.html
+binary_operator_00.html
+binary_operator_01.html
+binary_operator_02.html
+binary_operator_03.html
+binary_operator_04.html
+binary_operator_05.html
+binary_operator_06.html
+binary_operator_07.html
+binary_operator_08.html
+binary_operator_09.html
+binary_operator_10.html
+binary_operator_11.html
+binary_operator_12.html
+binary_operator_13.html
+binary_operator_14.html
+binary_operator_15.html
+angle_and_trigonometry_00.html
+angle_and_trigonometry_01.html
+angle_and_trigonometry_02.html
+angle_and_trigonometry_03.html
+exponential.html
+common_functions_00.html
+common_functions_01.html
+common_functions_02.html
+common_functions_03.html
+common_functions_04.html
+common_functions_05.html
+common_functions_06.html
+geometric.html
+float_compare.html
+int_compare.html
+bool_compare.html
+selection.html
+sequence.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_00.html
new file mode 100644
index 0000000000..04d3c3c26e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_00.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [19, 20]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_01.html
new file mode 100644
index 0000000000..a342a007be
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_01.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [20, 21]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_02.html
new file mode 100644
index 0000000000..a7273c649a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_02.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [21, 22]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_03.html
new file mode 100644
index 0000000000..6ca3ef247f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/angle_and_trigonometry_03.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [22, 23]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_00.html
new file mode 100644
index 0000000000..35fb8043c3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_00.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_01.html
new file mode 100644
index 0000000000..3740edea2c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_01.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_02.html
new file mode 100644
index 0000000000..1834fec65a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_02.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_03.html
new file mode 100644
index 0000000000..d4b3afca33
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_03.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_04.html
new file mode 100644
index 0000000000..bcc0d964da
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_04.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_05.html
new file mode 100644
index 0000000000..6f5a189327
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_05.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_06.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_06.html
new file mode 100644
index 0000000000..f5f2c1d8a3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_06.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [9, 10]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_07.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_07.html
new file mode 100644
index 0000000000..eb5933dc1b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_07.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [10, 11]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_08.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_08.html
new file mode 100644
index 0000000000..4a5726c562
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_08.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [11, 12]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_09.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_09.html
new file mode 100644
index 0000000000..c64fd1d6c8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_09.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [12, 13]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_10.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_10.html
new file mode 100644
index 0000000000..16bc768646
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_10.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [13, 14]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_11.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_11.html
new file mode 100644
index 0000000000..98a66ffe9b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_11.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [14, 15]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_12.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_12.html
new file mode 100644
index 0000000000..c463b6ff30
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_12.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [15, 16]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_13.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_13.html
new file mode 100644
index 0000000000..8caa497062
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_13.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [16, 17]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_14.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_14.html
new file mode 100644
index 0000000000..245db50eef
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_14.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [17, 18]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_15.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_15.html
new file mode 100644
index 0000000000..d11b9aae53
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/binary_operator_15.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [18, 19]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/bool_compare.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/bool_compare.html
new file mode 100644
index 0000000000..d8dbfc65b8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/bool_compare.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [34, 35]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_00.html
new file mode 100644
index 0000000000..f814bad597
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_00.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [24, 25]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_01.html
new file mode 100644
index 0000000000..1c2ce0f407
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_01.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [25, 26]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_02.html
new file mode 100644
index 0000000000..2b81002870
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_02.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [26, 27]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_03.html
new file mode 100644
index 0000000000..8818deae4e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_03.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [27, 28]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_04.html
new file mode 100644
index 0000000000..bbd4bbc68e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_04.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [28, 29]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_05.html
new file mode 100644
index 0000000000..b9ea2cc1d6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_05.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [29, 30]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_06.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_06.html
new file mode 100644
index 0000000000..e818da471a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/common_functions_06.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [30, 31]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/exponential.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/exponential.html
new file mode 100644
index 0000000000..849f44f9c8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/exponential.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [23, 24]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/float_compare.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/float_compare.html
new file mode 100644
index 0000000000..3510f51f9a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/float_compare.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [32, 33]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/geometric.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/geometric.html
new file mode 100644
index 0000000000..20ba764dec
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/geometric.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [31, 32]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/int_compare.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/int_compare.html
new file mode 100644
index 0000000000..50a4222e86
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/int_compare.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [33, 34]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/selection.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/selection.html
new file mode 100644
index 0000000000..dfea42d3a4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/selection.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [35, 36]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/sequence.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/sequence.html
new file mode 100644
index 0000000000..e1b61ed4a4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/sequence.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [36, 37]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/shaderoperator_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/shaderoperator_test_generator.py
new file mode 100644
index 0000000000..cdf21b0371
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/shaderoperator_test_generator.py
@@ -0,0 +1,127 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for shaderoperator* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'unary_operator_00',
+ 'unary_operator_01',
+ 'unary_operator_02',
+ 'binary_operator_00',
+ 'binary_operator_01',
+ 'binary_operator_02',
+ 'binary_operator_03',
+ 'binary_operator_04',
+ 'binary_operator_05',
+ 'binary_operator_06',
+ 'binary_operator_07',
+ 'binary_operator_08',
+ 'binary_operator_09',
+ 'binary_operator_10',
+ 'binary_operator_11',
+ 'binary_operator_12',
+ 'binary_operator_13',
+ 'binary_operator_14',
+ 'binary_operator_15',
+ 'angle_and_trigonometry_00',
+ 'angle_and_trigonometry_01',
+ 'angle_and_trigonometry_02',
+ 'angle_and_trigonometry_03',
+ 'exponential',
+ 'common_functions_00',
+ 'common_functions_01',
+ 'common_functions_02',
+ 'common_functions_03',
+ 'common_functions_04',
+ 'common_functions_05',
+ 'common_functions_06',
+ 'geometric',
+ 'float_compare',
+ 'int_compare',
+ 'bool_compare',
+ 'selection',
+ 'sequence',
+]
+
+def GenerateFilename(group):
+ """Generate test filename."""
+ filename = group
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ filename = GenerateFilename(_GROUPS[ii])
+ filelist.append(filename)
+ WriteTest(filename, ii, ii + 1)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/unary_operator_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/unary_operator_00.html
new file mode 100644
index 0000000000..8e80bcd623
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/unary_operator_00.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/unary_operator_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/unary_operator_01.html
new file mode 100644
index 0000000000..3dfee32749
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/unary_operator_01.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/unary_operator_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/unary_operator_02.html
new file mode 100644
index 0000000000..1b8c5e5e03
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderoperator/unary_operator_02.html
@@ -0,0 +1,33 @@
+<!--
+
+This file is auto-generated from shaderoperator_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Operator Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderOperatorTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderOperatorTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderpackingfunction.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderpackingfunction.html
new file mode 100644
index 0000000000..a07e9b1d81
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderpackingfunction.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Packing Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>
+goog.require('functional.gles3.es3fShaderPackingFunctionTests');
+</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderPackingFunctionTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderprecision_float.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderprecision_float.html
new file mode 100644
index 0000000000..ef78733716
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderprecision_float.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderPrecisionTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderprecision_int.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderprecision_int.html
new file mode 100644
index 0000000000..ec659017cf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderprecision_int.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderPrecisionTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderprecision_uint.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderprecision_uint.html
new file mode 100644
index 0000000000..3097ed7b19
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderprecision_uint.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Precision Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderPrecisionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderPrecisionTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderstatequery.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderstatequery.html
new file mode 100644
index 0000000000..325bb0bf25
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderstatequery.html
@@ -0,0 +1,31 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader State Query Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderStateQueryTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+ try {
+ functional.gles3.es3fShaderStateQueryTests.run(gl);
+ }
+ catch(err)
+ {
+ bufferedLogToConsole(err);
+ }
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderstruct.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderstruct.html
new file mode 100644
index 0000000000..e510ceb2d5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderstruct.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Struct Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderStructTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderStructTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderswitch.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderswitch.html
new file mode 100644
index 0000000000..714f9044d4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shaderswitch.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Switch Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderSwitchTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderSwitchTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/00_test_list.txt
new file mode 100644
index 0000000000..13a12534db
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/00_test_list.txt
@@ -0,0 +1,15 @@
+texture.html
+textureoffset.html
+textureproj.html
+textureprojoffset.html
+texturelod.html
+texturelodoffset.html
+textureprojlod.html
+textureprojlodoffset.html
+texturegrad.html
+texturegradoffset.html
+textureprojgrad.html
+textureprojgradoffset.html
+texelfetch.html
+texelfetchoffset.html
+texturesize.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/shadertexturefunction_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/shadertexturefunction_test_generator.py
new file mode 100644
index 0000000000..3b63359d7f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/shadertexturefunction_test_generator.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for shadertexturefunction* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'texture',
+ 'textureoffset',
+ 'textureproj',
+ 'textureprojoffset',
+ 'texturelod',
+ 'texturelodoffset',
+ 'textureprojlod',
+ 'textureprojlodoffset',
+ 'texturegrad',
+ 'texturegradoffset',
+ 'textureprojgrad',
+ 'textureprojgradoffset',
+ 'texelfetch',
+ 'texelfetchoffset',
+ 'texturesize'
+]
+
+def GenerateFilename(group):
+ """Generate test filename."""
+ filename = group
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ filename = GenerateFilename(_GROUPS[ii])
+ filelist.append(filename)
+ WriteTest(filename, ii, ii + 1)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texelfetch.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texelfetch.html
new file mode 100644
index 0000000000..6787012d51
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texelfetch.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [12, 13]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texelfetchoffset.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texelfetchoffset.html
new file mode 100644
index 0000000000..1d2e0de506
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texelfetchoffset.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [13, 14]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texture.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texture.html
new file mode 100644
index 0000000000..f5668b4d9d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texture.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturegrad.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturegrad.html
new file mode 100644
index 0000000000..7ef3d92104
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturegrad.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturegradoffset.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturegradoffset.html
new file mode 100644
index 0000000000..c016084bf9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturegradoffset.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [9, 10]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturelod.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturelod.html
new file mode 100644
index 0000000000..928bade495
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturelod.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturelodoffset.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturelodoffset.html
new file mode 100644
index 0000000000..23792c3d83
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturelodoffset.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureoffset.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureoffset.html
new file mode 100644
index 0000000000..61b9c6affa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureoffset.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureproj.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureproj.html
new file mode 100644
index 0000000000..676c7cde0c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureproj.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojgrad.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojgrad.html
new file mode 100644
index 0000000000..c68978abbb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojgrad.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [10, 11]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojgradoffset.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojgradoffset.html
new file mode 100644
index 0000000000..d2165e4f87
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojgradoffset.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [11, 12]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojlod.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojlod.html
new file mode 100644
index 0000000000..fe0fc76b2a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojlod.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojlodoffset.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojlodoffset.html
new file mode 100644
index 0000000000..a8d9760ab8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojlodoffset.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojoffset.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojoffset.html
new file mode 100644
index 0000000000..3b383a72da
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/textureprojoffset.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturesize.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturesize.html
new file mode 100644
index 0000000000..245a285b51
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/shadertexturefunction/texturesize.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from shadertexturefunction_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Shader Texture Function Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fShaderTextureFunctionTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fShaderTextureFunctionTests.run(gl, [14, 15]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/stringquery.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/stringquery.html
new file mode 100644
index 0000000000..79045db515
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/stringquery.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL String Query Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fStringQueryTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fStringQueryTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/sync.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/sync.html
new file mode 100644
index 0000000000..7d4c09f053
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/sync.html
@@ -0,0 +1,32 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Fence Sync Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fSyncTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+
+ try {
+ functional.gles3.es3fSyncTests.run(gl);
+ }
+ catch(err)
+ {
+ bufferedLogToConsole(err);
+ }
+
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/00_test_list.txt
new file mode 100644
index 0000000000..b446b8d6da
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/00_test_list.txt
@@ -0,0 +1,116 @@
+2d_formats_00.html
+2d_formats_01.html
+2d_formats_02.html
+2d_formats_03.html
+2d_formats_04.html
+2d_formats_05.html
+2d_formats_06.html
+2d_formats_07.html
+2d_formats_08.html
+2d_formats_09.html
+2d_sizes_00.html
+2d_sizes_01.html
+2d_sizes_02.html
+2d_sizes_03.html
+2d_sizes_04.html
+2d_sizes_05.html
+2d_combinations_00.html
+2d_combinations_01.html
+2d_combinations_02.html
+2d_combinations_03.html
+2d_combinations_04.html
+2d_combinations_05.html
+cube_formats_00.html
+cube_formats_01.html
+cube_formats_02.html
+cube_formats_03.html
+cube_formats_04.html
+cube_formats_05.html
+cube_formats_06.html
+cube_formats_07.html
+cube_formats_08.html
+cube_formats_09.html
+cube_sizes_00.html
+cube_sizes_01.html
+cube_sizes_02.html
+cube_sizes_03.html
+cube_sizes_04.html
+cube_combinations_00.html
+cube_combinations_01.html
+cube_combinations_02.html
+cube_combinations_03.html
+cube_combinations_04.html
+cube_combinations_05.html
+cube_no_edges_visible.html
+2d_array_formats_00.html
+2d_array_formats_01.html
+2d_array_formats_02.html
+2d_array_formats_03.html
+2d_array_formats_04.html
+2d_array_formats_05.html
+2d_array_formats_06.html
+2d_array_formats_07.html
+2d_array_formats_08.html
+2d_array_formats_09.html
+2d_array_sizes_00.html
+2d_array_sizes_01.html
+2d_array_sizes_02.html
+2d_array_sizes_03.html
+2d_array_sizes_04.html
+2d_array_combinations_00.html
+2d_array_combinations_01.html
+2d_array_combinations_02.html
+2d_array_combinations_03.html
+2d_array_combinations_04.html
+2d_array_combinations_05.html
+3d_formats_00.html
+3d_formats_01.html
+3d_formats_02.html
+3d_formats_03.html
+3d_formats_04.html
+3d_formats_05.html
+3d_formats_06.html
+3d_formats_07.html
+3d_formats_08.html
+3d_formats_09.html
+3d_sizes_00.html
+3d_sizes_01.html
+3d_sizes_02.html
+3d_sizes_03.html
+3d_sizes_04.html
+3d_combinations_00.html
+3d_combinations_01.html
+3d_combinations_02.html
+3d_combinations_03.html
+3d_combinations_04.html
+3d_combinations_05.html
+3d_combinations_06.html
+3d_combinations_07.html
+3d_combinations_08.html
+3d_combinations_09.html
+3d_combinations_10.html
+3d_combinations_11.html
+3d_combinations_12.html
+3d_combinations_13.html
+3d_combinations_14.html
+3d_combinations_15.html
+3d_combinations_16.html
+3d_combinations_17.html
+3d_combinations_18.html
+3d_combinations_19.html
+3d_combinations_20.html
+3d_combinations_21.html
+3d_combinations_22.html
+3d_combinations_23.html
+3d_combinations_24.html
+3d_combinations_25.html
+3d_combinations_26.html
+3d_combinations_27.html
+3d_combinations_28.html
+3d_combinations_29.html
+3d_combinations_30.html
+3d_combinations_31.html
+3d_combinations_32.html
+3d_combinations_33.html
+3d_combinations_34.html
+3d_combinations_35.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_00.html
new file mode 100644
index 0000000000..629813355b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [59, 60]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_01.html
new file mode 100644
index 0000000000..1fd04cdb6e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [60, 61]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_02.html
new file mode 100644
index 0000000000..63f3826d5e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [61, 62]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_03.html
new file mode 100644
index 0000000000..efe23d2a7d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [62, 63]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_04.html
new file mode 100644
index 0000000000..5fd151fb17
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [63, 64]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_05.html
new file mode 100644
index 0000000000..d6e8d71d18
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_combinations_05.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [64, 65]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_00.html
new file mode 100644
index 0000000000..7c822b2f57
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [44, 45]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_01.html
new file mode 100644
index 0000000000..adc218a46d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [45, 46]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_02.html
new file mode 100644
index 0000000000..afb3b67375
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [46, 47]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_03.html
new file mode 100644
index 0000000000..03acb11a19
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [47, 48]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_04.html
new file mode 100644
index 0000000000..b16f7e9ed2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [48, 49]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_05.html
new file mode 100644
index 0000000000..cafc3bd48d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_05.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [49, 50]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_06.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_06.html
new file mode 100644
index 0000000000..ce5e168b98
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_06.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [50, 51]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_07.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_07.html
new file mode 100644
index 0000000000..d4b59de12a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_07.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [51, 52]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_08.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_08.html
new file mode 100644
index 0000000000..121f0f74e8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_08.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [52, 53]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_09.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_09.html
new file mode 100644
index 0000000000..f306f70d80
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_formats_09.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [53, 54]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_00.html
new file mode 100644
index 0000000000..ce7c08c57b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [54, 55]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_01.html
new file mode 100644
index 0000000000..c83ad21fc3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [55, 56]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_02.html
new file mode 100644
index 0000000000..5c930d71c0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [56, 57]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_03.html
new file mode 100644
index 0000000000..e131614e10
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [57, 58]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_04.html
new file mode 100644
index 0000000000..651e97d04b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_array_sizes_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [58, 59]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_00.html
new file mode 100644
index 0000000000..b594c81df2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [16, 17]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_01.html
new file mode 100644
index 0000000000..f875ddc124
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [17, 18]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_02.html
new file mode 100644
index 0000000000..51150be084
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [18, 19]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_03.html
new file mode 100644
index 0000000000..e22d0d44d9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [19, 20]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_04.html
new file mode 100644
index 0000000000..e94ffc04f6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [20, 21]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_05.html
new file mode 100644
index 0000000000..429ae6e3e1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_combinations_05.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [21, 22]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_00.html
new file mode 100644
index 0000000000..4b58c6f787
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_01.html
new file mode 100644
index 0000000000..ef0d419d3a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_02.html
new file mode 100644
index 0000000000..f670313845
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_03.html
new file mode 100644
index 0000000000..fc10d2db75
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_04.html
new file mode 100644
index 0000000000..95227c1dd4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_05.html
new file mode 100644
index 0000000000..0397fbf6b2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_05.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_06.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_06.html
new file mode 100644
index 0000000000..7eb40d1433
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_06.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_07.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_07.html
new file mode 100644
index 0000000000..a236ac7c5c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_07.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_08.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_08.html
new file mode 100644
index 0000000000..8a29fe723c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_08.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_09.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_09.html
new file mode 100644
index 0000000000..4ae8227647
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_formats_09.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [9, 10]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_00.html
new file mode 100644
index 0000000000..8d2e2d736a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [10, 11]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_01.html
new file mode 100644
index 0000000000..87bc3f9a6a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [11, 12]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_02.html
new file mode 100644
index 0000000000..b4a9c90102
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [12, 13]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_03.html
new file mode 100644
index 0000000000..3831e58a2e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [13, 14]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_04.html
new file mode 100644
index 0000000000..77ce5f6b12
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [14, 15]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_05.html
new file mode 100644
index 0000000000..64f1b65a2f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/2d_sizes_05.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [15, 16]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_00.html
new file mode 100644
index 0000000000..e833feff80
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [80, 81]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_01.html
new file mode 100644
index 0000000000..141193d5ec
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [81, 82]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_02.html
new file mode 100644
index 0000000000..4913ab35eb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [82, 83]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_03.html
new file mode 100644
index 0000000000..b60af0ea21
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [83, 84]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_04.html
new file mode 100644
index 0000000000..5e4892249a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [84, 85]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_05.html
new file mode 100644
index 0000000000..d87584684f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_05.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [85, 86]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_06.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_06.html
new file mode 100644
index 0000000000..b1c2c808cb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_06.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [86, 87]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_07.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_07.html
new file mode 100644
index 0000000000..79a2be951b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_07.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [87, 88]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_08.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_08.html
new file mode 100644
index 0000000000..c32a25ab79
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_08.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [88, 89]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_09.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_09.html
new file mode 100644
index 0000000000..aa4c3c50d0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_09.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [89, 90]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_10.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_10.html
new file mode 100644
index 0000000000..3872150b75
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_10.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [90, 91]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_11.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_11.html
new file mode 100644
index 0000000000..30763a2ea7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_11.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [91, 92]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_12.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_12.html
new file mode 100644
index 0000000000..f252f529e4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_12.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [92, 93]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_13.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_13.html
new file mode 100644
index 0000000000..6c3e9b135e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_13.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [93, 94]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_14.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_14.html
new file mode 100644
index 0000000000..b4cb0d7573
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_14.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [94, 95]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_15.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_15.html
new file mode 100644
index 0000000000..2c4590dd41
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_15.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [95, 96]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_16.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_16.html
new file mode 100644
index 0000000000..c0838fc3f6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_16.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [96, 97]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_17.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_17.html
new file mode 100644
index 0000000000..48e924daae
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_17.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [97, 98]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_18.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_18.html
new file mode 100644
index 0000000000..9cd79ceb5b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_18.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [98, 99]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_19.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_19.html
new file mode 100644
index 0000000000..e224822c62
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_19.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [99, 100]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_20.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_20.html
new file mode 100644
index 0000000000..2c959a811a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_20.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [100, 101]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_21.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_21.html
new file mode 100644
index 0000000000..78c6f0a3d6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_21.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [101, 102]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_22.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_22.html
new file mode 100644
index 0000000000..9980e3a3a9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_22.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [102, 103]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_23.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_23.html
new file mode 100644
index 0000000000..08c647aff0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_23.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [103, 104]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_24.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_24.html
new file mode 100644
index 0000000000..fe81630d42
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_24.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [104, 105]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_25.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_25.html
new file mode 100644
index 0000000000..aa0cff3737
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_25.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [105, 106]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_26.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_26.html
new file mode 100644
index 0000000000..a3423dcbc4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_26.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [106, 107]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_27.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_27.html
new file mode 100644
index 0000000000..071c36672e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_27.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [107, 108]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_28.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_28.html
new file mode 100644
index 0000000000..07d17edcf4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_28.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [108, 109]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_29.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_29.html
new file mode 100644
index 0000000000..cd7f63e14c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_29.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [109, 110]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_30.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_30.html
new file mode 100644
index 0000000000..56988bd046
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_30.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [110, 111]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_31.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_31.html
new file mode 100644
index 0000000000..286ace3917
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_31.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [111, 112]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_32.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_32.html
new file mode 100644
index 0000000000..1ba0ae432b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_32.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [112, 113]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_33.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_33.html
new file mode 100644
index 0000000000..19cb29fb4a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_33.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [113, 114]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_34.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_34.html
new file mode 100644
index 0000000000..5afb122414
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_34.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [114, 115]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_35.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_35.html
new file mode 100644
index 0000000000..1411f68e0f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_combinations_35.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [115, 116]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_00.html
new file mode 100644
index 0000000000..1b41ca237d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [65, 66]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_01.html
new file mode 100644
index 0000000000..c8059f7e39
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [66, 67]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_02.html
new file mode 100644
index 0000000000..6529aec830
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [67, 68]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_03.html
new file mode 100644
index 0000000000..249860cee7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [68, 69]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_04.html
new file mode 100644
index 0000000000..0bb0aab1ac
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [69, 70]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_05.html
new file mode 100644
index 0000000000..dba6d0f666
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_05.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [70, 71]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_06.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_06.html
new file mode 100644
index 0000000000..df06c3c1e4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_06.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [71, 72]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_07.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_07.html
new file mode 100644
index 0000000000..827ceba0c8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_07.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [72, 73]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_08.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_08.html
new file mode 100644
index 0000000000..695d317ecb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_08.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [73, 74]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_09.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_09.html
new file mode 100644
index 0000000000..72e7b41419
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_formats_09.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [74, 75]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_00.html
new file mode 100644
index 0000000000..7ff8170258
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [75, 76]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_01.html
new file mode 100644
index 0000000000..6263ae9413
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [76, 77]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_02.html
new file mode 100644
index 0000000000..17e7a30c55
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [77, 78]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_03.html
new file mode 100644
index 0000000000..c888db7145
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [78, 79]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_04.html
new file mode 100644
index 0000000000..d1f4a5f869
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/3d_sizes_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [79, 80]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_00.html
new file mode 100644
index 0000000000..21e59eea02
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [37, 38]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_01.html
new file mode 100644
index 0000000000..9833f0f84e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [38, 39]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_02.html
new file mode 100644
index 0000000000..8fc0017864
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [39, 40]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_03.html
new file mode 100644
index 0000000000..f80bc00d80
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [40, 41]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_04.html
new file mode 100644
index 0000000000..2d69ac867b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [41, 42]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_05.html
new file mode 100644
index 0000000000..ea6bbb755c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_combinations_05.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [42, 43]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_00.html
new file mode 100644
index 0000000000..e228874f75
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [22, 23]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_01.html
new file mode 100644
index 0000000000..f9c966e680
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [23, 24]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_02.html
new file mode 100644
index 0000000000..bf9c256bed
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [24, 25]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_03.html
new file mode 100644
index 0000000000..d3f78a46cd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [25, 26]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_04.html
new file mode 100644
index 0000000000..eb07dea652
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [26, 27]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_05.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_05.html
new file mode 100644
index 0000000000..d7ccb2c171
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_05.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [27, 28]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_06.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_06.html
new file mode 100644
index 0000000000..1496707baa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_06.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [28, 29]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_07.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_07.html
new file mode 100644
index 0000000000..2683e71ea6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_07.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [29, 30]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_08.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_08.html
new file mode 100644
index 0000000000..d69dcfae64
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_08.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [30, 31]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_09.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_09.html
new file mode 100644
index 0000000000..f34e51e8f4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_formats_09.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [31, 32]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_no_edges_visible.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_no_edges_visible.html
new file mode 100644
index 0000000000..531df3bb98
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_no_edges_visible.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [43, 44]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_00.html
new file mode 100644
index 0000000000..4e4fe4dfa4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [32, 33]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_01.html
new file mode 100644
index 0000000000..a4db3fc04c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [33, 34]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_02.html
new file mode 100644
index 0000000000..cf7ac7644d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [34, 35]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_03.html
new file mode 100644
index 0000000000..6b8d94c51f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [35, 36]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_04.html
new file mode 100644
index 0000000000..b1260c751f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/cube_sizes_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [36, 37]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/texturefiltering_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/texturefiltering_test_generator.py
new file mode 100644
index 0000000000..0b6064c8ca
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturefiltering/texturefiltering_test_generator.py
@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for texturefilter* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from texturefiltering_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Filtering Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFilteringTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFilteringTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_FILTERABLE_FORMAT_COUNT = 10
+_SIZE_2D_COUNT = 6
+_SIZE_CUBE_COUNT = 5
+_SIZE_2D_ARRAY_COUNT = 5
+_SIZE_3D_COUNT = 5
+_MIN_FILTER_MODE_COUNT = 6
+_MAG_FILTER_MODE_COUNT = 2
+_WRAP_MODE_COUNT = 3
+
+_GROUPS = [
+ '2d_formats',
+ '2d_sizes',
+ '2d_combinations',
+ 'cube_formats',
+ 'cube_sizes',
+ 'cube_combinations',
+ 'cube_no_edges_visible',
+ '2d_array_formats',
+ '2d_array_sizes',
+ '2d_array_combinations',
+ '3d_formats',
+ '3d_sizes',
+ '3d_combinations'
+]
+
+_GROUP_TEST_COUNTS = [
+ _FILTERABLE_FORMAT_COUNT, # 2d_formats
+ _SIZE_2D_COUNT, # 2d_sizes
+ _MIN_FILTER_MODE_COUNT, # 2d_combinations
+ _FILTERABLE_FORMAT_COUNT, # cube_formats
+ _SIZE_CUBE_COUNT, # cube_sizes
+ _MIN_FILTER_MODE_COUNT, # cube_combinations
+ 1, # cube_no_edges_visible
+ _FILTERABLE_FORMAT_COUNT, # 2d_array_formats
+ _SIZE_2D_ARRAY_COUNT, # 2d_array_sizes
+ _MIN_FILTER_MODE_COUNT, # 2d_array_combinations
+ _FILTERABLE_FORMAT_COUNT, # 3d_formats
+ _SIZE_3D_COUNT, # 3d_sizes,
+ _MIN_FILTER_MODE_COUNT * _MAG_FILTER_MODE_COUNT * _WRAP_MODE_COUNT, # 3d_combinations
+]
+
+def GenerateFilename(group, count, index):
+ """Generate test filename."""
+ assert index >= 0 and index < count
+ filename = group
+ if count > 1:
+ index_str = str(index)
+ if index < 10:
+ index_str = "0" + index_str
+ filename += "_" + index_str
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ assert len(_GROUPS) == len(_GROUP_TEST_COUNTS)
+ test_index = 0
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ group = _GROUPS[ii]
+ count = _GROUP_TEST_COUNTS[ii]
+ for index in range(count):
+ filename = GenerateFilename(group, count, index)
+ filelist.append(filename)
+ WriteTest(filename, test_index, test_index + 1)
+ test_index += 1
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/00_test_list.txt
new file mode 100644
index 0000000000..cbd63eb92d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/00_test_list.txt
@@ -0,0 +1,38 @@
+unsized_2d.html
+unsized_2d_array.html
+unsized_3d.html
+sized_color_2d_pot_00.html
+sized_color_2d_pot_01.html
+sized_color_2d_pot_02.html
+sized_color_2d_pot_03.html
+sized_color_2d_npot_00.html
+sized_color_2d_npot_01.html
+sized_color_2d_npot_02.html
+sized_color_2d_npot_03.html
+sized_color_cube_pot_00.html
+sized_color_cube_pot_01.html
+sized_color_cube_pot_02.html
+sized_color_cube_pot_03.html
+sized_color_cube_npot_00.html
+sized_color_cube_npot_01.html
+sized_color_cube_npot_02.html
+sized_color_cube_npot_03.html
+sized_color_2d_array_pot_00.html
+sized_color_2d_array_pot_01.html
+sized_color_2d_array_pot_02.html
+sized_color_2d_array_pot_03.html
+sized_color_2d_array_npot_00.html
+sized_color_2d_array_npot_01.html
+sized_color_2d_array_npot_02.html
+sized_color_2d_array_npot_03.html
+sized_color_3d_pot_00.html
+sized_color_3d_pot_01.html
+sized_color_3d_pot_02.html
+sized_color_3d_pot_03.html
+sized_color_3d_npot_00.html
+sized_color_3d_npot_01.html
+sized_color_3d_npot_02.html
+sized_color_3d_npot_03.html
+sized_depth_stencil.html
+compressed_2d.html
+compressed_cube.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/compressed_2d.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/compressed_2d.html
new file mode 100644
index 0000000000..8f104f0ffc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/compressed_2d.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [36, 37]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/compressed_cube.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/compressed_cube.html
new file mode 100644
index 0000000000..39e7f2055e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/compressed_cube.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [37, 38]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_00.html
new file mode 100644
index 0000000000..c0867d87a1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [23, 24]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_01.html
new file mode 100644
index 0000000000..8f143eaf74
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [24, 25]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_02.html
new file mode 100644
index 0000000000..92a8b2c98e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [25, 26]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_03.html
new file mode 100644
index 0000000000..55fea6907d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_npot_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [26, 27]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_00.html
new file mode 100644
index 0000000000..975fb089b9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [19, 20]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_01.html
new file mode 100644
index 0000000000..11267669c1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [20, 21]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_02.html
new file mode 100644
index 0000000000..26190a4f79
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [21, 22]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_03.html
new file mode 100644
index 0000000000..6d42808253
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_array_pot_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [22, 23]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_00.html
new file mode 100644
index 0000000000..c0cea16d87
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_01.html
new file mode 100644
index 0000000000..ca38325a3c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_02.html
new file mode 100644
index 0000000000..04c3e0fbcf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [9, 10]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_03.html
new file mode 100644
index 0000000000..e63de3ae2f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_npot_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [10, 11]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_00.html
new file mode 100644
index 0000000000..d880ac7196
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_01.html
new file mode 100644
index 0000000000..e65f1f851e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_02.html
new file mode 100644
index 0000000000..64d4715d2f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_03.html
new file mode 100644
index 0000000000..67140d7f79
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_2d_pot_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_00.html
new file mode 100644
index 0000000000..4b1eed3a10
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [31, 32]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_01.html
new file mode 100644
index 0000000000..9adf66b652
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [32, 33]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_02.html
new file mode 100644
index 0000000000..6f6dd722e3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [33, 34]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_03.html
new file mode 100644
index 0000000000..8d2f6ed044
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_npot_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [34, 35]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_00.html
new file mode 100644
index 0000000000..c1d3dedd38
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [27, 28]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_01.html
new file mode 100644
index 0000000000..e33bb5ea91
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [28, 29]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_02.html
new file mode 100644
index 0000000000..f28f2589dd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [29, 30]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_03.html
new file mode 100644
index 0000000000..a6028c9290
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_3d_pot_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [30, 31]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_00.html
new file mode 100644
index 0000000000..1e6403f3f4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [15, 16]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_01.html
new file mode 100644
index 0000000000..9b79dd1932
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [16, 17]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_02.html
new file mode 100644
index 0000000000..d3bfde6336
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [17, 18]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_03.html
new file mode 100644
index 0000000000..7a9f7b3618
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_npot_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [18, 19]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_00.html
new file mode 100644
index 0000000000..9f88f7e572
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [11, 12]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_01.html
new file mode 100644
index 0000000000..6f24c6d8eb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [12, 13]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_02.html
new file mode 100644
index 0000000000..3ce93d65a6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [13, 14]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_03.html
new file mode 100644
index 0000000000..fcbf8d6493
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_color_cube_pot_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [14, 15]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_depth_stencil.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_depth_stencil.html
new file mode 100644
index 0000000000..bca1fbfbc9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/sized_depth_stencil.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [35, 36]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/textureformat_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/textureformat_test_generator.py
new file mode 100644
index 0000000000..ba20f04899
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/textureformat_test_generator.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for textureformat* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'unsized_2d',
+ 'unsized_2d_array',
+ 'unsized_3d',
+ 'sized_color_2d_pot_00',
+ 'sized_color_2d_pot_01',
+ 'sized_color_2d_pot_02',
+ 'sized_color_2d_pot_03',
+ 'sized_color_2d_npot_00',
+ 'sized_color_2d_npot_01',
+ 'sized_color_2d_npot_02',
+ 'sized_color_2d_npot_03',
+ 'sized_color_cube_pot_00',
+ 'sized_color_cube_pot_01',
+ 'sized_color_cube_pot_02',
+ 'sized_color_cube_pot_03',
+ 'sized_color_cube_npot_00',
+ 'sized_color_cube_npot_01',
+ 'sized_color_cube_npot_02',
+ 'sized_color_cube_npot_03',
+ 'sized_color_2d_array_pot_00',
+ 'sized_color_2d_array_pot_01',
+ 'sized_color_2d_array_pot_02',
+ 'sized_color_2d_array_pot_03',
+ 'sized_color_2d_array_npot_00',
+ 'sized_color_2d_array_npot_01',
+ 'sized_color_2d_array_npot_02',
+ 'sized_color_2d_array_npot_03',
+ 'sized_color_3d_pot_00',
+ 'sized_color_3d_pot_01',
+ 'sized_color_3d_pot_02',
+ 'sized_color_3d_pot_03',
+ 'sized_color_3d_npot_00',
+ 'sized_color_3d_npot_01',
+ 'sized_color_3d_npot_02',
+ 'sized_color_3d_npot_03',
+ 'sized_depth_stencil',
+ 'compressed_2d',
+ 'compressed_cube',
+]
+
+def GenerateFilename(group):
+ """Generate test filename."""
+ filename = group
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ filename = GenerateFilename(_GROUPS[ii])
+ filelist.append(filename)
+ WriteTest(filename, ii, ii + 1)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/unsized_2d.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/unsized_2d.html
new file mode 100644
index 0000000000..447e4387f9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/unsized_2d.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/unsized_2d_array.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/unsized_2d_array.html
new file mode 100644
index 0000000000..6eaeb451e2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/unsized_2d_array.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/unsized_3d.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/unsized_3d.html
new file mode 100644
index 0000000000..8fe25fde1a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureformat/unsized_3d.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureformat_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureFormatTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="300" height="300"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureFormatTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/00_test_list.txt
new file mode 100644
index 0000000000..48498b565e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/00_test_list.txt
@@ -0,0 +1,144 @@
+2d_nearest_less_or_equal.html
+2d_nearest_greater_or_equal.html
+2d_nearest_less.html
+2d_nearest_greater.html
+2d_nearest_equal.html
+2d_nearest_not_equal.html
+2d_nearest_always.html
+2d_nearest_never.html
+2d_linear_less_or_equal.html
+2d_linear_greater_or_equal.html
+2d_linear_less.html
+2d_linear_greater.html
+2d_linear_equal.html
+2d_linear_not_equal.html
+2d_linear_always.html
+2d_linear_never.html
+2d_nearest_mipmap_nearest_less_or_equal.html
+2d_nearest_mipmap_nearest_greater_or_equal.html
+2d_nearest_mipmap_nearest_less.html
+2d_nearest_mipmap_nearest_greater.html
+2d_nearest_mipmap_nearest_equal.html
+2d_nearest_mipmap_nearest_not_equal.html
+2d_nearest_mipmap_nearest_always.html
+2d_nearest_mipmap_nearest_never.html
+2d_linear_mipmap_nearest_less_or_equal.html
+2d_linear_mipmap_nearest_greater_or_equal.html
+2d_linear_mipmap_nearest_less.html
+2d_linear_mipmap_nearest_greater.html
+2d_linear_mipmap_nearest_equal.html
+2d_linear_mipmap_nearest_not_equal.html
+2d_linear_mipmap_nearest_always.html
+2d_linear_mipmap_nearest_never.html
+2d_nearest_mipmap_linear_less_or_equal.html
+2d_nearest_mipmap_linear_greater_or_equal.html
+2d_nearest_mipmap_linear_less.html
+2d_nearest_mipmap_linear_greater.html
+2d_nearest_mipmap_linear_equal.html
+2d_nearest_mipmap_linear_not_equal.html
+2d_nearest_mipmap_linear_always.html
+2d_nearest_mipmap_linear_never.html
+2d_linear_mipmap_linear_less_or_equal.html
+2d_linear_mipmap_linear_greater_or_equal.html
+2d_linear_mipmap_linear_less.html
+2d_linear_mipmap_linear_greater.html
+2d_linear_mipmap_linear_equal.html
+2d_linear_mipmap_linear_not_equal.html
+2d_linear_mipmap_linear_always.html
+2d_linear_mipmap_linear_never.html
+cube_nearest_less_or_equal.html
+cube_nearest_greater_or_equal.html
+cube_nearest_less.html
+cube_nearest_greater.html
+cube_nearest_equal.html
+cube_nearest_not_equal.html
+cube_nearest_always.html
+cube_nearest_never.html
+cube_linear_less_or_equal.html
+cube_linear_greater_or_equal.html
+cube_linear_less.html
+cube_linear_greater.html
+cube_linear_equal.html
+cube_linear_not_equal.html
+cube_linear_always.html
+cube_linear_never.html
+cube_nearest_mipmap_nearest_less_or_equal.html
+cube_nearest_mipmap_nearest_greater_or_equal.html
+cube_nearest_mipmap_nearest_less.html
+cube_nearest_mipmap_nearest_greater.html
+cube_nearest_mipmap_nearest_equal.html
+cube_nearest_mipmap_nearest_not_equal.html
+cube_nearest_mipmap_nearest_always.html
+cube_nearest_mipmap_nearest_never.html
+cube_linear_mipmap_nearest_less_or_equal.html
+cube_linear_mipmap_nearest_greater_or_equal.html
+cube_linear_mipmap_nearest_less.html
+cube_linear_mipmap_nearest_greater.html
+cube_linear_mipmap_nearest_equal.html
+cube_linear_mipmap_nearest_not_equal.html
+cube_linear_mipmap_nearest_always.html
+cube_linear_mipmap_nearest_never.html
+cube_nearest_mipmap_linear_less_or_equal.html
+cube_nearest_mipmap_linear_greater_or_equal.html
+cube_nearest_mipmap_linear_less.html
+cube_nearest_mipmap_linear_greater.html
+cube_nearest_mipmap_linear_equal.html
+cube_nearest_mipmap_linear_not_equal.html
+cube_nearest_mipmap_linear_always.html
+cube_nearest_mipmap_linear_never.html
+cube_linear_mipmap_linear_less_or_equal.html
+cube_linear_mipmap_linear_greater_or_equal.html
+cube_linear_mipmap_linear_less.html
+cube_linear_mipmap_linear_greater.html
+cube_linear_mipmap_linear_equal.html
+cube_linear_mipmap_linear_not_equal.html
+cube_linear_mipmap_linear_always.html
+cube_linear_mipmap_linear_never.html
+2d_array_nearest_less_or_equal.html
+2d_array_nearest_greater_or_equal.html
+2d_array_nearest_less.html
+2d_array_nearest_greater.html
+2d_array_nearest_equal.html
+2d_array_nearest_not_equal.html
+2d_array_nearest_always.html
+2d_array_nearest_never.html
+2d_array_linear_less_or_equal.html
+2d_array_linear_greater_or_equal.html
+2d_array_linear_less.html
+2d_array_linear_greater.html
+2d_array_linear_equal.html
+2d_array_linear_not_equal.html
+2d_array_linear_always.html
+2d_array_linear_never.html
+2d_array_nearest_mipmap_nearest_less_or_equal.html
+2d_array_nearest_mipmap_nearest_greater_or_equal.html
+2d_array_nearest_mipmap_nearest_less.html
+2d_array_nearest_mipmap_nearest_greater.html
+2d_array_nearest_mipmap_nearest_equal.html
+2d_array_nearest_mipmap_nearest_not_equal.html
+2d_array_nearest_mipmap_nearest_always.html
+2d_array_nearest_mipmap_nearest_never.html
+2d_array_linear_mipmap_nearest_less_or_equal.html
+2d_array_linear_mipmap_nearest_greater_or_equal.html
+2d_array_linear_mipmap_nearest_less.html
+2d_array_linear_mipmap_nearest_greater.html
+2d_array_linear_mipmap_nearest_equal.html
+2d_array_linear_mipmap_nearest_not_equal.html
+2d_array_linear_mipmap_nearest_always.html
+2d_array_linear_mipmap_nearest_never.html
+2d_array_nearest_mipmap_linear_less_or_equal.html
+2d_array_nearest_mipmap_linear_greater_or_equal.html
+2d_array_nearest_mipmap_linear_less.html
+2d_array_nearest_mipmap_linear_greater.html
+2d_array_nearest_mipmap_linear_equal.html
+2d_array_nearest_mipmap_linear_not_equal.html
+2d_array_nearest_mipmap_linear_always.html
+2d_array_nearest_mipmap_linear_never.html
+2d_array_linear_mipmap_linear_less_or_equal.html
+2d_array_linear_mipmap_linear_greater_or_equal.html
+2d_array_linear_mipmap_linear_less.html
+2d_array_linear_mipmap_linear_greater.html
+2d_array_linear_mipmap_linear_equal.html
+2d_array_linear_mipmap_linear_not_equal.html
+2d_array_linear_mipmap_linear_always.html
+2d_array_linear_mipmap_linear_never.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_always.html
new file mode 100644
index 0000000000..683a50a80c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [110, 111]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_equal.html
new file mode 100644
index 0000000000..9031d2180d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [108, 109]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_greater.html
new file mode 100644
index 0000000000..9ef3900ea1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [107, 108]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_greater_or_equal.html
new file mode 100644
index 0000000000..51914257e5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [105, 106]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_less.html
new file mode 100644
index 0000000000..924315e72f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [106, 107]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_less_or_equal.html
new file mode 100644
index 0000000000..877f3ae810
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [104, 105]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_always.html
new file mode 100644
index 0000000000..0495e7e3b0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [142, 143]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_equal.html
new file mode 100644
index 0000000000..c40fceded9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [140, 141]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater.html
new file mode 100644
index 0000000000..b813379c3f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [139, 140]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater_or_equal.html
new file mode 100644
index 0000000000..01b90b1316
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [137, 138]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less.html
new file mode 100644
index 0000000000..ea6d12246a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [138, 139]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less_or_equal.html
new file mode 100644
index 0000000000..da5c45dc87
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [136, 137]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_never.html
new file mode 100644
index 0000000000..6c7177d4eb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [143, 144]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_not_equal.html
new file mode 100644
index 0000000000..ece2898683
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_linear_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [141, 142]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_always.html
new file mode 100644
index 0000000000..d9ce0da356
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [126, 127]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_equal.html
new file mode 100644
index 0000000000..969dd028ed
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [124, 125]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater.html
new file mode 100644
index 0000000000..e6cdc2aba7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [123, 124]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater_or_equal.html
new file mode 100644
index 0000000000..8f3ab4a2a8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [121, 122]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less.html
new file mode 100644
index 0000000000..12cbf4d71d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [122, 123]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less_or_equal.html
new file mode 100644
index 0000000000..aa16ca2d03
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [120, 121]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_never.html
new file mode 100644
index 0000000000..ff8c6b4e7f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [127, 128]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_not_equal.html
new file mode 100644
index 0000000000..b12597025a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_mipmap_nearest_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [125, 126]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_never.html
new file mode 100644
index 0000000000..aaf630f95e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [111, 112]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_not_equal.html
new file mode 100644
index 0000000000..b5f37b7a24
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_linear_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [109, 110]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_always.html
new file mode 100644
index 0000000000..87e30ba530
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [102, 103]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_equal.html
new file mode 100644
index 0000000000..0121ae0c6f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [100, 101]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_greater.html
new file mode 100644
index 0000000000..a407700531
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [99, 100]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_greater_or_equal.html
new file mode 100644
index 0000000000..2b838e0da0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [97, 98]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_less.html
new file mode 100644
index 0000000000..b5e56cdc35
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [98, 99]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_less_or_equal.html
new file mode 100644
index 0000000000..3980fcd889
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [96, 97]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_always.html
new file mode 100644
index 0000000000..fe782c37a1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [134, 135]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_equal.html
new file mode 100644
index 0000000000..57838d838e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [132, 133]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater.html
new file mode 100644
index 0000000000..ac85fd057d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [131, 132]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater_or_equal.html
new file mode 100644
index 0000000000..17074cb881
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [129, 130]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less.html
new file mode 100644
index 0000000000..849a0787c2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [130, 131]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less_or_equal.html
new file mode 100644
index 0000000000..4ed680906e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [128, 129]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_never.html
new file mode 100644
index 0000000000..484b3b7a37
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [135, 136]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_not_equal.html
new file mode 100644
index 0000000000..7611bba2b3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_linear_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [133, 134]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_always.html
new file mode 100644
index 0000000000..e80d611a21
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [118, 119]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_equal.html
new file mode 100644
index 0000000000..0c8af699cf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [116, 117]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater.html
new file mode 100644
index 0000000000..58d3f537f0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [115, 116]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater_or_equal.html
new file mode 100644
index 0000000000..26a3ca0c7f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [113, 114]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less.html
new file mode 100644
index 0000000000..fc9895c7c0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [114, 115]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less_or_equal.html
new file mode 100644
index 0000000000..82f5381db4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [112, 113]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_never.html
new file mode 100644
index 0000000000..2959de11e8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [119, 120]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_not_equal.html
new file mode 100644
index 0000000000..d2d2a1657d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_mipmap_nearest_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [117, 118]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_never.html
new file mode 100644
index 0000000000..970b393e8f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [103, 104]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_not_equal.html
new file mode 100644
index 0000000000..cc52419bb6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_array_nearest_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [101, 102]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_always.html
new file mode 100644
index 0000000000..0c072e4e9a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [14, 15]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_equal.html
new file mode 100644
index 0000000000..1c358069a5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [12, 13]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_greater.html
new file mode 100644
index 0000000000..65109bfc8c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [11, 12]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_greater_or_equal.html
new file mode 100644
index 0000000000..b9065cde43
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [9, 10]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_less.html
new file mode 100644
index 0000000000..d4d98b914b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [10, 11]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_less_or_equal.html
new file mode 100644
index 0000000000..e0d4c1584f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_always.html
new file mode 100644
index 0000000000..a71e2d2e48
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [46, 47]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_equal.html
new file mode 100644
index 0000000000..03e604163a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [44, 45]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater.html
new file mode 100644
index 0000000000..e0e163e2eb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [43, 44]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater_or_equal.html
new file mode 100644
index 0000000000..7498d0b29d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [41, 42]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less.html
new file mode 100644
index 0000000000..8c9c018e5a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [42, 43]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less_or_equal.html
new file mode 100644
index 0000000000..0e23db2efb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [40, 41]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_never.html
new file mode 100644
index 0000000000..519746474a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [47, 48]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_not_equal.html
new file mode 100644
index 0000000000..53a9c44a7f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_linear_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [45, 46]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_always.html
new file mode 100644
index 0000000000..879a5eec9c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [30, 31]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_equal.html
new file mode 100644
index 0000000000..6ddfb4a88c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [28, 29]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater.html
new file mode 100644
index 0000000000..89f48e479c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [27, 28]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater_or_equal.html
new file mode 100644
index 0000000000..79962393e1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [25, 26]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less.html
new file mode 100644
index 0000000000..f2207075cd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [26, 27]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less_or_equal.html
new file mode 100644
index 0000000000..a600187ebe
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [24, 25]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_never.html
new file mode 100644
index 0000000000..1d499f8c73
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [31, 32]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_not_equal.html
new file mode 100644
index 0000000000..522a65e41d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_mipmap_nearest_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [29, 30]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_never.html
new file mode 100644
index 0000000000..b7368c2759
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [15, 16]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_not_equal.html
new file mode 100644
index 0000000000..490692b4d4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_linear_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [13, 14]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_always.html
new file mode 100644
index 0000000000..d811685f8e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_equal.html
new file mode 100644
index 0000000000..f6574fe35c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_greater.html
new file mode 100644
index 0000000000..1b6df673ae
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_greater_or_equal.html
new file mode 100644
index 0000000000..064388f636
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_less.html
new file mode 100644
index 0000000000..1efa1a01a5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_less_or_equal.html
new file mode 100644
index 0000000000..10196bf59f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_always.html
new file mode 100644
index 0000000000..c799aa9ff7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [38, 39]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_equal.html
new file mode 100644
index 0000000000..cd0dd6a1d8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [36, 37]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater.html
new file mode 100644
index 0000000000..5bd98c0677
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [35, 36]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater_or_equal.html
new file mode 100644
index 0000000000..dee22dc3e7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [33, 34]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less.html
new file mode 100644
index 0000000000..8b954a55a7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [34, 35]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less_or_equal.html
new file mode 100644
index 0000000000..b6eb41c0ea
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [32, 33]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_never.html
new file mode 100644
index 0000000000..be55dd6c41
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [39, 40]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_not_equal.html
new file mode 100644
index 0000000000..996cb8a393
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_linear_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [37, 38]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_always.html
new file mode 100644
index 0000000000..1eef513bef
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [22, 23]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_equal.html
new file mode 100644
index 0000000000..793c544c6f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [20, 21]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater.html
new file mode 100644
index 0000000000..426e431255
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [19, 20]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater_or_equal.html
new file mode 100644
index 0000000000..4eca9eb327
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [17, 18]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less.html
new file mode 100644
index 0000000000..a4324c2447
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [18, 19]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less_or_equal.html
new file mode 100644
index 0000000000..b63b148823
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [16, 17]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_never.html
new file mode 100644
index 0000000000..5e74f10bb2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [23, 24]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_not_equal.html
new file mode 100644
index 0000000000..804b2e3ae9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_mipmap_nearest_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [21, 22]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_never.html
new file mode 100644
index 0000000000..de447dac45
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_not_equal.html
new file mode 100644
index 0000000000..fa8977bf91
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/2d_nearest_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_always.html
new file mode 100644
index 0000000000..846d6ee7e4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [62, 63]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_equal.html
new file mode 100644
index 0000000000..829e0977f7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [60, 61]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_greater.html
new file mode 100644
index 0000000000..1035f86428
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [59, 60]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_greater_or_equal.html
new file mode 100644
index 0000000000..e287605818
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [57, 58]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_less.html
new file mode 100644
index 0000000000..cae8affb2b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [58, 59]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_less_or_equal.html
new file mode 100644
index 0000000000..c7ad559722
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [56, 57]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_always.html
new file mode 100644
index 0000000000..6bc8a946df
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [94, 95]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_equal.html
new file mode 100644
index 0000000000..c3cc8ca0e9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [92, 93]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater.html
new file mode 100644
index 0000000000..0294b65acb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [91, 92]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater_or_equal.html
new file mode 100644
index 0000000000..d19866502b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [89, 90]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less.html
new file mode 100644
index 0000000000..4d3c98cb08
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [90, 91]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less_or_equal.html
new file mode 100644
index 0000000000..2972d989a1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [88, 89]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_never.html
new file mode 100644
index 0000000000..7015dec4fb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [95, 96]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_not_equal.html
new file mode 100644
index 0000000000..d67b0d5f7f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_linear_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [93, 94]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_always.html
new file mode 100644
index 0000000000..a22b92d412
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [78, 79]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_equal.html
new file mode 100644
index 0000000000..2102e56dcb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [76, 77]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater.html
new file mode 100644
index 0000000000..80ed0e3b41
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [75, 76]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater_or_equal.html
new file mode 100644
index 0000000000..e590f76bb8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [73, 74]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less.html
new file mode 100644
index 0000000000..63d99bd97f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [74, 75]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less_or_equal.html
new file mode 100644
index 0000000000..53bdba5ff5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [72, 73]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_never.html
new file mode 100644
index 0000000000..fffe6fe452
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [79, 80]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_not_equal.html
new file mode 100644
index 0000000000..1ddeb39d91
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_mipmap_nearest_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [77, 78]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_never.html
new file mode 100644
index 0000000000..b96321fe1b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [63, 64]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_not_equal.html
new file mode 100644
index 0000000000..0c663cdaf1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_linear_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [61, 62]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_always.html
new file mode 100644
index 0000000000..de25c5ef0b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [54, 55]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_equal.html
new file mode 100644
index 0000000000..6a76cb062a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [52, 53]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_greater.html
new file mode 100644
index 0000000000..d5fa0b62d6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [51, 52]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_greater_or_equal.html
new file mode 100644
index 0000000000..b7e7085da2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [49, 50]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_less.html
new file mode 100644
index 0000000000..47c4b34d17
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [50, 51]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_less_or_equal.html
new file mode 100644
index 0000000000..1c9f005c0a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [48, 49]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_always.html
new file mode 100644
index 0000000000..14af11c511
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [86, 87]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_equal.html
new file mode 100644
index 0000000000..96c1e1d586
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [84, 85]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater.html
new file mode 100644
index 0000000000..f7e1087a86
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [83, 84]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater_or_equal.html
new file mode 100644
index 0000000000..be1773c2e2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [81, 82]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less.html
new file mode 100644
index 0000000000..e4aa08d139
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [82, 83]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less_or_equal.html
new file mode 100644
index 0000000000..fe6705c20a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [80, 81]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_never.html
new file mode 100644
index 0000000000..34bc00816d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [87, 88]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_not_equal.html
new file mode 100644
index 0000000000..8d7a900a77
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_linear_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [85, 86]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_always.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_always.html
new file mode 100644
index 0000000000..610869e06a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_always.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [70, 71]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_equal.html
new file mode 100644
index 0000000000..59a878d1d0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [68, 69]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater.html
new file mode 100644
index 0000000000..dc788bc5f0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [67, 68]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater_or_equal.html
new file mode 100644
index 0000000000..e7e86e9cc0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_greater_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [65, 66]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less.html
new file mode 100644
index 0000000000..cdb64a95ed
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [66, 67]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less_or_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less_or_equal.html
new file mode 100644
index 0000000000..26b6db723f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_less_or_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [64, 65]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_never.html
new file mode 100644
index 0000000000..8d71e5859f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [71, 72]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_not_equal.html
new file mode 100644
index 0000000000..6e681695fc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_mipmap_nearest_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [69, 70]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_never.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_never.html
new file mode 100644
index 0000000000..15d5b531f0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_never.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [55, 56]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_not_equal.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_not_equal.html
new file mode 100644
index 0000000000..3a3a41ddb3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/cube_nearest_not_equal.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [53, 54]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/textureshadow_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/textureshadow_test_generator.py
new file mode 100644
index 0000000000..4ead80de86
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/textureshadow/textureshadow_test_generator.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for textureformat* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Shadow Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureShadowTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureShadowTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_TARGETS = [
+ '2d',
+ 'cube',
+ '2d_array',
+]
+
+_FILTERS = [
+ 'nearest',
+ 'linear',
+ 'nearest_mipmap_nearest',
+ 'linear_mipmap_nearest',
+ 'nearest_mipmap_linear',
+ 'linear_mipmap_linear',
+]
+
+_COMPARE_FUNCS = [
+ 'less_or_equal',
+ 'greater_or_equal',
+ 'less',
+ 'greater',
+ 'equal',
+ 'not_equal',
+ 'always',
+ 'never',
+]
+
+def GenerateFilename(group):
+ """Generate test filename."""
+ filename = group
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ ii = 0
+ for iTarget in range(len(_TARGETS)):
+ for iFilter in range(len(_FILTERS)):
+ for iFunc in range(len(_COMPARE_FUNCS)):
+ item = _TARGETS[iTarget] + '_' + _FILTERS[iFilter] + '_' + _COMPARE_FUNCS[iFunc]
+ filename = GenerateFilename(item)
+ filelist.append(filename)
+ WriteTest(filename, ii, ii + 1)
+ ii = ii + 1
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/00_test_list.txt
new file mode 100644
index 0000000000..b3f8275d99
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/00_test_list.txt
@@ -0,0 +1,90 @@
+basic_teximage2d_2d_00.html
+basic_teximage2d_2d_01.html
+basic_teximage2d_cube_00.html
+basic_teximage2d_cube_01.html
+basic_teximage2d_cube_02.html
+basic_teximage2d_cube_03.html
+basic_teximage2d_cube_04.html
+random_teximage2d_2d.html
+random_teximage2d_cube.html
+teximage2d_align.html
+teximage2d_unpack_params.html
+teximage2d_pbo_2d_00.html
+teximage2d_pbo_2d_01.html
+teximage2d_pbo_cube_00.html
+teximage2d_pbo_cube_01.html
+teximage2d_pbo_cube_02.html
+teximage2d_pbo_cube_03.html
+teximage2d_pbo_cube_04.html
+teximage2d_pbo_params.html
+teximage2d_depth.html
+teximage2d_depth_pbo.html
+basic_texsubimage2d_2d_00.html
+basic_texsubimage2d_2d_01.html
+basic_texsubimage2d_2d_02.html
+basic_texsubimage2d_cube_00.html
+basic_texsubimage2d_cube_01.html
+basic_texsubimage2d_cube_02.html
+basic_texsubimage2d_cube_03.html
+basic_texsubimage2d_cube_04.html
+texsubimage2d_empty_tex.html
+texsubimage2d_align.html
+texsubimage2d_unpack_params.html
+texsubimage2d_pbo_2d_00.html
+texsubimage2d_pbo_2d_01.html
+texsubimage2d_pbo_cube_00.html
+texsubimage2d_pbo_cube_01.html
+texsubimage2d_pbo_cube_02.html
+texsubimage2d_pbo_cube_03.html
+texsubimage2d_pbo_cube_04.html
+texsubimage2d_pbo_params.html
+texsubimage2d_depth.html
+basic_copyteximage2d.html
+basic_copytexsubimage2d.html
+basic_teximage3d_2d_array_00.html
+basic_teximage3d_2d_array_01.html
+basic_teximage3d_2d_array_02.html
+basic_teximage3d_3d_00.html
+basic_teximage3d_3d_01.html
+basic_teximage3d_3d_02.html
+basic_teximage3d_3d_03.html
+basic_teximage3d_3d_04.html
+teximage3d_unpack_params.html
+teximage3d_pbo_2d_array_00.html
+teximage3d_pbo_2d_array_01.html
+teximage3d_pbo_3d_00.html
+teximage3d_pbo_3d_01.html
+teximage3d_pbo_params.html
+teximage3d_depth.html
+teximage3d_depth_pbo.html
+basic_texsubimage3d_00.html
+basic_texsubimage3d_01.html
+basic_texsubimage3d_02.html
+basic_texsubimage3d_03.html
+basic_texsubimage3d_04.html
+texsubimage3d_unpack_params.html
+texsubimage3d_pbo_2d_array_00.html
+texsubimage3d_pbo_2d_array_01.html
+texsubimage3d_pbo_3d_00.html
+texsubimage3d_pbo_3d_01.html
+texsubimage3d_pbo_params.html
+texsubimage3d_depth.html
+texstorage2d_format_2d_00.html
+texstorage2d_format_2d_01.html
+texstorage2d_format_2d_02.html
+texstorage2d_format_cube_00.html
+texstorage2d_format_cube_01.html
+texstorage2d_format_cube_02.html
+texstorage2d_format_cube_03.html
+texstorage2d_format_cube_04.html
+texstorage2d_format_depth_stencil.html
+texstorage2d_format_size.html
+texstorage3d_format_2d_array_00.html
+texstorage3d_format_2d_array_01.html
+texstorage3d_format_2d_array_02.html
+texstorage3d_format_3d_00.html
+texstorage3d_format_3d_01.html
+texstorage3d_format_3d_02.html
+texstorage3d_format_3d_03.html
+texstorage3d_format_depth_stencil.html
+texstorage3d_format_size.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_copyteximage2d.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_copyteximage2d.html
new file mode 100644
index 0000000000..8ad04f6a33
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_copyteximage2d.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [41, 42]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_copytexsubimage2d.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_copytexsubimage2d.html
new file mode 100644
index 0000000000..01832d5e8f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_copytexsubimage2d.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [42, 43]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_2d_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_2d_00.html
new file mode 100644
index 0000000000..25a3941fd4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_2d_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_2d_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_2d_01.html
new file mode 100644
index 0000000000..7258bb0f2c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_2d_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_00.html
new file mode 100644
index 0000000000..a0b44fa064
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_01.html
new file mode 100644
index 0000000000..1d59fd011e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_02.html
new file mode 100644
index 0000000000..01fbabc0bd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_03.html
new file mode 100644
index 0000000000..c1f662fb71
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_04.html
new file mode 100644
index 0000000000..1c0cbda645
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage2d_cube_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_00.html
new file mode 100644
index 0000000000..04f5f82a89
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [43, 44]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_01.html
new file mode 100644
index 0000000000..fe6dbec66c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [44, 45]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_02.html
new file mode 100644
index 0000000000..b33f5c0dc9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_2d_array_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [45, 46]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_00.html
new file mode 100644
index 0000000000..330a980b9e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [46, 47]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_01.html
new file mode 100644
index 0000000000..ebe8449990
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [47, 48]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_02.html
new file mode 100644
index 0000000000..941e6d3689
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [48, 49]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_03.html
new file mode 100644
index 0000000000..49bd666589
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [49, 50]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_04.html
new file mode 100644
index 0000000000..b35f582c31
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_teximage3d_3d_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [50, 51]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_00.html
new file mode 100644
index 0000000000..2c9ab82a97
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [21, 22]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_01.html
new file mode 100644
index 0000000000..1ce8c4ed69
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [22, 23]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_02.html
new file mode 100644
index 0000000000..ab339cc79e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_2d_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [23, 24]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_00.html
new file mode 100644
index 0000000000..5152b59266
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [24, 25]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_01.html
new file mode 100644
index 0000000000..519387bf4c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [25, 26]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_02.html
new file mode 100644
index 0000000000..f2d88d3094
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [26, 27]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_03.html
new file mode 100644
index 0000000000..e32a550b44
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [27, 28]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_04.html
new file mode 100644
index 0000000000..263e5da5d1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage2d_cube_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [28, 29]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_00.html
new file mode 100644
index 0000000000..c418c167b8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [59, 60]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_01.html
new file mode 100644
index 0000000000..f24c56e383
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [60, 61]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_02.html
new file mode 100644
index 0000000000..8d761c9391
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [61, 62]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_03.html
new file mode 100644
index 0000000000..f04cd395a8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [62, 63]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_04.html
new file mode 100644
index 0000000000..036df5fe25
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/basic_texsubimage3d_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [63, 64]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/random_teximage2d_2d.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/random_teximage2d_2d.html
new file mode 100644
index 0000000000..d166152cea
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/random_teximage2d_2d.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/random_teximage2d_cube.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/random_teximage2d_cube.html
new file mode 100644
index 0000000000..b7fcc77142
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/random_teximage2d_cube.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_align.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_align.html
new file mode 100644
index 0000000000..bf844178ff
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_align.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [9, 10]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_depth.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_depth.html
new file mode 100644
index 0000000000..6b2e31b76e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_depth.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [19, 20]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_depth_pbo.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_depth_pbo.html
new file mode 100644
index 0000000000..0ccf52ba1b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_depth_pbo.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [20, 21]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_00.html
new file mode 100644
index 0000000000..4df9f6a0d4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [11, 12]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_01.html
new file mode 100644
index 0000000000..26f503dbb1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_2d_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [12, 13]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_00.html
new file mode 100644
index 0000000000..c0b7ce461e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [13, 14]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_01.html
new file mode 100644
index 0000000000..24e3ebb47a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [14, 15]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_02.html
new file mode 100644
index 0000000000..76f74ebf99
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [15, 16]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_03.html
new file mode 100644
index 0000000000..cfc63dcf44
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [16, 17]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_04.html
new file mode 100644
index 0000000000..5f26f61bb0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_cube_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [17, 18]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_params.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_params.html
new file mode 100644
index 0000000000..cb4c7b87a0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_pbo_params.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [18, 19]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_unpack_params.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_unpack_params.html
new file mode 100644
index 0000000000..43fdf383a0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage2d_unpack_params.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [10, 11]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_depth.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_depth.html
new file mode 100644
index 0000000000..a6a6691a87
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_depth.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [57, 58]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_depth_pbo.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_depth_pbo.html
new file mode 100644
index 0000000000..d8ec29d395
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_depth_pbo.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [58, 59]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_00.html
new file mode 100644
index 0000000000..2b963af9b5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [52, 53]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_01.html
new file mode 100644
index 0000000000..4a3c9e3175
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_2d_array_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [53, 54]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_00.html
new file mode 100644
index 0000000000..472621dc96
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [54, 55]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_01.html
new file mode 100644
index 0000000000..4275a1c0b1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_3d_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [55, 56]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_params.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_params.html
new file mode 100644
index 0000000000..213bc831d2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_pbo_params.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [56, 57]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_unpack_params.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_unpack_params.html
new file mode 100644
index 0000000000..9bfd6c2157
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/teximage3d_unpack_params.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [51, 52]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_2d_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_2d_00.html
new file mode 100644
index 0000000000..dfa571683b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_2d_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [71, 72]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_2d_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_2d_01.html
new file mode 100644
index 0000000000..d764993f39
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_2d_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [72, 73]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_2d_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_2d_02.html
new file mode 100644
index 0000000000..53077e684b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_2d_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [73, 74]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_00.html
new file mode 100644
index 0000000000..f8a4c6c8a4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [74, 75]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_01.html
new file mode 100644
index 0000000000..d56154d30b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [75, 76]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_02.html
new file mode 100644
index 0000000000..c575c39d6e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [76, 77]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_03.html
new file mode 100644
index 0000000000..8b4a767530
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [77, 78]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_04.html
new file mode 100644
index 0000000000..2e9aa10486
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_cube_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [78, 79]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_depth_stencil.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_depth_stencil.html
new file mode 100644
index 0000000000..e2454c4475
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_depth_stencil.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [79, 80]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_size.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_size.html
new file mode 100644
index 0000000000..0d7bb7c009
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage2d_format_size.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [80, 81]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_00.html
new file mode 100644
index 0000000000..b7792d85b5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [81, 82]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_01.html
new file mode 100644
index 0000000000..de3140514e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [82, 83]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_02.html
new file mode 100644
index 0000000000..831b7ba386
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_2d_array_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [83, 84]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_00.html
new file mode 100644
index 0000000000..a4bfad50ff
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [84, 85]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_01.html
new file mode 100644
index 0000000000..1673ca1811
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [85, 86]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_02.html
new file mode 100644
index 0000000000..cad658becf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [86, 87]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_03.html
new file mode 100644
index 0000000000..dee4ae0bf5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_3d_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [87, 88]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_depth_stencil.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_depth_stencil.html
new file mode 100644
index 0000000000..2a10ac2a94
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_depth_stencil.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [88, 89]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_size.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_size.html
new file mode 100644
index 0000000000..b681d83071
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texstorage3d_format_size.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [89, 90]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_align.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_align.html
new file mode 100644
index 0000000000..990098d190
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_align.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [30, 31]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_depth.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_depth.html
new file mode 100644
index 0000000000..33194ec150
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_depth.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [40, 41]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_empty_tex.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_empty_tex.html
new file mode 100644
index 0000000000..3da5eed58c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_empty_tex.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [29, 30]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_00.html
new file mode 100644
index 0000000000..94391c252a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [32, 33]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_01.html
new file mode 100644
index 0000000000..906c70917e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_2d_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [33, 34]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_00.html
new file mode 100644
index 0000000000..c96d0952c5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [34, 35]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_01.html
new file mode 100644
index 0000000000..3fd841c5cc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [35, 36]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_02.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_02.html
new file mode 100644
index 0000000000..b62a2a1579
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_02.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [36, 37]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_03.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_03.html
new file mode 100644
index 0000000000..eb6ab351b7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_03.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [37, 38]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_04.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_04.html
new file mode 100644
index 0000000000..717d84018a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_cube_04.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [38, 39]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_params.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_params.html
new file mode 100644
index 0000000000..b6e1027e0b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_pbo_params.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [39, 40]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_unpack_params.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_unpack_params.html
new file mode 100644
index 0000000000..0e341e798b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage2d_unpack_params.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [31, 32]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_depth.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_depth.html
new file mode 100644
index 0000000000..9635f1e9c8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_depth.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [70, 71]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_00.html
new file mode 100644
index 0000000000..68443fffc2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [65, 66]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_01.html
new file mode 100644
index 0000000000..b578192827
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_2d_array_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [66, 67]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_00.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_00.html
new file mode 100644
index 0000000000..b5adb604a0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_00.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [67, 68]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_01.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_01.html
new file mode 100644
index 0000000000..8bff387e75
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_3d_01.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [68, 69]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_params.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_params.html
new file mode 100644
index 0000000000..cb4311db14
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_pbo_params.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [69, 70]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_unpack_params.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_unpack_params.html
new file mode 100644
index 0000000000..3f3f7242f0
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texsubimage3d_unpack_params.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [64, 65]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texturespecification_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texturespecification_test_generator.py
new file mode 100644
index 0000000000..04fd403b98
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturespecification/texturespecification_test_generator.py
@@ -0,0 +1,178 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for texturespecification* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from texturespecification_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureSpecificationTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureSpecificationTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'basic_teximage2d_2d_00',
+ 'basic_teximage2d_2d_01',
+ 'basic_teximage2d_cube_00',
+ 'basic_teximage2d_cube_01',
+ 'basic_teximage2d_cube_02',
+ 'basic_teximage2d_cube_03',
+ 'basic_teximage2d_cube_04',
+ 'random_teximage2d_2d',
+ 'random_teximage2d_cube',
+ 'teximage2d_align',
+ 'teximage2d_unpack_params',
+ 'teximage2d_pbo_2d_00',
+ 'teximage2d_pbo_2d_01',
+ 'teximage2d_pbo_cube_00',
+ 'teximage2d_pbo_cube_01',
+ 'teximage2d_pbo_cube_02',
+ 'teximage2d_pbo_cube_03',
+ 'teximage2d_pbo_cube_04',
+ 'teximage2d_pbo_params',
+ 'teximage2d_depth',
+ 'teximage2d_depth_pbo',
+ 'basic_texsubimage2d_2d_00',
+ 'basic_texsubimage2d_2d_01',
+ 'basic_texsubimage2d_2d_02',
+ 'basic_texsubimage2d_cube_00',
+ 'basic_texsubimage2d_cube_01',
+ 'basic_texsubimage2d_cube_02',
+ 'basic_texsubimage2d_cube_03',
+ 'basic_texsubimage2d_cube_04',
+ 'texsubimage2d_empty_tex',
+ 'texsubimage2d_align',
+ 'texsubimage2d_unpack_params',
+ 'texsubimage2d_pbo_2d_00',
+ 'texsubimage2d_pbo_2d_01',
+ 'texsubimage2d_pbo_cube_00',
+ 'texsubimage2d_pbo_cube_01',
+ 'texsubimage2d_pbo_cube_02',
+ 'texsubimage2d_pbo_cube_03',
+ 'texsubimage2d_pbo_cube_04',
+ 'texsubimage2d_pbo_params',
+ 'texsubimage2d_depth',
+ 'basic_copyteximage2d',
+ 'basic_copytexsubimage2d',
+ 'basic_teximage3d_2d_array_00',
+ 'basic_teximage3d_2d_array_01',
+ 'basic_teximage3d_2d_array_02',
+ 'basic_teximage3d_3d_00',
+ 'basic_teximage3d_3d_01',
+ 'basic_teximage3d_3d_02',
+ 'basic_teximage3d_3d_03',
+ 'basic_teximage3d_3d_04',
+ 'teximage3d_unpack_params',
+ 'teximage3d_pbo_2d_array_00',
+ 'teximage3d_pbo_2d_array_01',
+ 'teximage3d_pbo_3d_00',
+ 'teximage3d_pbo_3d_01',
+ 'teximage3d_pbo_params',
+ 'teximage3d_depth',
+ 'teximage3d_depth_pbo',
+ 'basic_texsubimage3d_00',
+ 'basic_texsubimage3d_01',
+ 'basic_texsubimage3d_02',
+ 'basic_texsubimage3d_03',
+ 'basic_texsubimage3d_04',
+ 'texsubimage3d_unpack_params',
+ 'texsubimage3d_pbo_2d_array_00',
+ 'texsubimage3d_pbo_2d_array_01',
+ 'texsubimage3d_pbo_3d_00',
+ 'texsubimage3d_pbo_3d_01',
+ 'texsubimage3d_pbo_params',
+ 'texsubimage3d_depth',
+ 'texstorage2d_format_2d_00',
+ 'texstorage2d_format_2d_01',
+ 'texstorage2d_format_2d_02',
+ 'texstorage2d_format_cube_00',
+ 'texstorage2d_format_cube_01',
+ 'texstorage2d_format_cube_02',
+ 'texstorage2d_format_cube_03',
+ 'texstorage2d_format_cube_04',
+ 'texstorage2d_format_depth_stencil',
+ 'texstorage2d_format_size',
+ 'texstorage3d_format_2d_array_00',
+ 'texstorage3d_format_2d_array_01',
+ 'texstorage3d_format_2d_array_02',
+ 'texstorage3d_format_3d_00',
+ 'texstorage3d_format_3d_01',
+ 'texstorage3d_format_3d_02',
+ 'texstorage3d_format_3d_03',
+ 'texstorage3d_format_depth_stencil',
+ 'texstorage3d_format_size',
+]
+
+def GenerateFilename(group):
+ """Generate test filename."""
+ filename = group
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ filename = GenerateFilename(_GROUPS[ii])
+ filelist.append(filename)
+ WriteTest(filename, ii, ii + 1)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturestatequery.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturestatequery.html
new file mode 100644
index 0000000000..2b6600bee2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturestatequery.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture State Query Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureStateQuery');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureStateQuery.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap.html
new file mode 100644
index 0000000000..fb19852595
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Wrap Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/00_test_list.txt
new file mode 100644
index 0000000000..7e3a90712b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/00_test_list.txt
@@ -0,0 +1,22 @@
+rgba8_pot.html
+rgba8_npot.html
+eac_r11_pot.html
+eac_r11_npot.html
+eac_signed_r11_pot.html
+eac_signed_r11_npot.html
+eac_rg11_pot.html
+eac_rg11_npot.html
+eac_signed_rg11_pot.html
+eac_signed_rg11_npot.html
+etc2_rgb8_pot.html
+etc2_rgb8_npot.html
+etc2_srgb8_pot.html
+etc2_srgb8_npot.html
+etc2_rgb8_punchthrough_alpha1_pot.html
+etc2_rgb8_punchthrough_alpha1_npot.html
+etc2_srgb8_punchthrough_alpha1_pot.html
+etc2_srgb8_punchthrough_alpha1_npot.html
+etc2_eac_rgba8_pot.html
+etc2_eac_rgba8_npot.html
+etc2_eac_srgb8_alpha8_pot.html
+etc2_eac_srgb8_alpha8_npot.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_r11_npot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_r11_npot.html
new file mode 100644
index 0000000000..a3cbe500a7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_r11_npot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_r11_pot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_r11_pot.html
new file mode 100644
index 0000000000..6c51aa998a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_r11_pot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_rg11_npot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_rg11_npot.html
new file mode 100644
index 0000000000..0a1ae8f924
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_rg11_npot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_rg11_pot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_rg11_pot.html
new file mode 100644
index 0000000000..9d4bf2c3ce
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_rg11_pot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_r11_npot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_r11_npot.html
new file mode 100644
index 0000000000..c7aeca4798
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_r11_npot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_r11_pot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_r11_pot.html
new file mode 100644
index 0000000000..0cb75e22e2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_r11_pot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_rg11_npot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_rg11_npot.html
new file mode 100644
index 0000000000..6905c76775
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_rg11_npot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [9, 10]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_rg11_pot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_rg11_pot.html
new file mode 100644
index 0000000000..83f3a8b536
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/eac_signed_rg11_pot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_rgba8_npot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_rgba8_npot.html
new file mode 100644
index 0000000000..c3ab4caa48
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_rgba8_npot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [19, 20]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_rgba8_pot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_rgba8_pot.html
new file mode 100644
index 0000000000..86d1dcd030
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_rgba8_pot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [18, 19]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_npot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_npot.html
new file mode 100644
index 0000000000..25c6bebb04
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_npot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [21, 22]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_pot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_pot.html
new file mode 100644
index 0000000000..8ffef8a6ec
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_eac_srgb8_alpha8_pot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [20, 21]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_npot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_npot.html
new file mode 100644
index 0000000000..c69e8adb3f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_npot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [11, 12]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_pot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_pot.html
new file mode 100644
index 0000000000..79cc6398ff
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_pot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [10, 11]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_npot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_npot.html
new file mode 100644
index 0000000000..09d8c01167
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_npot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [15, 16]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_pot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_pot.html
new file mode 100644
index 0000000000..07b5cf209d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_rgb8_punchthrough_alpha1_pot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [14, 15]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_npot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_npot.html
new file mode 100644
index 0000000000..d2cb034ccd
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_npot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [13, 14]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_pot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_pot.html
new file mode 100644
index 0000000000..6f124f0489
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_pot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [12, 13]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_npot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_npot.html
new file mode 100644
index 0000000000..e6d38338be
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_npot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [17, 18]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_pot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_pot.html
new file mode 100644
index 0000000000..27af094ed2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/etc2_srgb8_punchthrough_alpha1_pot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [16, 17]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/rgba8_npot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/rgba8_npot.html
new file mode 100644
index 0000000000..c05a40607b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/rgba8_npot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/rgba8_pot.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/rgba8_pot.html
new file mode 100644
index 0000000000..eeb9b4639d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/rgba8_pot.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/texturewrap_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/texturewrap_test_generator.py
new file mode 100644
index 0000000000..112c39958d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/texturewrap/texturewrap_test_generator.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for textureformat* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from texturewrap_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Texture Specification Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTextureWrapTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fTextureWrapTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'rgba8_pot',
+ 'rgba8_npot',
+ 'eac_r11_pot',
+ 'eac_r11_npot',
+ 'eac_signed_r11_pot',
+ 'eac_signed_r11_npot',
+ 'eac_rg11_pot',
+ 'eac_rg11_npot',
+ 'eac_signed_rg11_pot',
+ 'eac_signed_rg11_npot',
+ 'etc2_rgb8_pot',
+ 'etc2_rgb8_npot',
+ 'etc2_srgb8_pot',
+ 'etc2_srgb8_npot',
+ 'etc2_rgb8_punchthrough_alpha1_pot',
+ 'etc2_rgb8_punchthrough_alpha1_npot',
+ 'etc2_srgb8_punchthrough_alpha1_pot',
+ 'etc2_srgb8_punchthrough_alpha1_npot',
+ 'etc2_eac_rgba8_pot',
+ 'etc2_eac_rgba8_npot',
+ 'etc2_eac_srgb8_alpha8_pot',
+ 'etc2_eac_srgb8_alpha8_npot',
+]
+
+def GenerateFilename(group):
+ """Generate test filename."""
+ filename = group
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ filename = GenerateFilename(_GROUPS[ii])
+ filelist.append(filename)
+ WriteTest(filename, ii, ii + 1)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/00_test_list.txt
new file mode 100644
index 0000000000..79daefed54
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/00_test_list.txt
@@ -0,0 +1,29 @@
+position.html
+point_size.html
+basic_types_separate_points.html
+basic_types_separate_lines.html
+basic_types_separate_triangles.html
+basic_types_interleaved_points.html
+basic_types_interleaved_lines.html
+basic_types_interleaved_triangles.html
+array_separate_points.html
+array_separate_lines.html
+array_separate_triangles.html
+array_interleaved_points.html
+array_interleaved_lines.html
+array_interleaved_triangles.html
+array_element_separate_points.html
+array_element_separate_lines.html
+array_element_separate_triangles.html
+array_element_interleaved_points.html
+array_element_interleaved_lines.html
+array_element_interleaved_triangles.html
+interpolation_smooth.html
+interpolation_flat.html
+interpolation_centroid.html
+random_separate_points.html
+random_separate_lines.html
+random_separate_triangles.html
+random_interleaved_points.html
+random_interleaved_lines.html
+random_interleaved_triangles.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_interleaved_lines.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_interleaved_lines.html
new file mode 100644
index 0000000000..3bf5e0cb2d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_interleaved_lines.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [18, 19]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_interleaved_points.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_interleaved_points.html
new file mode 100644
index 0000000000..4adc875438
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_interleaved_points.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [17, 18]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_interleaved_triangles.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_interleaved_triangles.html
new file mode 100644
index 0000000000..5fbdf00bc3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_interleaved_triangles.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [19, 20]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_separate_lines.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_separate_lines.html
new file mode 100644
index 0000000000..37667c6b22
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_separate_lines.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [15, 16]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_separate_points.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_separate_points.html
new file mode 100644
index 0000000000..f92dd2551e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_separate_points.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [14, 15]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_separate_triangles.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_separate_triangles.html
new file mode 100644
index 0000000000..4bf5cf9590
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_element_separate_triangles.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [16, 17]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_interleaved_lines.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_interleaved_lines.html
new file mode 100644
index 0000000000..534b088d35
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_interleaved_lines.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [12, 13]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_interleaved_points.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_interleaved_points.html
new file mode 100644
index 0000000000..fa08538f2b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_interleaved_points.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [11, 12]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_interleaved_triangles.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_interleaved_triangles.html
new file mode 100644
index 0000000000..5fea527b76
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_interleaved_triangles.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [13, 14]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_separate_lines.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_separate_lines.html
new file mode 100644
index 0000000000..092e6e003f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_separate_lines.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [9, 10]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_separate_points.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_separate_points.html
new file mode 100644
index 0000000000..c8a7ad95cb
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_separate_points.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_separate_triangles.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_separate_triangles.html
new file mode 100644
index 0000000000..79d4b7450d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/array_separate_triangles.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [10, 11]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_interleaved_lines.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_interleaved_lines.html
new file mode 100644
index 0000000000..66653a97b7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_interleaved_lines.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_interleaved_points.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_interleaved_points.html
new file mode 100644
index 0000000000..ed753da5a9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_interleaved_points.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_interleaved_triangles.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_interleaved_triangles.html
new file mode 100644
index 0000000000..fc1f239126
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_interleaved_triangles.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_separate_lines.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_separate_lines.html
new file mode 100644
index 0000000000..191655141e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_separate_lines.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_separate_points.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_separate_points.html
new file mode 100644
index 0000000000..64be415928
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_separate_points.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_separate_triangles.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_separate_triangles.html
new file mode 100644
index 0000000000..1d73630fb3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/basic_types_separate_triangles.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/interpolation_centroid.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/interpolation_centroid.html
new file mode 100644
index 0000000000..ebceb16db2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/interpolation_centroid.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [22, 23]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/interpolation_flat.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/interpolation_flat.html
new file mode 100644
index 0000000000..5a3529867d
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/interpolation_flat.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [21, 22]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/interpolation_smooth.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/interpolation_smooth.html
new file mode 100644
index 0000000000..39464ee263
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/interpolation_smooth.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [20, 21]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/point_size.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/point_size.html
new file mode 100644
index 0000000000..b6391bff6b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/point_size.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/position.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/position.html
new file mode 100644
index 0000000000..6b4dc6f0ee
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/position.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_interleaved_lines.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_interleaved_lines.html
new file mode 100644
index 0000000000..7f63bfdcf7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_interleaved_lines.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [27, 28]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_interleaved_points.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_interleaved_points.html
new file mode 100644
index 0000000000..039029c0a9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_interleaved_points.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [26, 27]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_interleaved_triangles.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_interleaved_triangles.html
new file mode 100644
index 0000000000..57798a4356
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_interleaved_triangles.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [28, 29]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_separate_lines.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_separate_lines.html
new file mode 100644
index 0000000000..66bfea802f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_separate_lines.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [24, 25]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_separate_points.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_separate_points.html
new file mode 100644
index 0000000000..3cd6f520ae
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_separate_points.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [23, 24]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_separate_triangles.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_separate_triangles.html
new file mode 100644
index 0000000000..ab221ef053
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/random_separate_triangles.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [25, 26]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/transformfeedback_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/transformfeedback_test_generator.py
new file mode 100644
index 0000000000..cf89cb1cab
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/transformfeedback/transformfeedback_test_generator.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for textureformat* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from textureshadow_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Transform Feedback Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fTransformFeedbackTests');</script>
+<script>goog.require('framework.opengl.gluVarTypeUtil');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="320" height="240"></canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', {preserveDrawingBuffer: true}, 2);
+
+functional.gles3.es3fTransformFeedbackTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'position',
+ 'point_size',
+ 'basic_types_separate_points',
+ 'basic_types_separate_lines',
+ 'basic_types_separate_triangles',
+ 'basic_types_interleaved_points',
+ 'basic_types_interleaved_lines',
+ 'basic_types_interleaved_triangles',
+ 'array_separate_points',
+ 'array_separate_lines',
+ 'array_separate_triangles',
+ 'array_interleaved_points',
+ 'array_interleaved_lines',
+ 'array_interleaved_triangles',
+ 'array_element_separate_points',
+ 'array_element_separate_lines',
+ 'array_element_separate_triangles',
+ 'array_element_interleaved_points',
+ 'array_element_interleaved_lines',
+ 'array_element_interleaved_triangles',
+ 'interpolation_smooth',
+ 'interpolation_flat',
+ 'interpolation_centroid',
+ 'random_separate_points',
+ 'random_separate_lines',
+ 'random_separate_triangles',
+ 'random_interleaved_points',
+ 'random_interleaved_lines',
+ 'random_interleaved_triangles'
+]
+
+def GenerateFilename(group):
+ """Generate test filename."""
+ filename = group
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ for i in xrange(len(_GROUPS)):
+ groupname = _GROUPS[i]
+ filename = GenerateFilename(groupname)
+ filelist.append(filename)
+ WriteTest(filename, i, i+1)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi.html
new file mode 100644
index 0000000000..7ab136f5f6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform API Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformApiTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformApiTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/00_test_list.txt
new file mode 100644
index 0000000000..98735207bf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/00_test_list.txt
@@ -0,0 +1,4 @@
+info_query.html
+value_initial.html
+value_assigned.html
+random.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/info_query.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/info_query.html
new file mode 100644
index 0000000000..cb777e875f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/info_query.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from uniformapi_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform API Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformApiTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformApiTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/random.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/random.html
new file mode 100644
index 0000000000..69a20c6d4b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/random.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from uniformapi_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform API Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformApiTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformApiTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/uniformapi_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/uniformapi_test_generator.py
new file mode 100644
index 0000000000..2092c562d2
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/uniformapi_test_generator.py
@@ -0,0 +1,92 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for uniformapi* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from uniformapi_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform API Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformApiTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformApiTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'info_query',
+ 'value_initial',
+ 'value_assigned',
+ 'random',
+]
+
+def GenerateFilename(group):
+ """Generate test filename."""
+ filename = group
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ filename = GenerateFilename(_GROUPS[ii])
+ filelist.append(filename)
+ WriteTest(filename, ii, ii + 1)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/value_assigned.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/value_assigned.html
new file mode 100644
index 0000000000..9cce796e6b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/value_assigned.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from uniformapi_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform API Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformApiTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformApiTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/value_initial.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/value_initial.html
new file mode 100644
index 0000000000..0244c70cd9
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformapi/value_initial.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from uniformapi_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform API Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformApiTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformApiTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/00_test_list.txt
new file mode 100644
index 0000000000..dd35e89981
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/00_test_list.txt
@@ -0,0 +1,10 @@
+single_basic_type.html
+single_basic_array.html
+single_struct.html
+single_struct_array.html
+single_nested_struct.html
+single_nested_struct_array.html
+instance_array_basic_type.html
+multi_basic_types.html
+multi_nested_struct.html
+random.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/instance_array_basic_type.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/instance_array_basic_type.html
new file mode 100644
index 0000000000..8b768722b4
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/instance_array_basic_type.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from uniformbuffers_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform Block Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformBlockTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformBlockTests.run([6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/multi_basic_types.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/multi_basic_types.html
new file mode 100644
index 0000000000..205e276ff7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/multi_basic_types.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from uniformbuffers_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform Block Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformBlockTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformBlockTests.run([7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/multi_nested_struct.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/multi_nested_struct.html
new file mode 100644
index 0000000000..115256955e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/multi_nested_struct.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from uniformbuffers_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform Block Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformBlockTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformBlockTests.run([8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/random.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/random.html
new file mode 100644
index 0000000000..a1d1bf6858
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/random.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from uniformbuffers_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform Block Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformBlockTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformBlockTests.run([9, 10]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_basic_array.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_basic_array.html
new file mode 100644
index 0000000000..3458c3918b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_basic_array.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from uniformbuffers_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform Block Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformBlockTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformBlockTests.run([1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_basic_type.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_basic_type.html
new file mode 100644
index 0000000000..a0ebbed798
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_basic_type.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from uniformbuffers_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform Block Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformBlockTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformBlockTests.run([0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_nested_struct.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_nested_struct.html
new file mode 100644
index 0000000000..7a33d8731a
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_nested_struct.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from uniformbuffers_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform Block Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformBlockTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformBlockTests.run([4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_nested_struct_array.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_nested_struct_array.html
new file mode 100644
index 0000000000..006fdf9cd3
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_nested_struct_array.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from uniformbuffers_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform Block Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformBlockTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformBlockTests.run([5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_struct.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_struct.html
new file mode 100644
index 0000000000..4977f64919
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_struct.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from uniformbuffers_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform Block Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformBlockTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformBlockTests.run([2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_struct_array.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_struct_array.html
new file mode 100644
index 0000000000..cb39bbfec5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/single_struct_array.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from uniformbuffers_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform Block Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformBlockTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformBlockTests.run([3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/uniformbuffers_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/uniformbuffers_test_generator.py
new file mode 100644
index 0000000000..dbf97f7ff8
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/uniformbuffers/uniformbuffers_test_generator.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for uniformbuffers* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from uniformbuffers_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uniform Block Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fUniformBlockTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fUniformBlockTests.run([%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'single_basic_type',
+ 'single_basic_array',
+ 'single_struct',
+ 'single_struct_array',
+ 'single_nested_struct',
+ 'single_nested_struct_array',
+ 'instance_array_basic_type',
+ 'multi_basic_types',
+ 'multi_nested_struct',
+ 'random',
+]
+
+def GenerateFilename(group):
+ """Generate test filename."""
+ filename = group
+ filename += ".html"
+ return filename
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ for ii in range(len(_GROUPS)):
+ filename = GenerateFilename(_GROUPS[ii])
+ filelist.append(filename)
+ WriteTest(filename, ii, ii + 1)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrayobject.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrayobject.html
new file mode 100644
index 0000000000..e6888b059e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrayobject.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Array Object Conformance Tests</title>
+<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
+<script src="../../../js/js-test-pre.js"></script>
+<script src="../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../closure-library/closure/goog/base.js"></script>
+<script src="../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayObjectTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="256" height="256"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayObjectTests.run(gl);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/00_test_list.txt b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/00_test_list.txt
new file mode 100644
index 0000000000..f06de02f82
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/00_test_list.txt
@@ -0,0 +1,27 @@
+single_attribute.stride.html
+single_attribute.normalize.html
+single_attribute.output_type.float.html
+single_attribute.output_type.short.html
+single_attribute.output_type.byte.html
+single_attribute.output_type.unsigned_short.html
+single_attribute.output_type.unsigned_byte.html
+single_attribute.output_type.unsigned_int.html
+single_attribute.output_type.int.html
+single_attribute.output_type.half.html
+single_attribute.output_type.unsigned_int_2_10_10_10.html
+single_attribute.output_type.int_2_10_10_10.html
+single_attribute.usage.static_draw.html
+single_attribute.usage.stream_draw.html
+single_attribute.usage.dynamic_draw.html
+single_attribute.usage.static_copy.html
+single_attribute.usage.stream_copy.html
+single_attribute.usage.dynamic_copy.html
+single_attribute.usage.static_read.html
+single_attribute.usage.stream_read.html
+single_attribute.usage.dynamic_read.html
+single_attribute.offset.html
+single_attribute.first.html
+multiple_attributes.count.html
+multiple_attributes.storage.html
+multiple_attributes.stride.html
+multiple_attributes.output.html \ No newline at end of file
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.count.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.count.html
new file mode 100644
index 0000000000..be380c95ee
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.count.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [23, 24]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.output.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.output.html
new file mode 100644
index 0000000000..37ff4a8420
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.output.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [26, 27]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.storage.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.storage.html
new file mode 100644
index 0000000000..2dda458009
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.storage.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [24, 25]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.stride.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.stride.html
new file mode 100644
index 0000000000..8913a2d93f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/multiple_attributes.stride.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [25, 26]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.first.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.first.html
new file mode 100644
index 0000000000..dd2b1a23b7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.first.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [22, 23]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.normalize.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.normalize.html
new file mode 100644
index 0000000000..c92890a97c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.normalize.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [1, 2]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.offset.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.offset.html
new file mode 100644
index 0000000000..6b9286c1ab
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.offset.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [21, 22]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.byte.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.byte.html
new file mode 100644
index 0000000000..0babde2587
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.byte.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [4, 5]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.float.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.float.html
new file mode 100644
index 0000000000..a4cd67561b
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.float.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [2, 3]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.half.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.half.html
new file mode 100644
index 0000000000..95740244a7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.half.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [9, 10]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.int.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.int.html
new file mode 100644
index 0000000000..ec3f4903c1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.int.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [8, 9]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.int_2_10_10_10.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.int_2_10_10_10.html
new file mode 100644
index 0000000000..95eff6d999
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.int_2_10_10_10.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [11, 12]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.short.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.short.html
new file mode 100644
index 0000000000..ff6cbffa9f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.short.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [3, 4]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_byte.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_byte.html
new file mode 100644
index 0000000000..1ef3deb9d5
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_byte.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [6, 7]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int.html
new file mode 100644
index 0000000000..efff6a628e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [7, 8]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int_2_10_10_10.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int_2_10_10_10.html
new file mode 100644
index 0000000000..9b90ae1ed7
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_int_2_10_10_10.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [10, 11]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_short.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_short.html
new file mode 100644
index 0000000000..bf56c355ac
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.output_type.unsigned_short.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [5, 6]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.stride.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.stride.html
new file mode 100644
index 0000000000..46bd9e2036
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.stride.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [0, 1]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_copy.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_copy.html
new file mode 100644
index 0000000000..347834c74c
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_copy.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [17, 18]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_draw.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_draw.html
new file mode 100644
index 0000000000..dab5982daf
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_draw.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [14, 15]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_read.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_read.html
new file mode 100644
index 0000000000..8d868ce6a1
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.dynamic_read.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [20, 21]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.static_copy.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.static_copy.html
new file mode 100644
index 0000000000..0c1c286164
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.static_copy.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [15, 16]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.static_draw.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.static_draw.html
new file mode 100644
index 0000000000..eb3bb61265
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.static_draw.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [12, 13]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.static_read.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.static_read.html
new file mode 100644
index 0000000000..bfed3a9bfa
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.static_read.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [18, 19]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_copy.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_copy.html
new file mode 100644
index 0000000000..f7c63d107f
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_copy.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [16, 17]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_draw.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_draw.html
new file mode 100644
index 0000000000..238ce5e14e
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_draw.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [13, 14]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_read.html b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_read.html
new file mode 100644
index 0000000000..6dd2a736c6
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/single_attribute.usage.stream_read.html
@@ -0,0 +1,31 @@
+<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [19, 20]);
+</script>
+</body>
+</html>
diff --git a/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/vertexarrays_test_generator.py b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/vertexarrays_test_generator.py
new file mode 100644
index 0000000000..de781ccafc
--- /dev/null
+++ b/dom/canvas/test/webgl-conf/checkout/deqp/functional/gles3/vertexarrays/vertexarrays_test_generator.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019 The Khronos Group Inc.
+# Use of this source code is governed by an MIT-style license that can be
+# found in the LICENSE.txt file.
+
+"""
+ Generator for vertexarrays* tests.
+ This file needs to be run in its folder.
+"""
+
+import sys
+
+_DO_NOT_EDIT_WARNING = """<!--
+
+This file is auto-generated from vertexarrays_test_generator.py
+DO NOT EDIT!
+
+-->
+
+"""
+
+_HTML_TEMPLATE = """<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Vertex Arrays Conformance Tests</title>
+<link rel="stylesheet" href="../../../../resources/js-test-style.css"/>
+<script src="../../../../js/js-test-pre.js"></script>
+<script src="../../../../js/webgl-test-utils.js"></script>
+
+<script src="../../../../closure-library/closure/goog/base.js"></script>
+<script src="../../../deqp-deps.js"></script>
+<script>goog.require('functional.gles3.es3fVertexArrayTests');</script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="200" height="100"> </canvas>
+<script>
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext('canvas', null, 2);
+
+functional.gles3.es3fVertexArrayTests.run(gl, [%(start)s, %(end)s]);
+</script>
+</body>
+</html>
+"""
+
+_GROUPS = [
+ 'single_attribute.stride',
+ 'single_attribute.normalize',
+ 'single_attribute.output_type.float',
+ 'single_attribute.output_type.short',
+ 'single_attribute.output_type.byte',
+ 'single_attribute.output_type.unsigned_short',
+ 'single_attribute.output_type.unsigned_byte',
+ 'single_attribute.output_type.unsigned_int',
+ 'single_attribute.output_type.int',
+ 'single_attribute.output_type.half',
+ 'single_attribute.output_type.unsigned_int_2_10_10_10',
+ 'single_attribute.output_type.int_2_10_10_10',
+ 'single_attribute.usage.static_draw',
+ 'single_attribute.usage.stream_draw',
+ 'single_attribute.usage.dynamic_draw',
+ 'single_attribute.usage.static_copy',
+ 'single_attribute.usage.stream_copy',
+ 'single_attribute.usage.dynamic_copy',
+ 'single_attribute.usage.static_read',
+ 'single_attribute.usage.stream_read',
+ 'single_attribute.usage.dynamic_read',
+ 'single_attribute.offset',
+ 'single_attribute.first',
+ 'multiple_attributes.count',
+ 'multiple_attributes.storage',
+ 'multiple_attributes.stride',
+ 'multiple_attributes.output',
+]
+
+def WriteTest(filename, start, end):
+ """Write one test."""
+ file = open(filename, "wb")
+ file.write(_DO_NOT_EDIT_WARNING)
+ file.write(_HTML_TEMPLATE % {
+ 'start': start,
+ 'end': end
+ })
+ file.close
+
+def GenerateTests():
+ """Generate all tests."""
+ filelist = []
+ ii = 0
+ for ii in range(len(_GROUPS)):
+ filename = _GROUPS[ii] + ".html"
+ filelist.append(filename)
+ WriteTest(filename, ii, ii + 1)
+ return filelist
+
+def GenerateTestList(filelist):
+ file = open("00_test_list.txt", "wb")
+ file.write('\n'.join(filelist))
+ file.close
+
+def main(argv):
+ """This is the main function."""
+ filelist = GenerateTests()
+ GenerateTestList(filelist)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))